1 const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.4 2001/05/22 18:46:04 oes 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.4 2001/05/22 18:46:04 oes
40 * - Enabled filtering banners by size rather than URL
41 * by adding patterns that replace all standard banner
42 * sizes with the "Junkbuster" gif to the re_filterfile
44 * - Enabled filtering WebBugs by providing a pattern
45 * which kills all 1x1 images
47 * - Added support for PCRE_UNGREEDY behaviour to pcrs,
48 * which is selected by the (nonstandard and therefore
49 * capital) letter 'U' in the option string.
50 * It causes the quantifiers to be ungreedy by default.
51 * Appending a ? turns back to greedy (!).
53 * - Added a new interceptor ijb-send-banner, which
54 * sends back the "Junkbuster" gif. Without imagelist or
55 * MSIE detection support, or if tinygif = 1, or the
56 * URL isn't recognized as an imageurl, a lame HTML
57 * explanation is sent instead.
59 * - Added new feature, which permits blocking remote
60 * script redirects and firing back a local redirect
62 * The feature is conditionally compiled, i.e. it
63 * can be disabled with --disable-fast-redirects,
64 * plus it must be activated by a "fast-redirects"
65 * line in the config file, has its own log level
66 * and of course wants to be displayed by show-proxy-args
67 * Note: Boy, all the #ifdefs in 1001 locations and
68 * all the fumbling with configure.in and acconfig.h
69 * were *way* more work than the feature itself :-(
71 * - Because a generic redirect template was needed for
72 * this, tinygif = 3 now uses the same.
74 * - Moved GIFs, and other static HTTP response templates
79 * - Removed some >400 CRs again (Jon, you really worked
82 * Revision 1.3 2001/05/20 01:21:20 jongfoster
83 * Version 2.9.4 checkin.
84 * - Merged popupfile and cookiefile, and added control over PCRS
85 * filtering, in new "permissionsfile".
86 * - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
87 * file error you now get a message box (in the Win32 GUI) rather
88 * than the program exiting with no explanation.
89 * - Made killpopup use the PCRS MIME-type checking and HTTP-header
91 * - Removed tabs from "config"
92 * - Moved duplicated url parsing code in "loaders.c" to a new funcition.
93 * - Bumped up version number.
95 * Revision 1.2 2001/05/17 23:01:01 oes
96 * - Cleaned CRLF's from the sources and related files
98 * Revision 1.1.1.1 2001/05/15 13:58:58 oes
99 * Initial import of version 2.9.3 source tree
102 *********************************************************************/
108 #include <sys/types.h>
118 # include <sys/timeb.h>
119 # include <windows.h>
121 # include <process.h>
124 # endif /* def TOGGLE */
127 # ifndef _WIN_CONSOLE
129 # endif /* ndef _WIN_CONSOLE */
131 #else /* ifndef _WIN32 */
134 # include <sys/time.h>
135 # include <sys/wait.h>
136 # include <sys/stat.h>
145 #include "showargs.h"
147 #include "killpopup.h"
148 #include "miscutil.h"
150 #include "jbsockets.h"
153 const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
156 * Fix a problem with Solaris. There should be no effect on other
158 * Solaris's isspace() is a macro which uses it's argument directly
159 * as an array index. Therefore we need to make sure that high-bit
160 * characters generate +ve values, and ideally we also want to make
161 * the argument match the declared parameter type of "int".
163 #define ijb_isupper(__X) isupper((int)(unsigned char)(__X))
164 #define ijb_tolower(__X) tolower((int)(unsigned char)(__X))
166 static const char VANILLA_WAFER[] =
167 "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
168 "Do_not_send_me_any_copyrighted_information_other_than_the_"
169 "document_that_I_am_requesting_or_any_of_its_necessary_components._"
170 "In_particular_do_not_send_me_any_cookies_that_"
171 "are_subject_to_a_claim_of_copyright_by_anybody._"
172 "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
173 "(copyright_or_otherwise)_applying_to_any_cookie._";
176 /* by haroon - indicates if ijb is enabled */
177 int g_bToggleIJB = 1; /* JunkBusters is enabled by default. */
181 int multi_threaded = 1;
183 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
185 const char *tinygifurl = NULL;
186 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
188 const char *logfile = NULL;
190 const char *configfile = NULL;
192 const char *blockfile = NULL;
193 const char *permissions_file = NULL;
194 const char *forwardfile = NULL;
197 const char *aclfile = NULL;
198 #endif /* def ACL_FILES */
200 #ifdef USE_IMAGE_LIST
201 const char *imagefile = NULL;
202 #endif /* def USE_IMAGE_LIST */
205 * Permissions to use for URLs not in the permissions list.
207 int default_permissions = PERMIT_RE_FILTER;
210 const char *re_filterfile = NULL;
211 #endif /* def PCRS */
213 #ifdef FAST_REDIRECTS
214 int fast_redirects = 0;
215 #endif /* def FAST_REDIRECTS */
218 const char *trustfile = NULL;
219 #endif /* def TRUST_FILES */
222 const char *jarfile = NULL;
224 #endif /* def JAR_FILES */
226 const char *referrer = NULL;
227 const char *uagent = NULL;
228 const char *from = NULL;
230 #ifndef SPLIT_PROXY_ARGS
231 const char *suppress_message = NULL;
232 #endif /* ndef SPLIT_PROXY_ARGS */
234 int suppress_vanilla_wafer = 0;
235 int add_forwarded = 0;
237 struct list wafer_list[1];
238 struct list xtra_list[1];
241 struct list trust_info[1];
242 struct url_spec *trust_list[64];
243 #endif /* def TRUST_FILES */
246 * Port and IP to bind to.
247 * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8000
249 const char *haddr = NULL;
252 #ifndef SPLIT_PROXY_ARGS
253 int suppress_blocklists = 0; /* suppress listing sblock and simage */
254 #endif /* ndef SPLIT_PROXY_ARGS */
256 struct proxy_args proxy_args[1];
259 int config_changed = 0;
263 * The load_config function is now going to call `init_proxy_args',
264 * so it will need argc and argv. Since load_config will also be
265 * a signal handler, we need to have these globally available.
268 const char **Argv = NULL;
272 * This takes the "cryptic" hash of each keyword and aliases them to
273 * something a little more readable. This also makes changing the
274 * hash values easier if they should change or the hash algorthm changes.
275 * Use the included "hash" program to find out what the hash will be
276 * for any string supplied on the command line. (Or just put it in the
277 * config file and read the number from the error message in the log).
280 #define hash_trustfile 56494766ul
281 #define hash_trust_info_url 449869467ul
282 #define hash_debug 78263ul
283 #define hash_tinygif 2227702ul
284 #define hash_add_forwarded_header 3191044770ul
285 #define hash_single_threaded 4250084780ul
286 #define hash_suppress_vanilla_wafer 3121233547ul
287 #define hash_wafer 89669ul
288 #define hash_add_header 237434619ul
289 #define hash_permissions_file 3825730796lu /* "permissionsfile" */
290 #define hash_logfile 2114766ul
291 #define hash_blockfile 48845391ul
292 #define hash_imagefile 51447891ul
293 #define hash_jarfile 2046641ul
294 #define hash_listen_address 1255650842ul
295 #define hash_forwardfile 1268669141ul
296 #define hash_aclfile 1908516ul
297 #define hash_re_filterfile 3877522444ul
298 #define hash_user_agent 283326691ul
299 #define hash_referrer 10883969ul
300 #define hash_referer 2176719ul
301 #define hash_from 16264ul
302 #define hash_fast_redirects 464873764lu
303 #define hash_hide_console 2048809870ul
304 #define hash_include_stats 2174146548ul
305 #define hash_suppress_blocklists 1948693308ul
306 #define hash_toggle 447966ul
308 #define hash_activity_animation 1817904738ul
309 #define hash_log_messages 2291744899ul
310 #define hash_log_highlight_messages 4032101240ul
311 #define hash_log_buffer_size 2918070425ul
312 #define hash_log_max_lines 2868344173ul
313 #define hash_log_font_name 2866730124ul
314 #define hash_log_font_size 2866731014ul
315 #define hash_show_on_task_bar 215410365ul
316 #define hash_close_button_minimizes 3651284693ul
319 /*********************************************************************
321 * Function : load_config
323 * Description : Load the config file and all parameters.
326 * 1 : signum : this can be the signal SIGHUP or 0 (if from main).
327 * In any case, we just ignore this and reload the config file.
329 * Returns : configret : 0 => Ok, everything else is an error.
330 * Note: we use configret since a signal handler cannot
331 * return a value, and this function does double duty.
332 * Ie. Is is called from main and from signal( SIGHUP );
334 *********************************************************************/
335 void load_config( int signum )
339 FILE *configfp = NULL;
341 configret = 0; /* FIXME: This is obsolete, always 0. */
344 log_error(LOG_LEVEL_INFO, "loading configuration file '%s':", configfile);
346 init_proxy_args(Argc, Argv);
349 /* (Waste of memory [not quite a "leak"] here. The
350 * last blockfile/permissions file/... etc will not be
351 * unloaded until we load a new one. If the
352 * block/... feature has been disabled in
353 * the new config file, then we're wasting some
354 * memory we could otherwise reclaim.
357 /* Disable all loaders. */
358 remove_all_loaders();
361 * Reset to as close to startup state as we can.
362 * But leave changing the logfile until after we're done loading.
371 #endif /* def JAR_FILES */
376 default_permissions = PERMIT_RE_FILTER;
378 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
380 freez((char *)tinygifurl);
381 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
383 suppress_vanilla_wafer = 0;
389 #endif /*def _WIN_CONSOLE*/
398 #endif /* def STATISTICS */
400 #ifndef SPLIT_PROXY_ARGS
401 suppress_blocklists = 0;
402 #endif /* ndef SPLIT_PROXY_ARGS */
405 freez((char *)haddr);
406 freez((char *)uagent);
407 freez((char *)referrer);
408 freez((char *)logfile);
411 freez((char *)blockfile);
412 freez((char *)permissions_file);
413 freez((char *)forwardfile);
416 freez((char *)aclfile);
417 #endif /* def ACL_FILES */
419 #ifdef USE_IMAGE_LIST
420 freez((char *)imagefile);
421 #endif /* def USE_IMAGE_LIST */
424 freez((char *)jarfile);
425 #endif /* def JAR_FILES */
427 #ifndef SPLIT_PROXY_ARGS
428 freez((char *)suppress_message);
429 #endif /* ndef SPLIT_PROXY_ARGS */
432 freez((char *)trustfile);
433 #endif /* def TRUST_FILES */
436 freez((char *)re_filterfile);
437 #endif /* def PCRS */
439 #ifdef FAST_REDIRECTS
441 #endif /* def FAST_REDIRECTS */
443 if (NULL != configfile)
445 if ((configfp = fopen(configfile, "r")) == NULL)
447 log_error(LOG_LEVEL_FATAL, "can't open configuration file '%s': %E",
449 /* Never get here - LOG_LEVEL_FATAL causes program exit */
453 if (NULL != configfp)
455 memset (buf, 'j', sizeof(buf));
456 while (read_config_line(buf, sizeof(buf), configfp, NULL) != NULL)
464 /* Copy command (i.e. up to space or tab) into cmd */
467 while (*p && (*p != ' ') && (*p != '\t'))
473 /* Skip over the whitespace in buf */
474 while (*p && ((*p == ' ') || (*p == '\t')))
479 /* Copy the argument into arg */
482 /* Should never happen, but check this anyway */
488 /* Make sure the command field is lower case */
493 *p = ijb_tolower(*p);
497 /* Save the argument for show-proxy-args */
501 switch( hash_string( cmd ) )
504 case hash_trustfile :
505 freez((char *)trustfile);
506 trustfile = strdup(arg);
509 case hash_trust_info_url :
510 enlist(trust_info, arg);
512 #endif /* def TRUST_FILES */
518 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
520 freez((char *)tinygifurl);
525 while((*p >= '0') && (*p <= '9'))
529 while((*p == ' ') || (*p == '\t'))
535 q = malloc(strlen(p) + 5);
539 strcat(q, "\r\n\r\n");
544 if ((tinygif != 1) &&
546 ((tinygif != 3) || (tinygifurl==NULL)) )
548 log_error(LOG_LEVEL_ERROR, "tinygif setting invalid.");
551 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
553 case hash_add_forwarded_header :
557 case hash_single_threaded :
561 case hash_suppress_vanilla_wafer :
562 suppress_vanilla_wafer = 1;
566 enlist(wafer_list, arg);
569 case hash_add_header :
570 enlist(xtra_list, arg);
573 case hash_permissions_file :
574 freez((char *)permissions_file);
575 permissions_file = strdup(arg);
579 freez((char *)logfile);
580 logfile = strdup(arg);
583 case hash_blockfile :
584 freez((char *)blockfile);
585 blockfile = strdup(arg);
588 #ifdef USE_IMAGE_LIST
589 case hash_imagefile :
590 freez((char *)imagefile);
591 imagefile = strdup(arg);
593 #endif /* def USE_IMAGE_LIST */
597 freez((char *)jarfile);
598 jarfile = strdup(arg);
600 #endif /* def JAR_FILES */
602 case hash_listen_address :
603 freez((char *)haddr);
607 case hash_forwardfile :
608 freez((char *)forwardfile);
609 forwardfile = strdup(arg);
614 freez((char *)aclfile);
615 aclfile = strdup(arg);
617 #endif /* def ACL_FILES */
620 case hash_re_filterfile :
621 freez((char *)re_filterfile);
622 re_filterfile = strdup(arg);
624 #endif /* def PCRS */
626 case hash_user_agent :
627 freez((char *)uagent);
628 uagent = strdup(arg);
632 * Offer choice of correct spelling according to dictionary,
633 * or the misspelling used in the HTTP spec.
637 freez((char *)referrer);
638 referrer = strdup(arg);
646 #ifdef FAST_REDIRECTS
647 case hash_fast_redirects :
650 #endif /* def FAST_REDIRECTS */
653 case hash_hide_console :
656 #endif /*def _WIN_CONSOLE*/
658 #ifndef SPLIT_PROXY_ARGS
659 case hash_suppress_blocklists :
662 suppress_message = strdup(arg);
666 /* There will be NO reference in proxy-args. */
667 suppress_message = NULL;
670 suppress_blocklists = 1;
672 #endif /* ndef SPLIT_PROXY_ARGS */
676 g_bToggleIJB = atoi(arg);
678 #endif /* def TOGGLE */
680 #if defined(_WIN32) && ! defined(_WIN_CONSOLE)
681 case hash_activity_animation :
682 g_bShowActivityAnimation = atoi(arg);
685 case hash_log_messages :
686 g_bLogMessages = atoi(arg);
689 case hash_log_highlight_messages :
690 g_bHighlightMessages = atoi(arg);
693 case hash_log_buffer_size :
694 g_bLimitBufferSize = atoi(arg);
697 case hash_log_max_lines :
698 g_nMaxBufferLines = atoi(arg);
701 case hash_log_font_name :
702 strcpy( g_szFontFaceName, arg );
705 case hash_log_font_size :
706 g_nFontSize = atoi(arg);
709 case hash_show_on_task_bar :
710 g_bShowOnTaskBar = atoi(arg);
713 case hash_close_button_minimizes :
714 g_bCloseHidesWindow = atoi(arg);
716 #endif /* defined(_WIN32) && ! defined(_WIN_CONSOLE) */
718 /* Warnings about unsupported features */
721 case hash_trustfile :
722 case hash_trust_info_url :
723 #endif /* ndef TRUST_FILES */
724 #ifndef USE_IMAGE_LIST
725 case hash_imagefile :
726 #endif /* ndef USE_IMAGE_LIST */
728 case hash_re_filterfile :
729 #endif /* ndef PCRS */
732 #endif /* ndef TOGGLE */
733 #if defined(_WIN_CONSOLE) || ! defined(_WIN32)
734 case hash_activity_animation :
735 case hash_log_messages :
736 case hash_log_highlight_messages :
737 case hash_log_buffer_size :
738 case hash_log_max_lines :
739 case hash_log_font_name :
740 case hash_log_font_size :
741 case hash_show_on_task_bar :
742 case hash_close_button_minimizes :
743 #endif /* defined(_WIN_CONSOLE) || ! defined(_WIN32) */
745 case hash_hide_console :
746 #endif /* ndef _WIN_CONSOLE */
747 #if !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST)
749 #endif /* !defined(DETECT_MSIE_IMAGES) && !defined(USE_IMAGE_LIST) */
752 #endif /* ndef JAR_FILES */
755 #endif /* ndef ACL_FILES */
757 #ifdef SPLIT_PROXY_ARGS
758 case hash_suppress_blocklists :
759 #endif /* def SPLIT_PROXY_ARGS */
760 log_error(LOG_LEVEL_INFO, "Unsupported directive \"%s\" ignored.", cmd);
765 * I decided that I liked this better as a warning than an
766 * error. To change back to an error, just change log level
767 * to LOG_LEVEL_FATAL.
769 log_error(LOG_LEVEL_ERROR, "Unrecognized directive (%lulu) in "
770 "configuration file: \"%s\"", hash_string( cmd ), buf);
771 p = malloc( BUFSIZ );
774 sprintf( p, "<br>\nWARNING: unrecognized directive : %s<br><br>\n", buf );
775 proxy_args->invocation = strsav( proxy_args->invocation, p );
784 init_error_log(Argv[0], logfile, debug);
786 if (permissions_file)
788 add_loader(load_permissions_file);
793 add_loader(load_blockfile);
796 #ifdef USE_IMAGE_LIST
799 add_loader(load_imagefile);
801 #endif /* def USE_IMAGE_LIST */
806 add_loader(load_trustfile);
808 #endif /* def TRUST_FILES */
812 add_loader(load_forwardfile);
818 add_loader(load_aclfile);
820 #endif /* def ACL_FILES */
825 add_loader(load_re_filterfile);
827 #endif /* def PCRS */
830 if ( NULL != jarfile )
832 if ( NULL == (jar = fopen(jarfile, "a")) )
834 log_error(LOG_LEVEL_FATAL, "can't open jarfile '%s': %E", jarfile);
835 /* Never get here - LOG_LEVEL_FATAL causes program exit */
839 #endif /* def JAR_FILES */
843 haddr = strdup( HADDR_DEFAULT );
848 if ((p = strchr(haddr, ':')))
860 log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", haddr);
861 /* Never get here - LOG_LEVEL_FATAL causes program exit */
869 if (run_loader(NULL))
871 log_error(LOG_LEVEL_FATAL, "A loader failed while loading config file. Exiting.");
872 /* Never get here - LOG_LEVEL_FATAL causes program exit */
877 * If we're logging cookies in a cookie jar, and the user has not
878 * supplied any wafers, and the user has not told us to suppress the
879 * vanilla wafer, then send the vanilla wafer.
881 if ((jarfile != NULL)
882 && (wafer_list->next == NULL)
883 && (suppress_vanilla_wafer == 0))
885 enlist(wafer_list, VANILLA_WAFER);
887 #endif /* def JAR_FILES */