1 const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.27 2001/11/07 00:02:13 steudten Exp $";
2 /*********************************************************************
4 * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $
6 * Purpose : Loads settings from the configuration file into
7 * global variables. This file contains both the
8 * routine to load the configuration and the global
9 * variables it writes to.
11 * Copyright : Written by and Copyright (C) 2001 the SourceForge
12 * IJBSWA team. http://ijbswa.sourceforge.net
14 * Based on the Internet Junkbuster originally written
15 * by and Copyright (C) 1997 Anonymous Coders and
16 * Junkbusters Corporation. http://www.junkbusters.com
18 * This program is free software; you can redistribute it
19 * and/or modify it under the terms of the GNU General
20 * Public License as published by the Free Software
21 * Foundation; either version 2 of the License, or (at
22 * your option) any later version.
24 * This program is distributed in the hope that it will
25 * be useful, but WITHOUT ANY WARRANTY; without even the
26 * implied warranty of MERCHANTABILITY or FITNESS FOR A
27 * PARTICULAR PURPOSE. See the GNU General Public
28 * License for more details.
30 * The GNU General Public License should be included with
31 * this file. If not, you can view it at
32 * http://www.gnu.org/copyleft/gpl.html
33 * or write to the Free Software Foundation, Inc., 59
34 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 * Revision 1.27 2001/11/07 00:02:13 steudten
39 * Add line number in error output for lineparsing for
40 * actionsfile and configfile.
41 * Special handling for CLF added.
43 * Revision 1.26 2001/11/05 21:41:43 steudten
44 * Add changes to be a real daemon just for unix os.
45 * (change cwd to /, detach from controlling tty, set
46 * process group and session leader to the own process.
48 * Add some fatal-error log message for failed malloc().
49 * Add '-d' if compiled with 'configure --with-debug' to
50 * enable debug output.
52 * Revision 1.25 2001/10/25 03:40:48 david__schmidt
53 * Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
54 * threads to call select() simultaneously. So, it's time to do a real, live,
55 * native OS/2 port. See defines for __EMX__ (the porting layer) vs. __OS2__
56 * (native). Both versions will work, but using __OS2__ offers multi-threading.
58 * Revision 1.24 2001/10/23 21:40:30 jongfoster
59 * Added support for enable-edit-actions and enable-remote-toggle config
62 * Revision 1.23 2001/10/07 15:36:00 oes
63 * Introduced new config option "buffer-limit"
65 * Revision 1.22 2001/09/22 16:36:59 jongfoster
66 * Removing unused parameter fs from read_config_line()
68 * Revision 1.21 2001/09/16 17:10:43 jongfoster
69 * Moving function savearg() here, since it was the only thing left in
72 * Revision 1.20 2001/07/30 22:08:36 jongfoster
73 * Tidying up #defines:
74 * - All feature #defines are now of the form FEATURE_xxx
75 * - Permanently turned off WIN_GUI_EDIT
76 * - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
78 * Revision 1.19 2001/07/15 17:45:16 jongfoster
79 * Removing some unused #includes
81 * Revision 1.18 2001/07/13 14:01:14 oes
82 * - Removed all #ifdef PCRS
83 * - Removed vim-settings
85 * Revision 1.17 2001/06/29 13:31:03 oes
87 * - Fixed (actionsfile) and sorted hashes
88 * - Introduced admin_address and proxy-info-url
89 * as config parameters
90 * - Renamed config->proxy_args_invocation (which didn't have
91 * the invocation but the options!) to config->proxy_args
93 * - Removed logentry from cancelled commit
95 * Revision 1.16 2001/06/09 10:55:28 jongfoster
96 * Changing BUFSIZ ==> BUFFER_SIZE
98 * Revision 1.15 2001/06/07 23:13:40 jongfoster
99 * Merging ACL and forward files into config file.
100 * Cosmetic: Sorting config file options alphabetically.
101 * Cosmetic: Adding brief syntax comments to config file options.
103 * Revision 1.14 2001/06/07 14:46:25 joergs
104 * Missing make_path() added for re_filterfile.
106 * Revision 1.13 2001/06/05 22:33:54 jongfoster
108 * Fixed minor memory leak.
109 * Also now uses make_path to prepend the pathnames.
111 * Revision 1.12 2001/06/05 20:04:09 jongfoster
112 * Now uses _snprintf() in place of snprintf() under Win32.
114 * Revision 1.11 2001/06/04 18:31:58 swa
115 * files are now prefixed with either `confdir' or `logdir'.
116 * `make redhat-dist' replaces both entries confdir and logdir
119 * Revision 1.10 2001/06/03 19:11:54 oes
120 * introduced confdir option
122 * Revision 1.9 2001/06/01 20:06:24 jongfoster
123 * Removed support for "tinygif" option - moved to actions file.
125 * Revision 1.8 2001/05/31 21:27:13 jongfoster
126 * Removed many options from the config file and into the
127 * "actions" file: add_forwarded, suppress_vanilla_wafer,
128 * wafer, add_header, user_agent, referer, from
129 * Also globally replaced "permission" with "action".
131 * Revision 1.7 2001/05/29 09:50:24 jongfoster
132 * Unified blocklist/imagelist/permissionslist.
133 * File format is still under discussion, but the internal changes
136 * Also modified interceptor behaviour:
137 * - We now intercept all URLs beginning with one of the following
138 * prefixes (and *only* these prefixes):
140 * * http://ijbswa.sf.net/config/
141 * * http://ijbswa.sourceforge.net/config/
142 * - New interceptors "home page" - go to http://i.j.b/ to see it.
143 * - Internal changes so that intercepted and fast redirect pages
144 * are not replaced with an image.
145 * - Interceptors now have the option to send a binary page direct
146 * to the client. (i.e. ijb-send-banner uses this)
147 * - Implemented show-url-info interceptor. (Which is why I needed
148 * the above interceptors changes - a typical URL is
149 * "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
150 * The previous mechanism would not have intercepted that, and
151 * if it had been intercepted then it then it would have replaced
154 * Revision 1.6 2001/05/26 00:28:36 jongfoster
155 * Automatic reloading of config file.
156 * Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
157 * Most of the global variables have been moved to a new
158 * struct configuration_spec, accessed through csp->config->globalname
159 * Most of the globals remaining are used by the Win32 GUI.
161 * Revision 1.5 2001/05/25 22:34:30 jongfoster
164 * Revision 1.4 2001/05/22 18:46:04 oes
166 * - Enabled filtering banners by size rather than URL
167 * by adding patterns that replace all standard banner
168 * sizes with the "Junkbuster" gif to the re_filterfile
170 * - Enabled filtering WebBugs by providing a pattern
171 * which kills all 1x1 images
173 * - Added support for PCRE_UNGREEDY behaviour to pcrs,
174 * which is selected by the (nonstandard and therefore
175 * capital) letter 'U' in the option string.
176 * It causes the quantifiers to be ungreedy by default.
177 * Appending a ? turns back to greedy (!).
179 * - Added a new interceptor ijb-send-banner, which
180 * sends back the "Junkbuster" gif. Without imagelist or
181 * MSIE detection support, or if tinygif = 1, or the
182 * URL isn't recognized as an imageurl, a lame HTML
183 * explanation is sent instead.
185 * - Added new feature, which permits blocking remote
186 * script redirects and firing back a local redirect
188 * The feature is conditionally compiled, i.e. it
189 * can be disabled with --disable-fast-redirects,
190 * plus it must be activated by a "fast-redirects"
191 * line in the config file, has its own log level
192 * and of course wants to be displayed by show-proxy-args
193 * Note: Boy, all the #ifdefs in 1001 locations and
194 * all the fumbling with configure.in and acconfig.h
195 * were *way* more work than the feature itself :-(
197 * - Because a generic redirect template was needed for
198 * this, tinygif = 3 now uses the same.
200 * - Moved GIFs, and other static HTTP response templates
205 * - Removed some >400 CRs again (Jon, you really worked
208 * Revision 1.3 2001/05/20 01:21:20 jongfoster
209 * Version 2.9.4 checkin.
210 * - Merged popupfile and cookiefile, and added control over PCRS
211 * filtering, in new "permissionsfile".
212 * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
213 * file error you now get a message box (in the Win32 GUI) rather
214 * than the program exiting with no explanation.
215 * - Made killpopup use the PCRS MIME-type checking and HTTP-header
217 * - Removed tabs from "config"
218 * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
219 * - Bumped up version number.
221 * Revision 1.2 2001/05/17 23:01:01 oes
222 * - Cleaned CRLF's from the sources and related files
224 * Revision 1.1.1.1 2001/05/15 13:58:58 oes
225 * Initial import of version 2.9.3 source tree
228 *********************************************************************/
234 #include <sys/types.h>
244 # include <windows.h>
247 # ifndef _WIN_CONSOLE
249 # endif /* ndef _WIN_CONSOLE */
251 /* VC++ has "_snprintf", not "snprintf" */
252 #define snprintf _snprintf
254 #else /* ifndef _WIN32 */
258 # include <sys/wait.h>
260 # include <sys/time.h>
261 # include <sys/stat.h>
271 #include "miscutil.h"
276 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
279 * Fix a problem with Solaris. There should be no effect on other
281 * Solaris's isspace() is a macro which uses it's argument directly
282 * as an array index. Therefore we need to make sure that high-bit
283 * characters generate +ve values, and ideally we also want to make
284 * the argument match the declared parameter type of "int".
286 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
287 #define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
289 #ifdef FEATURE_TOGGLE
290 /* by haroon - indicates if ijb is enabled */
291 int g_bToggleIJB = 1; /* JunkBusters is enabled by default. */
292 #endif /* def FEATURE_TOGGLE */
294 /* The filename of the configfile */
295 const char *configfile = NULL;
298 * CGI functions will later need access to the invocation args,
299 * so we will make argc and argv global.
302 const char **Argv = NULL;
304 static struct file_list *current_configfile = NULL;
308 * This takes the "cryptic" hash of each keyword and aliases them to
309 * something a little more readable. This also makes changing the
310 * hash values easier if they should change or the hash algorthm changes.
311 * Use the included "hash" program to find out what the hash will be
312 * for any string supplied on the command line. (Or just put it in the
313 * config file and read the number from the error message in the log).
315 * Please keep this list sorted alphabetically (but with the Windows
316 * console and GUI specific options last).
319 #define hash_actions_file 1196306641ul /* "actionsfile" */
320 #define hash_admin_address 4112573064ul /* "admin-address" */
321 #define hash_buffer_limit 1881726070ul /* "buffer-limit */
322 #define hash_confdir 1978389ul /* "confdir" */
323 #define hash_debug 78263ul /* "debug" */
324 #define hash_deny_access 1227333715ul /* "deny-access" */
325 #define hash_enable_edit_actions 2517097536ul /* "enable-edit-actions" */
326 #define hash_enable_remote_toggle 2979744683ul /* "enable-remote-toggle" */
327 #define hash_forward 2029845ul /* "forward" */
328 #define hash_forward_socks4 3963965521ul /* "forward-socks4" */
329 #define hash_forward_socks4a 2639958518ul /* "forward-socks4a" */
330 #define hash_jarfile 2046641ul /* "jarfile" */
331 #define hash_listen_address 1255650842ul /* "listen-address" */
332 #define hash_logdir 422889ul /* "logdir" */
333 #define hash_logfile 2114766ul /* "logfile" */
334 #define hash_permit_access 3587953268ul /* "permit-access" */
335 #define hash_proxy_info_url 3903079059ul /* "proxy-info-url" */
336 #define hash_re_filterfile 3877522444ul /* "re_filterfile" */
337 #define hash_single_threaded 4250084780ul /* "single-threaded" */
338 #define hash_suppress_blocklists 1948693308ul /* "suppress-blocklists" */
339 #define hash_toggle 447966ul /* "toggle" */
340 #define hash_trust_info_url 430331967ul /* "trust-info-url" */
341 #define hash_trustfile 56494766ul /* "trustfile" */
343 #define hash_activity_animation 1817904738ul /* "activity-animation" */
344 #define hash_close_button_minimizes 3651284693ul /* "close-button-minimizes" */
345 #define hash_hide_console 2048809870ul /* "hide-console" */
346 #define hash_log_buffer_size 2918070425ul /* "log-buffer-size" */
347 #define hash_log_font_name 2866730124ul /* "log-font-name" */
348 #define hash_log_font_size 2866731014ul /* "log-font-size" */
349 #define hash_log_highlight_messages 4032101240ul /* "log-highlight-messages" */
350 #define hash_log_max_lines 2868344173ul /* "log-max-lines" */
351 #define hash_log_messages 2291744899ul /* "log-messages" */
352 #define hash_show_on_task_bar 215410365ul /* "show-on-task-bar" */
355 static void savearg(char *c, char *o, struct configuration_spec * config);
357 /*********************************************************************
359 * Function : unload_configfile
361 * Description : Free the config structure and all components.
364 * 1 : data: struct configuration_spec to unload
368 *********************************************************************/
369 void unload_configfile (void * data)
371 struct configuration_spec * config = (struct configuration_spec *)data;
372 struct forward_spec *cur_fwd = config->forward;
374 struct access_control_list *cur_acl = config->acl;
376 while (cur_acl != NULL)
378 struct access_control_list * next_acl = cur_acl->next;
383 #endif /* def FEATURE_ACL */
385 while (cur_fwd != NULL)
387 struct forward_spec * next_fwd = cur_fwd->next;
388 free_url(cur_fwd->url);
390 freez(cur_fwd->gateway_host);
391 freez(cur_fwd->forward_host);
395 config->forward = NULL;
397 #ifdef FEATURE_COOKIE_JAR
398 if ( NULL != config->jar )
400 fclose( config->jar );
403 #endif /* def FEATURE_COOKIE_JAR */
405 freez(config->confdir);
406 freez(config->logdir);
408 freez(config->haddr);
409 freez(config->logfile);
411 freez(config->actions_file);
412 freez(config->admin_address);
413 freez(config->proxy_info_url);
414 freez(config->proxy_args);
416 #ifdef FEATURE_COOKIE_JAR
417 freez(config->jarfile);
418 #endif /* def FEATURE_COOKIE_JAR */
420 freez(config->re_filterfile);
425 /*********************************************************************
427 * Function : load_config
429 * Description : Load the config file and all parameters.
432 * 1 : csp = Client state (the config member will be
433 * filled in by this function).
435 * Returns : 0 => Ok, everything else is an error.
437 *********************************************************************/
438 struct configuration_spec * load_config(void)
440 char buf[BUFFER_SIZE];
442 FILE *configfp = NULL;
443 struct configuration_spec * config = NULL;
444 struct client_state * fake_csp;
445 struct file_list *fs;
446 unsigned long linenum = 0;
448 DBG(1, ("load_config() entered..\n") );
449 if ( !check_file_changed(current_configfile, configfile, &fs))
451 /* No need to load */
452 return ((struct configuration_spec *)current_configfile->f);
456 log_error(LOG_LEVEL_FATAL, "can't check configuration file '%s': %E",
461 log_error(LOG_LEVEL_INFO, "loading configuration file '%s':", configfile);
464 #ifdef FEATURE_TOGGLE
466 #endif /* def FEATURE_TOGGLE */
468 fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
474 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
475 /* Never get here - LOG_LEVEL_FATAL causes program exit */
479 * This is backwards from how it's usually done.
480 * Following the usual pattern, "fs" would be stored in a member
481 * variable in "csp", and then we'd access "config" from "fs->f",
482 * using a cast. However, "config" is used so often that a
483 * cast each time would be very ugly, and the extra indirection
484 * would waste CPU cycles. Therefore we store "config" in
485 * "csp->config", and "fs" in "csp->config->config_file_list".
487 config->config_file_list = fs;
493 config->multi_threaded = 1;
494 config->hport = HADDR_PORT;
495 config->buffer_limit = 4096 * 1024;
497 if ((configfp = fopen(configfile, "r")) == NULL)
499 log_error(LOG_LEVEL_FATAL, "can't open configuration file '%s': %E",
501 /* Never get here - LOG_LEVEL_FATAL causes program exit */
504 while (read_config_line(buf, sizeof(buf), configfp, &linenum) != NULL)
506 char cmd[BUFFER_SIZE];
507 char arg[BUFFER_SIZE];
508 char tmp[BUFFER_SIZE];
510 struct access_control_list *cur_acl;
511 #endif /* def FEATURE_ACL */
512 struct forward_spec *cur_fwd;
518 /* Copy command (i.e. up to space or tab) into cmd */
521 while (*p && (*p != ' ') && (*p != '\t'))
527 /* Skip over the whitespace in buf */
528 while (*p && ((*p == ' ') || (*p == '\t')))
533 /* Copy the argument into arg */
536 /* Should never happen, but check this anyway */
542 /* Make sure the command field is lower case */
547 *p = ijb_tolower(*p);
551 /* Save the argument for show-proxy-args */
552 savearg(cmd, arg, config);
555 switch( hash_string( cmd ) )
557 /****************************************************************************
558 * actionsfile actions-file-name
559 * In confdir by default
560 ****************************************************************************/
561 case hash_actions_file :
562 freez(config->actions_file);
563 config->actions_file = make_path(config->confdir, arg);
566 /****************************************************************************
567 * admin-address email-address
568 ****************************************************************************/
569 case hash_admin_address :
570 freez(config->admin_address);
571 config->admin_address = strdup(arg);
574 /****************************************************************************
576 ****************************************************************************/
577 case hash_buffer_limit :
578 config->buffer_limit = (size_t) 1024 * atoi(arg);
581 /****************************************************************************
582 * confdir directory-name
583 ****************************************************************************/
585 freez(config->confdir);
586 config->confdir = make_path( NULL, arg);
589 /****************************************************************************
591 * Specifies debug level, multiple values are ORed together.
592 ****************************************************************************/
594 config->debug |= atoi(arg);
597 /****************************************************************************
598 * deny-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
599 ****************************************************************************/
601 case hash_deny_access:
602 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
604 if ((vec_count != 1) && (vec_count != 2))
606 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
607 "deny-access directive in configuration file.");
608 config->proxy_args = strsav( config->proxy_args,
609 "<br>\nWARNING: Wrong number of parameters for "
610 "deny-access directive in configuration file.<br><br>\n");
614 /* allocate a new node */
615 cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
619 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
620 /* Never get here - LOG_LEVEL_FATAL causes program exit */
623 cur_acl->action = ACL_DENY;
625 if (acl_addr(vec[0], cur_acl->src) < 0)
627 log_error(LOG_LEVEL_ERROR, "Invalid source IP for deny-access "
628 "directive in configuration file: \"%s\"", vec[0]);
629 config->proxy_args = strsav( config->proxy_args,
630 "<br>\nWARNING: Invalid source IP for deny-access directive"
631 " in configuration file: \"");
632 config->proxy_args = strsav( config->proxy_args,
634 config->proxy_args = strsav( config->proxy_args,
641 if (acl_addr(vec[1], cur_acl->dst) < 0)
643 log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access "
644 "directive in configuration file: \"%s\"", vec[0]);
645 config->proxy_args = strsav( config->proxy_args,
646 "<br>\nWARNING: Invalid destination IP for deny-access directive"
647 " in configuration file: \"");
648 config->proxy_args = strsav( config->proxy_args,
650 config->proxy_args = strsav( config->proxy_args,
658 * Add it to the list. Note we reverse the list to get the
659 * behaviour the user expects. With both the ACL and
660 * actions file, the last match wins. However, the internal
661 * implementations are different: The actions file is stored
662 * in the same order as the file, and scanned completely.
663 * With the ACL, we reverse the order as we load it, then
664 * when we scan it we stop as soon as we get a match.
666 cur_acl->next = config->acl;
667 config->acl = cur_acl;
670 #endif /* def FEATURE_ACL */
672 /****************************************************************************
673 * enable-edit-actions 0|1
674 ****************************************************************************/
675 #ifdef FEATURE_CGI_EDIT_ACTIONS
676 case hash_enable_edit_actions:
677 if ((*arg != '\0') && (0 != atoi(arg)))
679 config->feature_flags |= RUNTIME_FEATURE_CGI_EDIT_ACTIONS;
683 config->feature_flags &= ~RUNTIME_FEATURE_CGI_EDIT_ACTIONS;
686 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
688 /****************************************************************************
689 * enable-remote-toggle 0|1
690 ****************************************************************************/
691 #ifdef FEATURE_CGI_EDIT_ACTIONS
692 case hash_enable_remote_toggle:
693 if ((*arg != '\0') && (0 != atoi(arg)))
695 config->feature_flags |= RUNTIME_FEATURE_CGI_TOGGLE;
699 config->feature_flags &= ~RUNTIME_FEATURE_CGI_TOGGLE;
702 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
704 /****************************************************************************
705 * forward url-pattern (.|http-proxy-host[:port])
706 ****************************************************************************/
708 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
712 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for forward "
713 "directive in configuration file.");
714 config->proxy_args = strsav( config->proxy_args,
715 "<br>\nWARNING: Wrong number of parameters for "
716 "forward directive in configuration file.");
720 /* allocate a new node */
721 cur_fwd = zalloc(sizeof(*cur_fwd));
724 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
725 /* Never get here - LOG_LEVEL_FATAL causes program exit */
729 cur_fwd->type = SOCKS_NONE;
731 /* Save the URL pattern */
732 if (create_url_spec(cur_fwd->url, vec[0]))
734 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward "
735 "directive in configuration file.");
736 config->proxy_args = strsav( config->proxy_args,
737 "<br>\nWARNING: Bad URL specifier for "
738 "forward directive in configuration file.");
742 /* Parse the parent HTTP proxy host:port */
745 if (strcmp(p, ".") != 0)
747 cur_fwd->forward_host = strdup(p);
749 if ((p = strchr(cur_fwd->forward_host, ':')))
752 cur_fwd->forward_port = atoi(p);
755 if (cur_fwd->forward_port <= 0)
757 cur_fwd->forward_port = 8000;
762 cur_fwd->next = config->forward;
763 config->forward = cur_fwd;
767 /****************************************************************************
768 * forward-socks4 url-pattern socks-proxy[:port] (.|http-proxy[:port])
769 ****************************************************************************/
770 case hash_forward_socks4:
771 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
775 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
776 "forward-socks4 directive in configuration file.");
777 config->proxy_args = strsav( config->proxy_args,
778 "<br>\nWARNING: Wrong number of parameters for "
779 "forward-socks4 directive in configuration file.");
783 /* allocate a new node */
784 cur_fwd = zalloc(sizeof(*cur_fwd));
787 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
788 /* Never get here - LOG_LEVEL_FATAL causes program exit */
792 cur_fwd->type = SOCKS_4;
794 /* Save the URL pattern */
795 if (create_url_spec(cur_fwd->url, vec[0]))
797 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4 "
798 "directive in configuration file.");
799 config->proxy_args = strsav( config->proxy_args,
800 "<br>\nWARNING: Bad URL specifier for "
801 "forward-socks4 directive in configuration file.");
805 /* Parse the SOCKS proxy host[:port] */
808 if (strcmp(p, ".") != 0)
810 cur_fwd->gateway_host = strdup(p);
812 if ((p = strchr(cur_fwd->gateway_host, ':')))
815 cur_fwd->gateway_port = atoi(p);
817 if (cur_fwd->gateway_port <= 0)
819 cur_fwd->gateway_port = 1080;
823 /* Parse the parent HTTP proxy host[:port] */
826 if (strcmp(p, ".") != 0)
828 cur_fwd->forward_host = strdup(p);
830 if ((p = strchr(cur_fwd->forward_host, ':')))
833 cur_fwd->forward_port = atoi(p);
836 if (cur_fwd->forward_port <= 0)
838 cur_fwd->forward_port = 8000;
843 cur_fwd->next = config->forward;
844 config->forward = cur_fwd;
848 /****************************************************************************
849 * forward-socks4a url-pattern socks-proxy[:port] (.|http-proxy[:port])
850 ****************************************************************************/
851 case hash_forward_socks4a:
852 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
856 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
857 "forward-socks4a directive in configuration file.");
858 config->proxy_args = strsav( config->proxy_args,
859 "<br>\nWARNING: Wrong number of parameters for "
860 "forward-socks4a directive in configuration file.");
864 /* allocate a new node */
865 cur_fwd = zalloc(sizeof(*cur_fwd));
868 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
869 /* Never get here - LOG_LEVEL_FATAL causes program exit */
873 cur_fwd->type = SOCKS_4A;
875 /* Save the URL pattern */
876 if (create_url_spec(cur_fwd->url, vec[0]))
878 log_error(LOG_LEVEL_ERROR, "Bad URL specifier for forward-socks4a "
879 "directive in configuration file.");
880 config->proxy_args = strsav( config->proxy_args,
881 "<br>\nWARNING: Bad URL specifier for "
882 "forward-socks4a directive in configuration file.");
886 /* Parse the SOCKS proxy host[:port] */
889 cur_fwd->gateway_host = strdup(p);
891 if ((p = strchr(cur_fwd->gateway_host, ':')))
894 cur_fwd->gateway_port = atoi(p);
896 if (cur_fwd->gateway_port <= 0)
898 cur_fwd->gateway_port = 1080;
901 /* Parse the parent HTTP proxy host[:port] */
904 if (strcmp(p, ".") != 0)
906 cur_fwd->forward_host = strdup(p);
908 if ((p = strchr(cur_fwd->forward_host, ':')))
911 cur_fwd->forward_port = atoi(p);
914 if (cur_fwd->forward_port <= 0)
916 cur_fwd->forward_port = 8000;
921 cur_fwd->next = config->forward;
922 config->forward = cur_fwd;
926 /****************************************************************************
927 * jarfile jar-file-name
928 * In logdir by default
929 ****************************************************************************/
930 #ifdef FEATURE_COOKIE_JAR
932 freez(config->jarfile);
933 config->jarfile = make_path(config->logdir, arg);
935 #endif /* def FEATURE_COOKIE_JAR */
937 /****************************************************************************
938 * listen-address [ip][:port]
939 ****************************************************************************/
940 case hash_listen_address :
941 freez(config->haddr);
942 config->haddr = strdup(arg);
945 /****************************************************************************
946 * logdir directory-name
947 ****************************************************************************/
949 freez(config->logdir);
950 config->logdir = make_path(NULL, arg);
953 /****************************************************************************
954 * logfile log-file-name
955 * In logdir by default
956 ****************************************************************************/
958 freez(config->logfile);
959 config->logfile = make_path(config->logdir, arg);
962 /****************************************************************************
963 * permit-access source-ip[/significant-bits] [dest-ip[/significant-bits]]
964 ****************************************************************************/
966 case hash_permit_access:
967 vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
969 if ((vec_count != 1) && (vec_count != 2))
971 log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
972 "permit-access directive in configuration file.");
973 config->proxy_args = strsav( config->proxy_args,
974 "<br>\nWARNING: Wrong number of parameters for "
975 "permit-access directive in configuration file.<br><br>\n");
980 /* allocate a new node */
981 cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
985 log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
986 /* Never get here - LOG_LEVEL_FATAL causes program exit */
989 cur_acl->action = ACL_PERMIT;
991 if (acl_addr(vec[0], cur_acl->src) < 0)
993 log_error(LOG_LEVEL_ERROR, "Invalid source IP for permit-access "
994 "directive in configuration file: \"%s\"", vec[0]);
995 config->proxy_args = strsav( config->proxy_args,
996 "<br>\nWARNING: Invalid source IP for permit-access directive"
997 " in configuration file: \"");
998 config->proxy_args = strsav( config->proxy_args,
1000 config->proxy_args = strsav( config->proxy_args,
1007 if (acl_addr(vec[1], cur_acl->dst) < 0)
1009 log_error(LOG_LEVEL_ERROR, "Invalid destination IP for "
1010 "permit-access directive in configuration file: \"%s\"",
1012 config->proxy_args = strsav( config->proxy_args,
1013 "<br>\nWARNING: Invalid destination IP for permit-access directive"
1014 " in configuration file: \"");
1015 config->proxy_args = strsav( config->proxy_args,
1017 config->proxy_args = strsav( config->proxy_args,
1025 * Add it to the list. Note we reverse the list to get the
1026 * behaviour the user expects. With both the ACL and
1027 * actions file, the last match wins. However, the internal
1028 * implementations are different: The actions file is stored
1029 * in the same order as the file, and scanned completely.
1030 * With the ACL, we reverse the order as we load it, then
1031 * when we scan it we stop as soon as we get a match.
1033 cur_acl->next = config->acl;
1034 config->acl = cur_acl;
1037 #endif /* def FEATURE_ACL */
1039 /****************************************************************************
1040 * proxy-info-url url
1041 ****************************************************************************/
1042 case hash_proxy_info_url :
1043 freez(config->proxy_info_url);
1044 config->proxy_info_url = strdup(arg);
1047 /****************************************************************************
1048 * re_filterfile file-name
1049 * In confdir by default.
1050 ****************************************************************************/
1051 case hash_re_filterfile :
1052 freez(config->re_filterfile);
1053 config->re_filterfile = make_path(config->confdir, arg);
1056 /****************************************************************************
1058 ****************************************************************************/
1059 case hash_single_threaded :
1060 config->multi_threaded = 0;
1063 /****************************************************************************
1065 ****************************************************************************/
1066 #ifdef FEATURE_TOGGLE
1068 g_bToggleIJB = atoi(arg);
1070 #endif /* def FEATURE_TOGGLE */
1072 /****************************************************************************
1073 * trust-info-url url
1074 ****************************************************************************/
1075 #ifdef FEATURE_TRUST
1076 case hash_trust_info_url :
1077 enlist(config->trust_info, arg);
1079 #endif /* def FEATURE_TRUST */
1081 /****************************************************************************
1082 * trustfile filename
1083 * (In confdir by default.)
1084 ****************************************************************************/
1085 #ifdef FEATURE_TRUST
1086 case hash_trustfile :
1087 freez(config->trustfile);
1088 config->trustfile = make_path(config->confdir, arg);
1090 #endif /* def FEATURE_TRUST */
1093 /****************************************************************************
1094 * Win32 Console options:
1095 ****************************************************************************/
1097 /****************************************************************************
1099 ****************************************************************************/
1101 case hash_hide_console :
1104 #endif /*def _WIN_CONSOLE*/
1107 /****************************************************************************
1108 * Win32 GUI options:
1109 ****************************************************************************/
1111 #if defined(_WIN32) && ! defined(_WIN_CONSOLE)
1112 /****************************************************************************
1113 * activity-animation (0|1)
1114 ****************************************************************************/
1115 case hash_activity_animation :
1116 g_bShowActivityAnimation = atoi(arg);
1119 /****************************************************************************
1120 * close-button-minimizes (0|1)
1121 ****************************************************************************/
1122 case hash_close_button_minimizes :
1123 g_bCloseHidesWindow = atoi(arg);
1126 /****************************************************************************
1127 * log-buffer-size (0|1)
1128 ****************************************************************************/
1129 case hash_log_buffer_size :
1130 g_bLimitBufferSize = atoi(arg);
1133 /****************************************************************************
1134 * log-font-name fontnane
1135 ****************************************************************************/
1136 case hash_log_font_name :
1137 strcpy( g_szFontFaceName, arg );
1140 /****************************************************************************
1142 ****************************************************************************/
1143 case hash_log_font_size :
1144 g_nFontSize = atoi(arg);
1147 /****************************************************************************
1148 * log-highlight-messages (0|1)
1149 ****************************************************************************/
1150 case hash_log_highlight_messages :
1151 g_bHighlightMessages = atoi(arg);
1154 /****************************************************************************
1156 ****************************************************************************/
1157 case hash_log_max_lines :
1158 g_nMaxBufferLines = atoi(arg);
1161 /****************************************************************************
1162 * log-messages (0|1)
1163 ****************************************************************************/
1164 case hash_log_messages :
1165 g_bLogMessages = atoi(arg);
1168 /****************************************************************************
1169 * show-on-task-bar (0|1)
1170 ****************************************************************************/
1171 case hash_show_on_task_bar :
1172 g_bShowOnTaskBar = atoi(arg);
1175 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
1178 /****************************************************************************/
1179 /* Warnings about unsupported features */
1180 /****************************************************************************/
1182 case hash_deny_access:
1183 #endif /* ndef FEATURE_ACL */
1184 #ifndef FEATURE_CGI_EDIT_ACTIONS
1185 case hash_enable_edit_actions:
1186 case hash_enable_remote_toggle:
1187 #endif /* def FEATURE_CGI_EDIT_ACTIONS */
1188 #ifndef FEATURE_COOKIE_JAR
1190 #endif /* ndef FEATURE_COOKIE_JAR */
1192 case hash_permit_access:
1193 #endif /* ndef FEATURE_ACL */
1194 #ifndef FEATURE_TOGGLE
1196 #endif /* ndef FEATURE_TOGGLE */
1197 #ifndef FEATURE_TRUST
1198 case hash_trustfile :
1199 case hash_trust_info_url :
1200 #endif /* ndef FEATURE_TRUST */
1202 #ifndef _WIN_CONSOLE
1203 case hash_hide_console :
1204 #endif /* ndef _WIN_CONSOLE */
1206 #if defined(_WIN_CONSOLE) || ! defined(_WIN32)
1207 case hash_activity_animation :
1208 case hash_close_button_minimizes :
1209 case hash_log_buffer_size :
1210 case hash_log_font_name :
1211 case hash_log_font_size :
1212 case hash_log_highlight_messages :
1213 case hash_log_max_lines :
1214 case hash_log_messages :
1215 case hash_show_on_task_bar :
1216 #endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
1217 /* These warnings are annoying - so hide them. -- Jon */
1218 /* log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd); */
1221 /****************************************************************************/
1223 /****************************************************************************/
1225 * I decided that I liked this better as a warning than an
1226 * error. To change back to an error, just change log level
1227 * to LOG_LEVEL_FATAL.
1229 log_error(LOG_LEVEL_ERROR, "Unrecognized directive '%s' in line %lu in "
1230 "configuration file (%s).", buf, linenum, configfile);
1231 /* log_error(LOG_LEVEL_ERROR, "Unrecognized directive (%luul) in "
1232 "configuration file: \"%s\"", hash_string( cmd ), buf);
1234 config->proxy_args = strsav( config->proxy_args, "<br>\nWARNING: unrecognized directive : ");
1235 config->proxy_args = strsav( config->proxy_args, buf);
1236 config->proxy_args = strsav( config->proxy_args, "<br><br>\n");
1239 /****************************************************************************/
1240 } /* end switch( hash_string(cmd) ) */
1241 } /* end while ( read_config_line(...) ) */
1245 init_error_log(Argv[0], config->logfile, config->debug);
1247 if (config->actions_file)
1249 add_loader(load_actions_file, config);
1252 if (config->re_filterfile)
1254 add_loader(load_re_filterfile, config);
1257 #ifdef FEATURE_TRUST
1258 if (config->trustfile)
1260 add_loader(load_trustfile, config);
1262 #endif /* def FEATURE_TRUST */
1264 #ifdef FEATURE_COOKIE_JAR
1265 if ( NULL != config->jarfile )
1267 if ( NULL == (config->jar = fopen(config->jarfile, "a")) )
1269 log_error(LOG_LEVEL_FATAL, "can't open jarfile '%s': %E", config->jarfile);
1270 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1272 setbuf(config->jar, NULL);
1274 #endif /* def FEATURE_COOKIE_JAR */
1276 if ( NULL == config->haddr )
1278 config->haddr = strdup( HADDR_DEFAULT );
1281 if ( NULL != config->haddr )
1283 if ((p = strchr(config->haddr, ':')))
1288 config->hport = atoi(p);
1292 if (config->hport <= 0)
1295 log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
1296 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1298 if (*config->haddr == '\0')
1300 config->haddr = NULL;
1305 * Want to run all the loaders once now.
1307 * Need to set up a fake csp, so they can get to the config.
1309 fake_csp = (struct client_state *) zalloc (sizeof(*fake_csp));
1310 fake_csp->config = config;
1312 if (run_loader(fake_csp))
1315 log_error(LOG_LEVEL_FATAL, "A loader failed while loading config file. Exiting.");
1316 /* Never get here - LOG_LEVEL_FATAL causes program exit */
1320 /* FIXME: this is a kludge for win32 */
1321 #if defined(_WIN32) && !defined (_WIN_CONSOLE)
1323 g_actions_file = config->actions_file;
1324 g_re_filterfile = config->re_filterfile;
1326 #ifdef FEATURE_TRUST
1327 g_trustfile = config->trustfile;
1328 #endif /* def FEATURE_TRUST */
1331 #endif /* defined(_WIN32) && !defined (_WIN_CONSOLE) */
1332 /* FIXME: end kludge */
1335 config->need_bind = 1;
1337 if (current_configfile)
1339 struct configuration_spec * oldcfg = (struct configuration_spec *)
1340 current_configfile->f;
1342 * Check if config->haddr,hport == oldcfg->haddr,hport
1344 * The following could be written more compactly as a single,
1345 * (unreadably long) if statement.
1347 config->need_bind = 0;
1348 if (config->hport != oldcfg->hport)
1350 config->need_bind = 1;
1352 else if (config->haddr == NULL)
1354 if (oldcfg->haddr != NULL)
1356 config->need_bind = 1;
1359 else if (oldcfg->haddr == NULL)
1361 config->need_bind = 1;
1363 else if (0 != strcmp(config->haddr, oldcfg->haddr))
1365 config->need_bind = 1;
1368 current_configfile->unloader = unload_configfile;
1371 fs->next = files->next;
1374 current_configfile = fs;
1381 /*********************************************************************
1383 * Function : savearg
1385 * Description : Called from `load_config'. It saves each non-empty
1386 * and non-comment line from config into a list. This
1387 * list is used to create the show-proxy-args page.
1390 * 1 : c = config setting that was found
1391 * 2 : o = the setting's argument (if any)
1395 *********************************************************************/
1396 static void savearg(char *c, char *o, struct configuration_spec * config)
1398 char buf[BUFFER_SIZE];
1402 if ( ( NULL != c ) && ( '\0' != *c ) )
1404 if ((c = html_encode(c)))
1406 sprintf(buf, "<a href=\"" REDIRECT_URL "option#%s\">%s</a> ", c, c);
1410 if ( ( NULL != o ) && ( '\0' != *o ) )
1412 if ((o = html_encode(o)))
1414 if (strncmpic(o, "http://", 7) == 0)
1416 strcat(buf, "<a href=\"");
1420 strcat(buf, "</a>");
1430 strcat(buf, "<br>\n");
1432 config->proxy_args = strsav(config->proxy_args, buf);