2008-05-24 16:05:49 +08:00
|
|
|
/* tinyproxy - A fast light-weight HTTP proxy
|
|
|
|
* Copyright (C) 2004 Robert James Kaes <rjkaes@users.sourceforge.net>
|
2004-08-14 04:19:50 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Parses the configuration file and sets up the config_s structure for
|
2004-08-14 04:19:50 +08:00
|
|
|
* use by the application. This file replaces the old grammar.y and
|
2004-08-14 11:18:41 +08:00
|
|
|
* scanner.l files. It takes up less space and _I_ think is easier to
|
2004-08-14 04:19:50 +08:00
|
|
|
* add new directives to. Who knows if I'm right though.
|
|
|
|
*/
|
|
|
|
|
2009-09-21 12:11:59 +08:00
|
|
|
#include "conf.h"
|
2004-08-14 04:19:50 +08:00
|
|
|
|
|
|
|
#include "acl.h"
|
|
|
|
#include "anonymous.h"
|
|
|
|
#include "child.h"
|
|
|
|
#include "filter.h"
|
|
|
|
#include "heap.h"
|
2008-05-24 16:17:14 +08:00
|
|
|
#include "html-error.h"
|
2004-08-14 04:19:50 +08:00
|
|
|
#include "log.h"
|
|
|
|
#include "reqs.h"
|
2008-03-09 09:33:54 +08:00
|
|
|
#include "reverse-proxy.h"
|
2009-12-06 19:40:31 +08:00
|
|
|
#include "upstream.h"
|
2009-12-07 06:50:15 +08:00
|
|
|
#include "connect-ports.h"
|
2004-08-14 04:19:50 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The configuration directives are defined in the structure below. Each
|
|
|
|
* directive requires a regular expression to match against, and a
|
|
|
|
* function to call when the regex is matched.
|
|
|
|
*
|
|
|
|
* Below are defined certain constant regular expression strings that
|
|
|
|
* can (and likely should) be used when building the regex for the
|
|
|
|
* given directive.
|
|
|
|
*/
|
|
|
|
#define WS "[[:space:]]+"
|
|
|
|
#define STR "\"([^\"]+)\""
|
|
|
|
#define BOOL "(yes|on|no|off)"
|
|
|
|
#define INT "((0x)?[[:digit:]]+)"
|
|
|
|
#define ALNUM "([-a-z0-9._]+)"
|
|
|
|
#define IP "((([0-9]{1,3})\\.){3}[0-9]{1,3})"
|
|
|
|
#define IPMASK "(" IP "(/[[:digit:]]+)?)"
|
2009-11-09 05:14:14 +08:00
|
|
|
#define IPV6 "(" \
|
2009-11-10 06:25:13 +08:00
|
|
|
"(([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1})|" \
|
|
|
|
"((([0-9a-f]{1,4}:){1,7}|:):)|" \
|
|
|
|
"(:(:[0-9a-f]{1,4}){1,7})|" \
|
2009-11-10 07:52:53 +08:00
|
|
|
"([0-9a-f]{1,4}(:[0-9a-f]{1,4}){1,7})|" \
|
2009-11-10 06:25:13 +08:00
|
|
|
"(((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}))|" \
|
|
|
|
"((([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}))|" \
|
|
|
|
"(([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"(([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"((([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})|" \
|
|
|
|
"(:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3})" \
|
2009-11-09 05:14:14 +08:00
|
|
|
")"
|
|
|
|
|
|
|
|
#define IPV6MASK "(" IPV6 "(/[[:digit:]]+)?)"
|
2004-08-14 04:19:50 +08:00
|
|
|
#define BEGIN "^[[:space:]]*"
|
|
|
|
#define END "[[:space:]]*$"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Limit the maximum number of substring matches to a reasonably high
|
|
|
|
* number. Given the usual structure of the configuration file, sixteen
|
|
|
|
* substring matches should be plenty.
|
|
|
|
*/
|
|
|
|
#define RE_MAX_MATCHES 16
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All configuration handling functions are REQUIRED to be defined
|
|
|
|
* with the same function template as below.
|
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
typedef int (*CONFFILE_HANDLER) (struct config_s *, const char *, regmatch_t[]);
|
2004-08-14 04:19:50 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Define the pattern used by any directive handling function. The
|
|
|
|
* following arguments are defined:
|
|
|
|
*
|
|
|
|
* struct config_s* conf pointer to the current configuration structure
|
|
|
|
* const char* line full line matched by the regular expression
|
|
|
|
* regmatch_t match[] offsets to the substrings matched
|
|
|
|
*
|
|
|
|
* The handling function must return 0 if the directive was processed
|
|
|
|
* properly. Any errors are reported by returning a non-zero value.
|
|
|
|
*/
|
2008-12-08 20:26:08 +08:00
|
|
|
#define HANDLE_FUNC(func) \
|
|
|
|
int func(struct config_s* conf, const char* line, \
|
2009-12-06 08:34:42 +08:00
|
|
|
regmatch_t match[])
|
2004-08-14 04:19:50 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* List all the handling functions. These are defined later, but they need
|
|
|
|
* to be in-scope before the big structure below.
|
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_nop)
|
2005-08-15 11:54:31 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2008-12-08 21:39:44 +08:00
|
|
|
} /* do nothing function */
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_allow);
|
|
|
|
static HANDLE_FUNC (handle_anonymous);
|
|
|
|
static HANDLE_FUNC (handle_bind);
|
|
|
|
static HANDLE_FUNC (handle_bindsame);
|
|
|
|
static HANDLE_FUNC (handle_connectport);
|
|
|
|
static HANDLE_FUNC (handle_defaulterrorfile);
|
|
|
|
static HANDLE_FUNC (handle_deny);
|
|
|
|
static HANDLE_FUNC (handle_errorfile);
|
2005-11-04 09:31:41 +08:00
|
|
|
#ifdef FILTER_ENABLE
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_filter);
|
|
|
|
static HANDLE_FUNC (handle_filtercasesensitive);
|
|
|
|
static HANDLE_FUNC (handle_filterdefaultdeny);
|
|
|
|
static HANDLE_FUNC (handle_filterextended);
|
|
|
|
static HANDLE_FUNC (handle_filterurls);
|
2005-11-04 09:31:41 +08:00
|
|
|
#endif
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_group);
|
|
|
|
static HANDLE_FUNC (handle_listen);
|
|
|
|
static HANDLE_FUNC (handle_logfile);
|
|
|
|
static HANDLE_FUNC (handle_loglevel);
|
|
|
|
static HANDLE_FUNC (handle_maxclients);
|
|
|
|
static HANDLE_FUNC (handle_maxrequestsperchild);
|
|
|
|
static HANDLE_FUNC (handle_maxspareservers);
|
|
|
|
static HANDLE_FUNC (handle_minspareservers);
|
|
|
|
static HANDLE_FUNC (handle_pidfile);
|
|
|
|
static HANDLE_FUNC (handle_port);
|
2005-11-04 09:31:41 +08:00
|
|
|
#ifdef REVERSE_SUPPORT
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_reversebaseurl);
|
|
|
|
static HANDLE_FUNC (handle_reversemagic);
|
|
|
|
static HANDLE_FUNC (handle_reverseonly);
|
|
|
|
static HANDLE_FUNC (handle_reversepath);
|
2005-11-04 09:31:41 +08:00
|
|
|
#endif
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_startservers);
|
|
|
|
static HANDLE_FUNC (handle_statfile);
|
|
|
|
static HANDLE_FUNC (handle_stathost);
|
|
|
|
static HANDLE_FUNC (handle_syslog);
|
|
|
|
static HANDLE_FUNC (handle_timeout);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_user);
|
|
|
|
static HANDLE_FUNC (handle_viaproxyname);
|
2009-10-11 07:13:15 +08:00
|
|
|
static HANDLE_FUNC (handle_disableviaheader);
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_xtinyproxy);
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2005-11-04 13:15:47 +08:00
|
|
|
#ifdef UPSTREAM_SUPPORT
|
2008-12-01 23:01:11 +08:00
|
|
|
static HANDLE_FUNC (handle_upstream);
|
|
|
|
static HANDLE_FUNC (handle_upstream_no);
|
2005-11-04 13:15:47 +08:00
|
|
|
#endif
|
|
|
|
|
2004-08-14 04:19:50 +08:00
|
|
|
/*
|
|
|
|
* This macro can be used to make standard directives in the form:
|
|
|
|
* directive arguments [arguments ...]
|
|
|
|
*
|
|
|
|
* The directive itself will be the first matched substring.
|
|
|
|
*
|
|
|
|
* Note that this macro is not required. As you can see below, the
|
|
|
|
* comment and blank line elements are defined explicitly since they
|
|
|
|
* do not follow the pattern above. This macro is for convenience
|
|
|
|
* only.
|
|
|
|
*/
|
|
|
|
#define STDCONF(d, re, func) { BEGIN "(" d ")" WS re END, func, NULL }
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Holds the regular expression used to match the configuration directive,
|
2004-08-14 11:18:41 +08:00
|
|
|
* the function pointer to the routine to handle the directive, and
|
2004-08-14 04:19:50 +08:00
|
|
|
* for internal use, a pointer to the compiled regex so it only needs
|
|
|
|
* to be compiled one.
|
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
struct {
|
|
|
|
const char *re;
|
|
|
|
CONFFILE_HANDLER handler;
|
|
|
|
regex_t *cre;
|
|
|
|
} directives[] = {
|
|
|
|
/* comments */
|
|
|
|
{
|
2009-09-15 04:17:45 +08:00
|
|
|
BEGIN "#", handle_nop, NULL
|
|
|
|
},
|
|
|
|
/* blank lines */
|
2009-09-15 03:41:25 +08:00
|
|
|
{
|
2009-09-15 04:17:45 +08:00
|
|
|
"^[[:space:]]+$", handle_nop, NULL
|
|
|
|
},
|
|
|
|
/* string arguments */
|
|
|
|
STDCONF ("logfile", STR, handle_logfile),
|
|
|
|
STDCONF ("pidfile", STR, handle_pidfile),
|
|
|
|
STDCONF ("anonymous", STR, handle_anonymous),
|
|
|
|
STDCONF ("viaproxyname", STR, handle_viaproxyname),
|
|
|
|
STDCONF ("defaulterrorfile", STR, handle_defaulterrorfile),
|
|
|
|
STDCONF ("statfile", STR, handle_statfile),
|
|
|
|
STDCONF ("stathost", STR, handle_stathost),
|
2009-09-27 18:48:48 +08:00
|
|
|
STDCONF ("xtinyproxy", BOOL, handle_xtinyproxy),
|
2009-09-15 04:17:45 +08:00
|
|
|
/* boolean arguments */
|
|
|
|
STDCONF ("syslog", BOOL, handle_syslog),
|
|
|
|
STDCONF ("bindsame", BOOL, handle_bindsame),
|
2009-10-11 07:13:15 +08:00
|
|
|
STDCONF ("disableviaheader", BOOL, handle_disableviaheader),
|
2009-09-15 04:17:45 +08:00
|
|
|
/* integer arguments */
|
|
|
|
STDCONF ("port", INT, handle_port),
|
|
|
|
STDCONF ("maxclients", INT, handle_maxclients),
|
|
|
|
STDCONF ("maxspareservers", INT, handle_maxspareservers),
|
|
|
|
STDCONF ("minspareservers", INT, handle_minspareservers),
|
|
|
|
STDCONF ("startservers", INT, handle_startservers),
|
|
|
|
STDCONF ("maxrequestsperchild", INT, handle_maxrequestsperchild),
|
|
|
|
STDCONF ("timeout", INT, handle_timeout),
|
|
|
|
STDCONF ("connectport", INT, handle_connectport),
|
|
|
|
/* alphanumeric arguments */
|
|
|
|
STDCONF ("user", ALNUM, handle_user),
|
|
|
|
STDCONF ("group", ALNUM, handle_group),
|
|
|
|
/* ip arguments */
|
2009-11-09 05:14:14 +08:00
|
|
|
STDCONF ("listen", "(" IP "|" IPV6 ")", handle_listen),
|
|
|
|
STDCONF ("allow", "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
|
|
|
|
handle_allow),
|
|
|
|
STDCONF ("deny", "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")",
|
|
|
|
handle_deny),
|
|
|
|
STDCONF ("bind", "(" IP "|" IPV6 ")", handle_bind),
|
2009-09-15 04:17:45 +08:00
|
|
|
/* error files */
|
|
|
|
STDCONF ("errorfile", INT WS STR, handle_errorfile),
|
2005-11-04 09:31:41 +08:00
|
|
|
#ifdef FILTER_ENABLE
|
2009-09-15 04:17:45 +08:00
|
|
|
/* filtering */
|
|
|
|
STDCONF ("filter", STR, handle_filter),
|
|
|
|
STDCONF ("filterurls", BOOL, handle_filterurls),
|
|
|
|
STDCONF ("filterextended", BOOL, handle_filterextended),
|
|
|
|
STDCONF ("filterdefaultdeny", BOOL, handle_filterdefaultdeny),
|
|
|
|
STDCONF ("filtercasesensitive", BOOL, handle_filtercasesensitive),
|
2005-11-04 09:31:41 +08:00
|
|
|
#endif
|
|
|
|
#ifdef REVERSE_SUPPORT
|
2009-09-15 04:17:45 +08:00
|
|
|
/* Reverse proxy arguments */
|
|
|
|
STDCONF ("reversebaseurl", STR, handle_reversebaseurl),
|
|
|
|
STDCONF ("reverseonly", BOOL, handle_reverseonly),
|
|
|
|
STDCONF ("reversemagic", BOOL, handle_reversemagic),
|
2009-11-10 08:14:57 +08:00
|
|
|
STDCONF ("reversepath", STR "(" WS STR ")?", handle_reversepath),
|
2005-11-04 09:31:41 +08:00
|
|
|
#endif
|
2005-11-04 13:15:47 +08:00
|
|
|
#ifdef UPSTREAM_SUPPORT
|
2009-09-15 04:17:45 +08:00
|
|
|
/* upstream is rather complicated */
|
2009-09-15 03:41:25 +08:00
|
|
|
{
|
2009-09-15 04:17:45 +08:00
|
|
|
BEGIN "(no" WS "upstream)" WS STR END, handle_upstream_no, NULL
|
|
|
|
},
|
|
|
|
{
|
|
|
|
BEGIN "(upstream)" WS "(" IP "|" ALNUM ")" ":" INT "(" WS STR
|
2009-09-28 14:21:50 +08:00
|
|
|
")?" END, handle_upstream, NULL
|
|
|
|
},
|
2005-11-04 13:15:47 +08:00
|
|
|
#endif
|
2009-09-15 04:17:45 +08:00
|
|
|
/* loglevel */
|
|
|
|
STDCONF ("loglevel", "(critical|error|warning|notice|connect|info)",
|
|
|
|
handle_loglevel)
|
2009-08-04 21:25:36 +08:00
|
|
|
};
|
|
|
|
|
2008-12-01 23:01:11 +08:00
|
|
|
const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]);
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-12-07 07:22:53 +08:00
|
|
|
void free_config (struct config_s *conf)
|
|
|
|
{
|
|
|
|
safefree (conf->config_file);
|
|
|
|
safefree (conf->logf_name);
|
|
|
|
safefree (conf->stathost);
|
|
|
|
safefree (conf->user);
|
|
|
|
safefree (conf->group);
|
|
|
|
safefree (conf->ipAddr);
|
|
|
|
#ifdef FILTER_ENABLE
|
|
|
|
safefree (conf->filter);
|
|
|
|
#endif /* FILTER_ENABLE */
|
|
|
|
#ifdef REVERSE_SUPPORT
|
|
|
|
free_reversepath_list(conf->reversepath_list);
|
|
|
|
safefree (conf->reversebaseurl);
|
|
|
|
#endif
|
|
|
|
#ifdef UPSTREAM_SUPPORT
|
|
|
|
free_upstream_list (conf->upstream_list);
|
|
|
|
#endif /* UPSTREAM_SUPPORT */
|
|
|
|
safefree (conf->pidpath);
|
|
|
|
safefree (conf->bind_address);
|
|
|
|
safefree (conf->via_proxy_name);
|
|
|
|
hashmap_delete (conf->errorpages);
|
|
|
|
safefree (conf->errorpage_undef);
|
|
|
|
safefree (conf->statpage);
|
|
|
|
flush_access_list (conf->access_list);
|
|
|
|
free_connect_ports_list (conf->connect_ports);
|
|
|
|
hashmap_delete (conf->anonymous_map);
|
|
|
|
|
|
|
|
memset (conf, 0, sizeof(*conf));
|
|
|
|
}
|
|
|
|
|
2004-08-14 04:19:50 +08:00
|
|
|
/*
|
|
|
|
* Compiles the regular expressions used by the configuration file. This
|
|
|
|
* routine MUST be called before trying to parse the configuration file.
|
|
|
|
*
|
|
|
|
* Returns 0 on success; negative upon failure.
|
|
|
|
*/
|
2009-11-09 06:41:21 +08:00
|
|
|
static int config_compile (void)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
unsigned int i, r;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
for (i = 0; i != ndirectives; ++i) {
|
|
|
|
assert (directives[i].handler);
|
|
|
|
assert (!directives[i].cre);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
directives[i].cre = (regex_t *) safemalloc (sizeof (regex_t));
|
|
|
|
if (!directives[i].cre)
|
|
|
|
return -1;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
r = regcomp (directives[i].cre,
|
|
|
|
directives[i].re,
|
|
|
|
REG_EXTENDED | REG_ICASE | REG_NEWLINE);
|
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempt to match the supplied line with any of the configuration
|
|
|
|
* regexes defined above. If a match is found, call the handler
|
|
|
|
* function to process the directive.
|
|
|
|
*
|
|
|
|
* Returns 0 if a match was found and successfully processed; otherwise,
|
|
|
|
* a negative number is returned.
|
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
static int check_match (struct config_s *conf, const char *line)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
regmatch_t match[RE_MAX_MATCHES];
|
|
|
|
unsigned int i;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (ndirectives > 0);
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
for (i = 0; i != ndirectives; ++i) {
|
|
|
|
assert (directives[i].cre);
|
|
|
|
if (!regexec
|
|
|
|
(directives[i].cre, line, RE_MAX_MATCHES, match, 0))
|
|
|
|
return (*directives[i].handler) (conf, line, match);
|
|
|
|
}
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return -1;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the previously opened configuration stream.
|
|
|
|
*/
|
2009-11-09 06:41:21 +08:00
|
|
|
static int config_parse (struct config_s *conf, FILE * f)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char buffer[1024]; /* 1KB lines should be plenty */
|
|
|
|
unsigned long lineno = 1;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
while (fgets (buffer, sizeof (buffer), f)) {
|
|
|
|
if (check_match (conf, buffer)) {
|
|
|
|
printf ("Syntax error on line %ld\n", lineno);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
++lineno;
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
2009-11-09 06:41:21 +08:00
|
|
|
/**
|
|
|
|
* Read the settings from a config file.
|
|
|
|
*/
|
|
|
|
int load_config_file (const char *config_fname, struct config_s *conf)
|
|
|
|
{
|
|
|
|
FILE *config_file;
|
|
|
|
|
|
|
|
config_file = fopen (config_fname, "r");
|
|
|
|
if (!config_file) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Could not open config file \"%s\".\n",
|
|
|
|
PACKAGE, config_fname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-12-07 14:54:19 +08:00
|
|
|
if (config_compile () || config_parse (conf, config_file)) {
|
2009-11-09 06:41:21 +08:00
|
|
|
fprintf (stderr, "Unable to parse config file. "
|
|
|
|
"Not starting.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (config_file);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-07 08:08:22 +08:00
|
|
|
static void initialize_with_defaults (struct config_s *conf,
|
|
|
|
struct config_s *defaults)
|
|
|
|
{
|
|
|
|
if (defaults->logf_name) {
|
|
|
|
conf->logf_name = safestrdup (defaults->logf_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defaults->config_file) {
|
|
|
|
conf->config_file = safestrdup (defaults->config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->syslog = defaults->syslog;
|
|
|
|
conf->port = defaults->port;
|
|
|
|
|
|
|
|
if (defaults->stathost) {
|
|
|
|
conf->stathost = safestrdup (defaults->stathost);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->godaemon = defaults->godaemon;
|
|
|
|
conf->quit = defaults->quit;
|
|
|
|
|
|
|
|
if (defaults->user) {
|
|
|
|
conf->user = safestrdup (defaults->user);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defaults->group) {
|
|
|
|
conf->group = safestrdup (defaults->group);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defaults->ipAddr) {
|
|
|
|
conf->ipAddr = safestrdup (defaults->ipAddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef FILTER_ENABLE
|
|
|
|
if (defaults->filter) {
|
|
|
|
conf->filter = safestrdup (defaults->filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->filter_url = defaults->filter_url;
|
|
|
|
conf->filter_extended = defaults->filter_extended;
|
|
|
|
conf->filter_casesensitive = defaults->filter_casesensitive;
|
|
|
|
#endif /* FILTER_ENABLE */
|
|
|
|
|
|
|
|
#ifdef XTINYPROXY_ENABLE
|
|
|
|
conf->add_xtinyproxy = defaults->add_xtinyproxy;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef REVERSE_SUPPORT
|
|
|
|
/* struct reversepath *reversepath_list; */
|
|
|
|
conf->reverseonly = defaults->reverseonly;
|
|
|
|
conf->reversemagic = defaults->reversemagic;
|
|
|
|
|
|
|
|
if (defaults->reversebaseurl) {
|
|
|
|
conf->reversebaseurl = safestrdup (defaults->reversebaseurl);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef UPSTREAM_SUPPORT
|
|
|
|
/* struct upstream *upstream_list; */
|
|
|
|
#endif /* UPSTREAM_SUPPORT */
|
|
|
|
|
|
|
|
if (defaults->pidpath) {
|
|
|
|
conf->pidpath = safestrdup (defaults->pidpath);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->idletimeout = defaults->idletimeout;
|
|
|
|
|
|
|
|
if (defaults->bind_address) {
|
|
|
|
conf->bind_address = safestrdup (defaults->bind_address);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->bindsame = defaults->bindsame;
|
|
|
|
|
|
|
|
if (defaults->via_proxy_name) {
|
|
|
|
conf->via_proxy_name = safestrdup (defaults->via_proxy_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
conf->disable_viaheader = defaults->disable_viaheader;
|
|
|
|
|
|
|
|
if (defaults->errorpage_undef) {
|
|
|
|
conf->errorpage_undef = safestrdup (defaults->errorpage_undef);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (defaults->statpage) {
|
|
|
|
conf->statpage = safestrdup (defaults->statpage);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vector_t access_list; */
|
|
|
|
/* vector_t connect_ports; */
|
|
|
|
/* hashmap_t anonymous_map; */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load the configuration.
|
|
|
|
*/
|
|
|
|
int reload_config (const char *config_fname, struct config_s *conf,
|
|
|
|
struct config_s *defaults)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
free_config (conf);
|
|
|
|
|
|
|
|
initialize_with_defaults (conf, defaults);
|
|
|
|
|
|
|
|
ret = load_config_file (config_fname, conf);
|
|
|
|
if (ret != 0) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the default values if they were not set in the config file. */
|
|
|
|
if (conf->port == 0) {
|
|
|
|
/* Don't log here - logging might not be set up yet! */
|
|
|
|
fprintf (stderr, PACKAGE ": You MUST set a Port in the "
|
|
|
|
"config file.\n");
|
|
|
|
ret = -1;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!conf->user) {
|
|
|
|
log_message (LOG_WARNING, "You SHOULD set a UserName in the "
|
|
|
|
"config file. Using current user instead.");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (conf->idletimeout == 0) {
|
|
|
|
log_message (LOG_WARNING, "Invalid idle time setting. "
|
|
|
|
"Only values greater than zero are allowed. "
|
|
|
|
"Therefore setting idle timeout to %u seconds.",
|
|
|
|
MAX_IDLE_TIME);
|
2009-12-07 14:55:03 +08:00
|
|
|
conf->idletimeout = MAX_IDLE_TIME;
|
2009-12-07 08:08:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-08-14 11:18:41 +08:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
|
|
|
* The following are basic data extraction building blocks that can
|
|
|
|
* be used to simplify the parsing of a directive.
|
|
|
|
*
|
|
|
|
***********************************************************************/
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static char *get_string_arg (const char *line, regmatch_t * match)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *p;
|
|
|
|
const unsigned int len = match->rm_eo - match->rm_so;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (line);
|
|
|
|
assert (len > 0);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
p = (char *) safemalloc (len + 1);
|
|
|
|
if (!p)
|
|
|
|
return NULL;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
memcpy (p, line + match->rm_so, len);
|
|
|
|
p[len] = '\0';
|
|
|
|
return p;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static int set_string_arg (char **var, const char *line, regmatch_t * match)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *arg = get_string_arg (line, match);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (!arg)
|
|
|
|
return -1;
|
2009-11-17 04:50:27 +08:00
|
|
|
|
2009-12-06 08:31:14 +08:00
|
|
|
if (*var != NULL) {
|
|
|
|
safefree (*var);
|
|
|
|
}
|
|
|
|
|
2009-11-17 04:50:27 +08:00
|
|
|
*var = arg;
|
|
|
|
|
2009-11-17 04:51:51 +08:00
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static int get_bool_arg (const char *line, regmatch_t * match)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
const char *p = line + match->rm_so;
|
2004-08-25 00:34:22 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (line);
|
|
|
|
assert (match && match->rm_so != -1);
|
2004-08-14 11:18:41 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
/* "y"es or o"n" map as true, otherwise it's false. */
|
|
|
|
if (tolower (p[0]) == 'y' || tolower (p[1]) == 'n')
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 0;
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-12-01 23:01:11 +08:00
|
|
|
set_bool_arg (unsigned int *var, const char *line, regmatch_t * match)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (var);
|
|
|
|
assert (line);
|
|
|
|
assert (match && match->rm_so != -1);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
*var = get_bool_arg (line, match);
|
|
|
|
return 0;
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
|
|
|
|
2009-09-20 16:28:50 +08:00
|
|
|
static unsigned long int
|
2008-12-01 23:01:11 +08:00
|
|
|
get_int_arg (const char *line, regmatch_t * match)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (line);
|
|
|
|
assert (match && match->rm_so != -1);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return strtoul (line + match->rm_so, NULL, 0);
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
2008-12-01 23:01:11 +08:00
|
|
|
|
2004-08-14 11:18:41 +08:00
|
|
|
static int
|
2009-08-05 04:54:59 +08:00
|
|
|
set_int_arg (unsigned long int *var, const char *line, regmatch_t * match)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (var);
|
|
|
|
assert (line);
|
|
|
|
assert (match);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
*var = get_int_arg (line, match);
|
|
|
|
return 0;
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
*
|
|
|
|
* Below are all the directive handling functions. You will notice
|
|
|
|
* that most of the directives delegate to one of the basic data
|
|
|
|
* extraction routines. This is deliberate. To add a new directive
|
|
|
|
* to tinyproxy only requires you to define the regular expression
|
|
|
|
* above and then figure out what data extract routine to use.
|
|
|
|
*
|
|
|
|
* However, you will also notice that more complicated directives are
|
|
|
|
* possible. You can make your directive as complicated as you require
|
|
|
|
* to express a solution to the problem you're tackling.
|
|
|
|
*
|
|
|
|
* See the definition/comment about the HANDLE_FUNC() macro to learn
|
|
|
|
* what arguments are supplied to the handler, and to determine what
|
|
|
|
* values to return.
|
|
|
|
*
|
|
|
|
***********************************************************************/
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_logfile)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->logf_name, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_pidfile)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->pidpath, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_anonymous)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *arg = get_string_arg (line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (!arg)
|
|
|
|
return -1;
|
2004-08-14 04:19:50 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
anonymous_insert (arg);
|
|
|
|
safefree (arg);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_viaproxyname)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
int r = set_string_arg (&conf->via_proxy_name, line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
log_message (LOG_INFO,
|
|
|
|
"Setting \"Via\" header proxy to %s",
|
|
|
|
conf->via_proxy_name);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-10-11 07:13:15 +08:00
|
|
|
static HANDLE_FUNC (handle_disableviaheader)
|
|
|
|
{
|
|
|
|
int r = set_bool_arg (&conf->disable_viaheader, line, &match[2]);
|
|
|
|
|
|
|
|
if (r) {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
log_message (LOG_INFO,
|
|
|
|
"Disabling transmission of the \"Via\" header.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_defaulterrorfile)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->errorpage_undef, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_statfile)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->statpage, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_stathost)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
int r = set_string_arg (&conf->stathost, line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
log_message (LOG_INFO, "Stathost set to \"%s\"", conf->stathost);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_xtinyproxy)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2005-08-15 11:54:31 +08:00
|
|
|
#ifdef XTINYPROXY_ENABLE
|
2009-09-27 17:54:38 +08:00
|
|
|
return set_bool_arg (&conf->add_xtinyproxy, line, &match[2]);
|
2004-08-14 05:03:58 +08:00
|
|
|
#else
|
2009-09-15 03:41:25 +08:00
|
|
|
fprintf (stderr,
|
|
|
|
"XTinyproxy NOT Enabled! Recompile with --enable-xtinyproxy\n");
|
|
|
|
return 1;
|
2004-08-14 05:03:58 +08:00
|
|
|
#endif
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_syslog)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2005-08-15 11:54:31 +08:00
|
|
|
#ifdef HAVE_SYSLOG_H
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->syslog, line, &match[2]);
|
2004-08-14 05:03:58 +08:00
|
|
|
#else
|
2009-09-15 03:41:25 +08:00
|
|
|
fprintf (stderr, "Syslog support not compiled in executable.\n");
|
|
|
|
return 1;
|
2004-08-14 05:03:58 +08:00
|
|
|
#endif
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_bindsame)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
int r = set_bool_arg (&conf->bindsame, line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
log_message (LOG_INFO, "Binding outgoing connection to incoming IP");
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_port)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_int_arg ((unsigned long int *) &conf->port, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_maxclients)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
child_configure (CHILD_MAXCLIENTS, get_int_arg (line, &match[2]));
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_maxspareservers)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
child_configure (CHILD_MAXSPARESERVERS, get_int_arg (line, &match[2]));
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_minspareservers)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
child_configure (CHILD_MINSPARESERVERS, get_int_arg (line, &match[2]));
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_startservers)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
child_configure (CHILD_STARTSERVERS, get_int_arg (line, &match[2]));
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_maxrequestsperchild)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
child_configure (CHILD_MAXREQUESTSPERCHILD,
|
|
|
|
get_int_arg (line, &match[2]));
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_timeout)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_int_arg ((unsigned long int *) &conf->idletimeout, line,
|
|
|
|
&match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_connectport)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-12-07 06:56:41 +08:00
|
|
|
add_connect_port_allowed (get_int_arg (line, &match[2]),
|
|
|
|
&conf->connect_ports);
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_user)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->user, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_group)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->group, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_allow)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *arg = get_string_arg (line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-12-07 06:30:23 +08:00
|
|
|
insert_acl (arg, ACL_ALLOW, &conf->access_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (arg);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_deny)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *arg = get_string_arg (line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-12-07 06:30:23 +08:00
|
|
|
insert_acl (arg, ACL_DENY, &conf->access_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (arg);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_bind)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2004-08-14 05:03:58 +08:00
|
|
|
#ifndef TRANSPARENT_PROXY
|
2009-09-15 03:41:25 +08:00
|
|
|
int r = set_string_arg (&conf->bind_address, line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
log_message (LOG_INFO,
|
|
|
|
"Outgoing connections bound to IP %s", conf->bind_address);
|
|
|
|
return 0;
|
2004-08-14 05:03:58 +08:00
|
|
|
#else
|
2009-09-15 03:41:25 +08:00
|
|
|
fprintf (stderr,
|
|
|
|
"\"Bind\" cannot be used with transparent support enabled.\n");
|
|
|
|
return 1;
|
2004-08-14 05:03:58 +08:00
|
|
|
#endif
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_listen)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
int r = set_string_arg (&conf->ipAddr, line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (r)
|
|
|
|
return r;
|
2009-11-14 21:27:31 +08:00
|
|
|
log_message (LOG_INFO, "Listening on IP %s", conf->ipAddr);
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_errorfile)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
/*
|
|
|
|
* Because an integer is defined as ((0x)?[[:digit:]]+) _two_
|
|
|
|
* match places are used. match[2] matches the full digit
|
|
|
|
* string, while match[3] matches only the "0x" part if
|
|
|
|
* present. This is why the "string" is located at
|
|
|
|
* match[4] (rather than the more intuitive match[3].
|
|
|
|
*/
|
|
|
|
unsigned long int err = get_int_arg (line, &match[2]);
|
|
|
|
char *page = get_string_arg (line, &match[4]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
add_new_errorpage (page, err);
|
|
|
|
safefree (page);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2004-08-14 11:18:41 +08:00
|
|
|
* Log level's strings.
|
2004-08-14 04:19:50 +08:00
|
|
|
*/
|
2009-09-15 03:41:25 +08:00
|
|
|
struct log_levels_s {
|
|
|
|
const char *string;
|
|
|
|
int level;
|
2004-08-14 04:19:50 +08:00
|
|
|
};
|
|
|
|
static struct log_levels_s log_levels[] = {
|
2009-09-15 03:41:25 +08:00
|
|
|
{"critical", LOG_CRIT},
|
|
|
|
{"error", LOG_ERR},
|
|
|
|
{"warning", LOG_WARNING},
|
|
|
|
{"notice", LOG_NOTICE},
|
|
|
|
{"connect", LOG_CONN},
|
|
|
|
{"info", LOG_INFO}
|
2004-08-14 04:19:50 +08:00
|
|
|
};
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_loglevel)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
static const unsigned int nlevels =
|
|
|
|
sizeof (log_levels) / sizeof (log_levels[0]);
|
|
|
|
unsigned int i;
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
char *arg = get_string_arg (line, &match[2]);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
for (i = 0; i != nlevels; ++i) {
|
|
|
|
if (!strcasecmp (arg, log_levels[i].string)) {
|
|
|
|
set_log_level (log_levels[i].level);
|
|
|
|
safefree (arg);
|
|
|
|
return 0;
|
|
|
|
}
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2008-03-31 08:56:45 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (arg);
|
|
|
|
return -1;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef FILTER_ENABLE
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_filter)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->filter, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_filterurls)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->filter_url, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_filterextended)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->filter_extended, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_filterdefaultdeny)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
assert (match[2].rm_so != -1);
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (get_bool_arg (line, &match[2]))
|
|
|
|
filter_set_default_policy (FILTER_DEFAULT_DENY);
|
|
|
|
return 0;
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_filtercasesensitive)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->filter_casesensitive, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
#endif
|
2004-08-14 04:19:50 +08:00
|
|
|
|
|
|
|
#ifdef REVERSE_SUPPORT
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_reverseonly)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->reverseonly, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_reversemagic)
|
2004-08-14 04:19:50 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_bool_arg (&conf->reversemagic, line, &match[2]);
|
2004-08-14 04:19:50 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_reversebaseurl)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
return set_string_arg (&conf->reversebaseurl, line, &match[2]);
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
2005-08-15 11:54:31 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_reversepath)
|
2004-08-14 11:18:41 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
/*
|
|
|
|
* The second string argument is optional.
|
|
|
|
*/
|
|
|
|
char *arg1, *arg2;
|
2004-08-14 11:18:41 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
arg1 = get_string_arg (line, &match[2]);
|
|
|
|
if (!arg1)
|
|
|
|
return -1;
|
2004-08-14 11:18:41 +08:00
|
|
|
|
2009-11-10 08:15:46 +08:00
|
|
|
if (match[4].rm_so != -1) {
|
|
|
|
arg2 = get_string_arg (line, &match[4]);
|
2009-09-15 03:41:25 +08:00
|
|
|
if (!arg2) {
|
|
|
|
safefree (arg1);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-12-07 05:53:17 +08:00
|
|
|
reversepath_add (arg1, arg2, &conf->reversepath_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (arg1);
|
|
|
|
safefree (arg2);
|
|
|
|
} else {
|
2009-12-07 05:53:17 +08:00
|
|
|
reversepath_add (NULL, arg1, &conf->reversepath_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (arg1);
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2004-08-14 11:18:41 +08:00
|
|
|
}
|
2004-08-14 04:19:50 +08:00
|
|
|
#endif
|
2005-11-04 13:15:47 +08:00
|
|
|
|
|
|
|
#ifdef UPSTREAM_SUPPORT
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_upstream)
|
|
|
|
{
|
|
|
|
char *ip;
|
|
|
|
int port;
|
|
|
|
char *domain;
|
|
|
|
|
|
|
|
ip = get_string_arg (line, &match[2]);
|
|
|
|
if (!ip)
|
|
|
|
return -1;
|
|
|
|
port = (int) get_int_arg (line, &match[7]);
|
|
|
|
|
|
|
|
if (match[9].rm_so != -1) {
|
|
|
|
domain = get_string_arg (line, &match[9]);
|
|
|
|
if (domain) {
|
2009-12-06 20:03:05 +08:00
|
|
|
upstream_add (ip, port, domain, &conf->upstream_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (domain);
|
|
|
|
}
|
|
|
|
} else {
|
2009-12-06 20:03:05 +08:00
|
|
|
upstream_add (ip, port, NULL, &conf->upstream_list);
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2005-11-04 13:15:47 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (ip);
|
2008-05-24 16:05:49 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2005-11-04 13:15:47 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
static HANDLE_FUNC (handle_upstream_no)
|
2005-11-04 13:15:47 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *domain;
|
2005-11-04 13:15:47 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
domain = get_string_arg (line, &match[2]);
|
|
|
|
if (!domain)
|
|
|
|
return -1;
|
2008-05-24 16:05:49 +08:00
|
|
|
|
2009-12-06 20:03:05 +08:00
|
|
|
upstream_add (NULL, 0, domain, &conf->upstream_list);
|
2009-09-15 03:41:25 +08:00
|
|
|
safefree (domain);
|
2005-11-04 13:15:47 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return 0;
|
2005-11-04 13:15:47 +08:00
|
|
|
}
|
|
|
|
#endif
|