Improved reporting of errors under Win32.
[privoxy.git] / project.h
1 #ifndef _PROJECT_H
2 #define _PROJECT_H
3 #define PROJECT_H_VERSION "$Id: project.h,v 1.5 2001/05/26 00:28:36 jongfoster Exp $"
4 /*********************************************************************
5  *
6  * File        :  $Source: /cvsroot/ijbswa/current/project.h,v $
7  *
8  * Purpose     :  Defines data structures which are widely used in the
9  *                project.  Does not define any variables or functions
10  *                (though it does declare some macros).
11  *
12  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
13  *                IJBSWA team.  http://ijbswa.sourceforge.net
14  *
15  *                Based on the Internet Junkbuster originally written
16  *                by and Copyright (C) 1997 Anonymous Coders and 
17  *                Junkbusters Corporation.  http://www.junkbusters.com
18  *
19  *                This program is free software; you can redistribute it 
20  *                and/or modify it under the terms of the GNU General
21  *                Public License as published by the Free Software
22  *                Foundation; either version 2 of the License, or (at
23  *                your option) any later version.
24  *
25  *                This program is distributed in the hope that it will
26  *                be useful, but WITHOUT ANY WARRANTY; without even the
27  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
28  *                PARTICULAR PURPOSE.  See the GNU General Public
29  *                License for more details.
30  *
31  *                The GNU General Public License should be included with
32  *                this file.  If not, you can view it at
33  *                http://www.gnu.org/copyleft/gpl.html
34  *                or write to the Free Software Foundation, Inc., 59
35  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
36  *
37  * Revisions   :
38  *    $Log: project.h,v $
39  *    Revision 1.5  2001/05/26 00:28:36  jongfoster
40  *    Automatic reloading of config file.
41  *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
42  *    Most of the global variables have been moved to a new
43  *    struct configuration_spec, accessed through csp->config->globalname
44  *    Most of the globals remaining are used by the Win32 GUI.
45  *
46  *    Revision 1.4  2001/05/22 18:46:04  oes
47  *
48  *    - Enabled filtering banners by size rather than URL
49  *      by adding patterns that replace all standard banner
50  *      sizes with the "Junkbuster" gif to the re_filterfile
51  *
52  *    - Enabled filtering WebBugs by providing a pattern
53  *      which kills all 1x1 images
54  *
55  *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
56  *      which is selected by the (nonstandard and therefore
57  *      capital) letter 'U' in the option string.
58  *      It causes the quantifiers to be ungreedy by default.
59  *      Appending a ? turns back to greedy (!).
60  *
61  *    - Added a new interceptor ijb-send-banner, which
62  *      sends back the "Junkbuster" gif. Without imagelist or
63  *      MSIE detection support, or if tinygif = 1, or the
64  *      URL isn't recognized as an imageurl, a lame HTML
65  *      explanation is sent instead.
66  *
67  *    - Added new feature, which permits blocking remote
68  *      script redirects and firing back a local redirect
69  *      to the browser.
70  *      The feature is conditionally compiled, i.e. it
71  *      can be disabled with --disable-fast-redirects,
72  *      plus it must be activated by a "fast-redirects"
73  *      line in the config file, has its own log level
74  *      and of course wants to be displayed by show-proxy-args
75  *      Note: Boy, all the #ifdefs in 1001 locations and
76  *      all the fumbling with configure.in and acconfig.h
77  *      were *way* more work than the feature itself :-(
78  *
79  *    - Because a generic redirect template was needed for
80  *      this, tinygif = 3 now uses the same.
81  *
82  *    - Moved GIFs, and other static HTTP response templates
83  *      to project.h
84  *
85  *    - Some minor fixes
86  *
87  *    - Removed some >400 CRs again (Jon, you really worked
88  *      a lot! ;-)
89  *
90  *    Revision 1.3  2001/05/20 01:21:20  jongfoster
91  *    Version 2.9.4 checkin.
92  *    - Merged popupfile and cookiefile, and added control over PCRS
93  *      filtering, in new "permissionsfile".
94  *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
95  *      file error you now get a message box (in the Win32 GUI) rather
96  *      than the program exiting with no explanation.
97  *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
98  *      skipping.
99  *    - Removed tabs from "config"
100  *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
101  *    - Bumped up version number.
102  *
103  *    Revision 1.2  2001/05/17 23:01:01  oes
104  *     - Cleaned CRLF's from the sources and related files
105  *
106  *    Revision 1.1.1.1  2001/05/15 13:59:03  oes
107  *    Initial import of version 2.9.3 source tree
108  *
109  *
110  *********************************************************************/
111 \f
112
113 /* Declare struct FILE for vars and funcs. */
114 #include <stdio.h>
115
116 /* Need time_t for file_list */
117 #include <time.h>
118
119 /*
120  * Include appropriate regular expression libraries.
121  *
122  * PCRS           ==> Include pcre
123  * REGEX && PCRE  ==> Include pcre and pcreposix
124  * REGEX && !PCRE ==> Include gnu_regex
125  *
126  * STATIC  ==> Use  #include "pcre.h"  (compiling at same time)
127  * !STATIC ==> Use  #include <pcre.h>  (System library)
128  *
129  */
130 #if (defined(REGEX) && defined(PCRE)) || defined(PCRS)
131 #  ifdef STATIC
132 #    include "pcre.h"
133 #  else
134 #    include <pcre.h>
135 #  endif
136 #endif /* (defined(REGEX) && defined(PCRE)) || defined(PCRS) */
137
138 #if defined(REGEX) && defined(PCRE)
139 #  ifdef STATIC
140 #    include "pcreposix.h"
141 #  else
142 #    include <pcreposix.h>
143 #  endif
144 #endif /* defined(REGEX) && defined(PCRE) */
145
146 #if defined(REGEX) && !defined(PCRE)
147 #  include "gnu_regex.h"
148 #endif
149
150 #ifdef PCRS
151 #include "pcrs.h"
152 #endif /* def PCRS */
153
154 #ifdef AMIGA 
155 #include "amiga.h" 
156 #endif /* def AMIGA */
157
158 #ifdef __cplusplus
159 extern "C" {
160 #endif
161
162 #define FOREVER 1
163
164 /* Default IP and port to listen on */
165 #define HADDR_DEFAULT   "127.0.0.1"
166 #define HADDR_PORT      8000
167
168
169 /* Need this for struct gateway */
170 struct client_state;
171
172 /* Need this for struct client_state */
173 struct configuration_spec;
174
175
176 struct http_request
177 {
178    char *cmd;
179    char *gpc;
180    char *host;
181    int   port;
182    char *path;
183    char *ver;
184    char *hostport; /* "host[:port]" */
185    int   ssl;
186 };
187
188 struct gateway
189 {
190    /* generic attributes */
191    char *name;
192    int (*conn)(const struct gateway *, struct http_request *, struct client_state *);
193    int   type;
194
195    /* domain specific attributes */
196    char *gateway_host;
197    int   gateway_port;
198
199    char *forward_host;
200    int   forward_port;
201 };
202
203
204 struct proxy_args
205 {
206    char *header;
207    char *invocation;
208    char *gateways;
209    char *trailer;
210 };
211
212
213 struct iob
214 {
215    char *buf;
216    char *cur;
217    char *eod;
218 };
219
220
221 struct list
222 {
223    char *str;
224    struct list *last;
225    struct list *next;
226 };
227
228 #define IOB_PEEK(CSP) ((CSP->iob->cur > CSP->iob->eod) ? (CSP->iob->eod - CSP->iob->cur) : 0)
229 #define IOB_RESET(CSP) if(CSP->iob->buf) free(CSP->iob->buf); memset(CSP->iob, '\0', sizeof(CSP->iob));
230
231
232 /* Constants defining bitmask for csp->accept_types */
233
234 #ifdef DETECT_MSIE_IMAGES
235
236 /* MSIE detected by user-agent string */
237 #define ACCEPT_TYPE_IS_MSIE     0x0001
238
239 /*
240  * *If* this is MSIE, it wants an image.  (Or this is a shift-reload, or
241  * it's got an image from this URL before...  yuck!)
242  * Only meaningful if ACCEPT_TYPE_IS_MSIE set 
243  */
244 #define ACCEPT_TYPE_MSIE_IMAGE  0x0002
245
246 /*
247  * *If* this is MSIE, it wants a HTML document.
248  * Only meaningful if ACCEPT_TYPE_IS_MSIE set
249  */
250 #define ACCEPT_TYPE_MSIE_HTML   0x0004
251
252 #endif /* def DETECT_MSIE_IMAGES */
253
254
255 struct client_state
256 {
257    struct configuration_spec * config;
258
259    int  permissions;
260    
261    int  cfd;
262    int  sfd;
263
264 #ifdef STATISTICS
265    /* 1 if this URL was rejected, 0 otherwise. Allows actual stats inc to 
266     * occur in main thread only for thread-safety. 
267     */
268    int  rejected;
269 #endif /* def STATISTICS */
270
271 #ifdef FORCE_LOAD
272    int force;
273 #endif /* def FORCE_LOAD */
274
275 #ifdef TOGGLE
276    int   toggled_on;
277 #endif /* def TOGGLE */
278
279    char *ip_addr_str;
280    long  ip_addr_long;
281    char *referrer;
282
283 #if defined(DETECT_MSIE_IMAGES)
284    /* Types the client will accept.
285     * Bitmask - see ACCEPT_TYPE_XXX constants.
286     */
287    int accept_types;
288 #endif /* defined(DETECT_MSIE_IMAGES) */
289
290    const struct gateway *gw;
291    struct http_request http[1];
292
293    struct iob iob[1];
294
295    struct list headers[1];
296    struct list cookie_list[1];
297 #if defined(PCRS) || defined(KILLPOPUPS)
298    int is_text;
299 #endif /* defined(PCRS) || defined(KILLPOPUPS) */
300
301    char   *x_forwarded;
302
303    int active;
304
305    /* files associated with this client */
306    struct file_list *blist;   /* blockfile */
307    struct file_list *flist;   /* forwardfile */
308    struct file_list *permissions_list;
309
310
311 #ifdef ACL_FILES
312    struct file_list *alist;   /* aclfile */
313 #endif /* def ACL_FILES */
314
315 #ifdef USE_IMAGE_LIST
316    struct file_list *ilist;   /* imagefile */
317 #endif /* def USE_IMAGE_LIST */
318
319 #ifdef PCRS
320      struct file_list *rlist;   /* Perl re_filterfile */
321      size_t content_length;     /* Length after processing */ 
322 #endif /* def PCRS */
323
324 #ifdef TRUST_FILES
325    struct file_list *tlist;   /* trustfile */
326 #endif /* def TRUST_FILES */
327
328    struct client_state *next;
329 };
330
331
332 struct parsers
333 {
334    char *str;
335    char  len;
336    char *(*parser)(const struct parsers *, char *, struct client_state *);
337 };
338
339
340 struct interceptors
341 {
342    char *str;
343    char  len;
344    char *(*interceptor)(struct http_request *http, struct client_state *csp);
345 };
346
347
348 /* this allows the proxy to permit/block access to any host and/or path */
349
350 struct url_spec
351 {
352    char  *spec;
353    char  *domain;
354    char  *dbuf;
355    char **dvec;
356    int    dcnt;
357    int    toplevel;
358
359    char *path;
360    int   pathlen;
361    int   port;
362 #ifdef REGEX
363    regex_t *preg;
364 #endif
365 };
366
367
368 struct file_list
369 {
370    /*
371     * this is a pointer to the data structures associated with the file.
372     * Read-only once the structure has been created.
373     */
374    void *f;
375    
376    /* Normally NULL.  When we are finished with file (i.e. when we have
377     * loaded a new one), set to a pointer to an unloader function.
378     * Unloader will be called by sweep() (called from main loop) when
379     * all clients using this file are done.  This prevents threading 
380     * problems.
381     */
382    void (*unloader)(void *);
383
384    /* Used internally by sweep().  Do not access from elsewhere. */
385    int active;
386
387 #ifndef SPLIT_PROXY_ARGS
388    /* String to be displayed as part of show-proxy-args display.
389     * Read-only once the structure has been created.
390     */
391    char *proxy_args;
392 #endif /* ndef SPLIT_PROXY_ARGS */
393
394    /* Following variables allow us to check if file has been changed.
395     * Read-only once the structure has been created.
396     */
397    time_t lastmodified;
398    char * filename;
399
400    /* Pointer to next entry in the linked list of all "file_list"s.
401     * This linked list is so that sweep() can navigate it.
402     * Since sweep() can remove items from the list, we must be careful
403     * to only access this value from main thread (when we know sweep
404     * won't be running).
405     */
406    struct file_list *next;
407 };
408
409
410 struct block_spec
411 {
412    struct url_spec url[1];
413    int    reject;
414    struct block_spec *next;
415 };
416
417
418 #define PERMIT_COOKIE_SET    0x0001
419 #define PERMIT_COOKIE_READ   0x0002
420 #define PERMIT_RE_FILTER     0x0004
421 #define PERMIT_POPUPS        0x0008
422
423 struct permissions_spec
424 {
425    struct url_spec           url[1];
426    int                       permissions;
427    struct permissions_spec * next;
428 };
429
430 struct forward_spec
431 {
432    struct url_spec url[1];
433    int   reject;
434    struct gateway gw[1];
435    struct forward_spec *next;
436 };
437
438
439 #ifdef PCRS
440 struct re_filterfile_spec
441 {
442    struct list patterns[1];
443    /* See README.re_filter */
444    pcrs_job *joblist;
445 };
446 #endif /* def PCRS */
447
448
449 #ifdef ACL_FILES
450 #define ACL_PERMIT   1  /* accept connection request */
451 #define ACL_DENY     2  /* reject connection request */
452
453 struct access_control_addr
454 {
455    unsigned long addr;
456    unsigned long mask;
457    unsigned long port;
458 };
459
460 struct access_control_list
461 {
462    struct access_control_addr src[1];
463    struct access_control_addr dst[1];
464
465    short action;
466    struct access_control_list *next;
467 };
468 #endif /* def ACL_FILES */
469
470 /* Maximum number of loaders (permissions, block, forward, acl...) */
471 #define NLOADERS 8
472
473 /*
474  * Data loaded from the configuration file.
475  *
476  * (Anomaly: toggle is still handled through a global, not this structure)
477  */
478 struct configuration_spec
479 {
480    int debug;
481    int multi_threaded;
482
483 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
484    int tinygif;
485    const char *tinygifurl;
486 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
487
488    const char *logfile;
489
490    const char *blockfile;
491    const char *permissions_file;
492    const char *forwardfile;
493
494 #ifdef ACL_FILES
495    const char *aclfile;
496 #endif /* def ACL_FILES */
497
498 #ifdef USE_IMAGE_LIST
499    const char *imagefile;
500 #endif /* def USE_IMAGE_LIST */
501
502 #ifdef PCRS
503    const char *re_filterfile;
504 #endif /* def PCRS */
505
506    /*
507     * Permissions to use for URLs not in the permissions list.
508     */
509    int default_permissions;
510
511 #ifdef JAR_FILES
512    const char * jarfile;
513    FILE * jar;
514 #endif /* def JAR_FILES */
515
516    const char *referrer;
517    const char *uagent;
518    const char *from;
519
520    int add_forwarded;
521
522    struct list wafer_list[1];
523    struct list xtra_list[1];
524
525    /*
526     * Port and IP to bind to.
527     * Defaults to HADDR_DEFAULT:HADDR_PORT == 127.0.0.1:8000
528     */
529    const char *haddr;
530    int         hport;
531
532 #ifndef SPLIT_PROXY_ARGS
533    const char *suppress_message;
534 #endif /* ndef SPLIT_PROXY_ARGS */
535
536 #ifndef SPLIT_PROXY_ARGS
537    /* suppress listing sblock and simage */
538    int suppress_blocklists;
539 #endif /* ndef SPLIT_PROXY_ARGS */
540
541 #ifdef FAST_REDIRECTS
542    int fast_redirects;
543 #endif /* def FAST_REDIRECTS */
544
545 #ifdef TRUST_FILES
546    const char * trustfile;
547
548    struct list trust_info[1];
549    struct url_spec *trust_list[64];
550 #endif /* def TRUST_FILES */
551
552    struct proxy_args proxy_args[1];
553
554    struct file_list *config_file_list;
555
556    int (*loaders[NLOADERS])(struct client_state *);
557
558    int need_bind; /* bool, nonzero if we need to bind() to the new port */
559 };
560
561
562 #define SZ(X)  (sizeof(X) / sizeof(*X))
563
564 #define WHITEBG   "<body bgcolor=\"#ffffff\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
565 #define BODY      "<body bgcolor=\"#f8f8f0\" link=\"#000078\" alink=\"#ff0022\" vlink=\"#787878\">\n"
566 #define BANNER    "<strong>Internet J<small>UNK<i><font color=\"red\">BUSTER</font></i></small></strong>"
567
568 #ifdef FORCE_LOAD
569 #define FORCE_PREFIX "/IJB-FORCE-LOAD"
570 #endif /* def FORCE_LOAD */
571
572 #define HOME_PAGE_URL  "http://ijbswa.sourceforge.net/"
573 #define REDIRECT_URL HOME_PAGE_URL "redirect.php?v=" VERSION "&to="
574
575 static const char CFAIL[] =
576    "HTTP/1.0 503 Connect failed\n"
577    "Content-Type: text/html\n\n"
578    "<html>\n"
579    "<head>\n"
580    "<title>Internet Junkbuster: Connect failed</title>\n"
581    "</head>\n"
582    BODY
583    "<h1><center>"
584    BANNER
585    "</center></h1>"
586    "TCP connection to '%s' failed: %s.\n<br>"
587    "</body>\n"
588    "</html>\n";
589
590 static const char CNXDOM[] =
591    "HTTP/1.0 404 Non-existent domain\n"
592    "Content-Type: text/html\n\n"
593    "<html>\n"
594    "<head>\n"
595    "<title>Internet Junkbuster: Non-existent domain</title>\n"
596    "</head>\n"
597    BODY
598    "<h1><center>"
599    BANNER
600    "</center></h1>"
601    "No such domain: %s\n"
602    "</body>\n"
603    "</html>\n";
604
605 static const char CNOBANNER[] =
606    "HTTP/1.0 200 No Banner\n"
607    "Content-Type: text/html\n\n"
608    "<html>\n"
609    "<head>\n"
610    "<title>Internet Junkbuster: No Banner</title>\n"
611    "</head>\n"
612    BODY
613    "<h1><center>"
614    BANNER
615    "</h1>"
616    "You asked for a banner that this proxy can't produce because either configuration does not permit.\n<br>"
617    "or the URL didn't end with .gif\n"
618    "</center></body>\n"
619    "</html>\n";
620
621 static const char CSUCCEED[] =
622    "HTTP/1.0 200 Connection established\n"
623    "Proxy-Agent: IJ/" VERSION "\n\n";
624
625 static const char CHEADER[] =
626    "HTTP/1.0 400 Invalid header received from browser\n\n";
627
628 static const char SHEADER[] =
629    "HTTP/1.0 502 Invalid header received from server\n\n";
630
631 #if defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
632
633 /*
634  * Hint: You can encode your own GIFs like that:
635  * perl -e 'while (read STDIN, $c, 1) { printf("\\%.3o,", unpack("C", $c)); }'
636  */
637
638 static const char BLANKGIF[] =
639    "HTTP/1.0 200 OK\r\n"
640    "Pragma: no-cache\r\n"
641    "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
642    "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
643    "Content-type: image/gif\r\n\r\n"
644    "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
645    "\000!\371\004\001\000\000\000\000,\000\000\000\000\001"
646    "\000\001\000\000\002\002D\001\000;";
647
648 static const char JBGIF[] =
649    "HTTP/1.0 200 OK\r\n"
650    "Pragma: no-cache\r\n"
651    "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
652    "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
653    "Content-type: image/gif\r\n\r\n"
654    "GIF89aD\000\013\000\360\000\000\000\000\000\377\377\377!"
655    "\371\004\001\000\000\001\000,\000\000\000\000D\000\013\000"
656    "\000\002a\214\217\251\313\355\277\000\200G&K\025\316hC\037"
657    "\200\234\230Y\2309\235S\230\266\206\372J\253<\3131\253\271"
658    "\270\215\342\254\013\203\371\202\264\334P\207\332\020o\266"
659    "N\215I\332=\211\312\3513\266:\026AK)\364\370\365aobr\305"
660    "\372\003S\275\274k2\354\254z\347?\335\274x\306^9\374\276"
661    "\037Q\000\000;";
662
663 #endif /* defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
664
665 #if defined(FAST_REDIRECTS) || defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST)
666
667 static const char HTTP_REDIRECT_TEMPLATE[] =
668       "HTTP/1.0 302 Local Redirect from Junkbuster\r\n" 
669       "Pragma: no-cache\r\n"
670       "Last-Modified: Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
671       "Expires:       Thu Jul 31, 1997 07:42:22 pm GMT\r\n"
672       "Location: %s\r\n";
673
674 #endif /*  defined(DETECT_MSIE_IMAGES) || defined(USE_IMAGE_LIST) */
675
676 #ifdef __cplusplus
677 } /* extern "C" */
678 #endif
679
680 #endif /* ndef _PROJECT_H */
681
682 /*
683   Local Variables:
684   tab-width: 3
685   end:
686 */