Update all patches to CVS version as of 2007-10-14.
[privoxy.git] / jcc.c
1 const char jcc_rcs[] = "$Id: jcc.c,v 1.152 2007/10/04 18:03:34 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
5  *
6  * Purpose     :  Main file.  Contains main() method, main loop, and
7  *                the main connection-handling function.
8  *
9  * Copyright   :  Written by and Copyright (C) 2001-2007 the SourceForge
10  *                Privoxy team. http://www.privoxy.org/
11  *
12  *                Based on the Internet Junkbuster originally written
13  *                by and Copyright (C) 1997 Anonymous Coders and
14  *                Junkbusters Corporation.  http://www.junkbusters.com
15  *
16  *                This program is free software; you can redistribute it
17  *                and/or modify it under the terms of the GNU General
18  *                Public License as published by the Free Software
19  *                Foundation; either version 2 of the License, or (at
20  *                your option) any later version.
21  *
22  *                This program is distributed in the hope that it will
23  *                be useful, but WITHOUT ANY WARRANTY; without even the
24  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
25  *                PARTICULAR PURPOSE.  See the GNU General Public
26  *                License for more details.
27  *
28  *                The GNU General Public License should be included with
29  *                this file.  If not, you can view it at
30  *                http://www.gnu.org/copyleft/gpl.html
31  *                or write to the Free Software Foundation, Inc., 59
32  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  *
34  * Revisions   :
35  *    $Log: jcc.c,v $
36  *    Revision 1.152  2007/10/04 18:03:34  fabiankeil
37  *    - Fix a crash when parsing invalid requests whose first header
38  *      is rejected by get_header(). Regression (re?)introduced
39  *      in r1.143 by yours truly.
40  *    - Move ACTION_VANILLA_WAFER handling into parsers.c's
41  *      client_cookie_adder() to make sure send-vanilla-wafer can be
42  *      controlled through tags (and thus regression-tested).
43  *
44  *    Revision 1.151  2007/09/29 10:21:16  fabiankeil
45  *    - Move get_filter_function() from jcc.c to filters.c
46  *      so the filter functions can be static.
47  *    - Don't bother filtering body-less responses.
48  *
49  *    Revision 1.150  2007/09/28 16:39:29  fabiankeil
50  *    Execute content filters through execute_content_filter().
51  *
52  *    Revision 1.149  2007/09/04 15:08:48  fabiankeil
53  *    Initialize req to NULL to make sure it's defined if the
54  *    first read_socket() call fails. Reported by icmp30.
55  *
56  *    Revision 1.148  2007/08/26 16:47:13  fabiankeil
57  *    Add Stephen Gildea's --pre-chroot-nslookup patch [#1276666],
58  *    extensive comments moved to user manual.
59  *
60  *    Revision 1.147  2007/08/25 14:42:40  fabiankeil
61  *    Don't crash if a broken header filter wiped out the request line.
62  *
63  *    Revision 1.146  2007/08/20 17:09:32  fabiankeil
64  *    Fix byte_count calculation in case of flushes
65  *    and don't parse the server headers a second time.
66  *
67  *    Revision 1.145  2007/08/19 13:13:31  fabiankeil
68  *    - If there's a connection problem after we already forwarded
69  *      parts of the original content, just hang up. Fixes BR#1776724.
70  *    - Fix warnings about unused code on mingw32.
71  *    - In case of flushes, calculate the byte count
72  *      less incorrectly (I think).
73  *
74  *    Revision 1.144  2007/08/11 14:43:22  fabiankeil
75  *    Add some more prototypes for static functions.
76  *
77  *    Revision 1.143  2007/08/05 13:58:19  fabiankeil
78  *    Comment out request_contains_null_bytes() until it's used again.
79  *
80  *    Revision 1.142  2007/08/05 13:50:26  fabiankeil
81  *    #1763173 from Stefan Huehner: s@const static@static const@
82  *    and declare some more functions static.
83  *
84  *    Revision 1.141  2007/08/04 09:56:23  fabiankeil
85  *    - Log rejected CONNECT requests with LOG_LEVEL_INFO
86  *      and explain why they were rejected in the first place.
87  *    - Fix the LOG_LEVEL_CLF message for crunches of unallowed
88  *      CONNECT requests. The request line was missing.
89  *    - Add two more XXX reminders as we don't have enough already.
90  *
91  *    Revision 1.140  2007/07/21 11:51:36  fabiankeil
92  *    As Hal noticed, checking dispatch_cgi() as the last cruncher
93  *    looks like a bug if CGI requests are blocked unintentionally,
94  *    so don't do it unless the user enabled the new config option
95  *    "allow-cgi-request-crunching".
96  *
97  *    Revision 1.139  2007/07/14 07:46:41  fabiankeil
98  *    - Allow to rewrite the request destination behind the client's back.
99  *    - Turn the weird-looking unconditional for loop that
100  *      reads the client request into a conditional while loop.
101  *      Move the stuff that only runs once out of the loop.
102  *    - Move parts of chat(), server_content_type() and the
103  *      necessary stuff to fix BR#1750917 into get_filter_function().
104  *
105  *    Revision 1.138  2007/06/03 18:45:18  fabiankeil
106  *    Temporary workaround for BR#1730105.
107  *
108  *    Revision 1.137  2007/06/01 18:16:36  fabiankeil
109  *    Use the same mutex for gethostbyname() and gethostbyaddr() to prevent
110  *    deadlocks and crashes on OpenBSD and possibly other OS with neither
111  *    gethostbyname_r() nor gethostaddr_r(). Closes BR#1729174.
112  *    Thanks to Ralf Horstmann for report and solution.
113  *
114  *    Revision 1.136  2007/06/01 16:41:11  fabiankeil
115  *    Add forward-override{} to change the forwarding settings through
116  *    action sections. This is mainly interesting to forward different
117  *    clients differently (for example based on User-Agent or request
118  *    origin).
119  *
120  *    Revision 1.135  2007/05/24 17:03:50  fabiankeil
121  *    - Let usage() mention the --chroot parameter.
122  *    - Use read_socket() consistently and always leave
123  *      the last buffer byte alone, even in cases where
124  *      null termination (currently) doesn't matter.
125  *
126  *    Revision 1.134  2007/05/16 14:59:46  fabiankeil
127  *    - Fix config file loading on Unix if no config file is specified.
128  *      Since r1.97 Privoxy would always interpret the last argument as
129  *      config file, even if it's a valid command line option.
130  *    - Abort in case of unrecognized command line options. Closes #1719696.
131  *    - Remove a bunch of unnecessary strcpy() calls (yay for c&p without thinking).
132  *    - Replace the remaining strcpy() and strcat() calls with strlcpy() and strcat().
133  *
134  *    Revision 1.133  2007/05/04 11:23:19  fabiankeil
135  *    - Don't rerun crunchers that only depend on the request URL.
136  *    - Don't count redirects and CGI requests as "blocked requests".
137  *
138  *    Revision 1.132  2007/04/25 15:15:17  fabiankeil
139  *    Support crunching based on tags created by server-header taggers.
140  *
141  *    Revision 1.131  2007/04/22 13:24:50  fabiankeil
142  *    Make HTTP snippets static (again). Add a Content-Type for those
143  *    with content so the browser doesn't guess it based on the URL.
144  *
145  *    Revision 1.130  2007/04/19 13:47:34  fabiankeil
146  *    Move crunching and request line rebuilding out of chat().
147  *
148  *    Revision 1.129  2007/04/15 16:39:20  fabiankeil
149  *    Introduce tags as alternative way to specify which
150  *    actions apply to a request. At the moment tags can be
151  *    created based on client and server headers.
152  *
153  *    Revision 1.128  2007/03/25 16:55:54  fabiankeil
154  *    Don't CLF-log CONNECT requests twice.
155  *
156  *    Revision 1.127  2007/03/20 13:53:17  fabiankeil
157  *    Log the source address for ACL-related connection drops.
158  *
159  *    Revision 1.126  2007/03/17 15:20:05  fabiankeil
160  *    New config option: enforce-blocks.
161  *
162  *    Revision 1.125  2007/03/09 14:12:00  fabiankeil
163  *    - Move null byte check into separate function.
164  *    - Don't confuse the client with error pages
165  *      if a CONNECT request was already confirmed.
166  *
167  *    Revision 1.124  2007/02/23 14:59:54  fabiankeil
168  *    Speed up NULL byte escaping and only log the complete
169  *    NULL byte requests with header debugging enabled.
170  *
171  *    Revision 1.123  2007/02/21 18:42:10  fabiankeil
172  *    Answer requests that contain NULL bytes with
173  *    a custom response instead of waiting for more
174  *    data until the client eventually hangs up.
175  *
176  *    Revision 1.122  2007/02/07 11:12:02  fabiankeil
177  *    - Move delivery and logging of crunched responses
178  *      from chat() into send_crunch_response().
179  *    - Display the reason for generating http_responses.
180  *    - Log the content length for LOG_LEVEL_CLF correctly
181  *      (still incorrect for some fixed responses).
182  *    - Reword an incorrect comment about
183  *      treat-forbidden-connects-like-blocks violating
184  *      the specs.
185  *    - Add some log messages.
186  *
187  *    Revision 1.121  2007/01/27 10:52:56  fabiankeil
188  *    Move mutex initialization into separate
189  *    function and exit in case of errors.
190  *
191  *    Revision 1.120  2007/01/26 14:18:42  fabiankeil
192  *    - Start to reduce chat()'s line count and move
193  *      parts of it into separate functions.
194  *    - Add "HTTP/1.1 100 Continue" hack for BR 756734.
195  *
196  *    Revision 1.119  2007/01/25 14:02:30  fabiankeil
197  *    - Add Proxy-Agent header to HTTP snippets that are
198  *      supposed to reach HTTP clients only.
199  *    - Made a few CONNECT log messages more descriptive.
200  *    - Catch completely empty server responses (as seen
201  *      with Tor's fake ".noconnect" top level domain).
202  *    - Use shiny new "forwarding-failed" template for socks errors.
203  *
204  *    Revision 1.118  2007/01/07 07:43:43  joergs
205  *    AmigaOS4 support added.
206  *
207  *    Revision 1.117  2006/12/31 17:56:37  fabiankeil
208  *    Added config option accept-intercepted-requests
209  *    and disabled it by default.
210  *
211  *    Revision 1.116  2006/12/29 19:08:22  fabiankeil
212  *    Reverted parts of my last commit
213  *    to keep error handling working.
214  *
215  *    Revision 1.115  2006/12/29 17:38:57  fabiankeil
216  *    Fixed gcc43 conversion warnings.
217  *
218  *    Revision 1.114  2006/12/27 18:52:02  fabiankeil
219  *    Fix -pedantic ISO C warning about converting
220  *    from function pointer to object pointer.
221  *
222  *    Revision 1.113  2006/12/26 17:38:50  fabiankeil
223  *    Silence compiler warning I introduced with my last commit.
224  *
225  *    Revision 1.112  2006/12/26 17:31:41  fabiankeil
226  *    Mutex protect rand() if POSIX threading
227  *    is used, warn the user if that's not possible
228  *    and stop using it on _WIN32 where it could
229  *    cause crashes.
230  *
231  *    Revision 1.111  2006/12/23 16:15:06  fabiankeil
232  *    Don't prevent core dumps by catching SIGABRT.
233  *    It's rude and makes debugging unreasonable painful.
234  *
235  *    Revision 1.110  2006/12/13 14:52:53  etresoft
236  *    Fix build failure on MacOS X. Global symbols can be either static or extern, but not both.
237  *
238  *    Revision 1.109  2006/12/06 19:41:40  fabiankeil
239  *    Privoxy is now able to run as intercepting
240  *    proxy in combination with any packet filter
241  *    that does the port redirection. The destination
242  *    is extracted from the "Host:" header which
243  *    should be available for nearly all requests.
244  *
245  *    Moved HTTP snipplets into jcc.c.
246  *    Added error message for gopher proxy requests.
247  *
248  *    Revision 1.108  2006/11/28 15:38:51  fabiankeil
249  *    Only unlink the pidfile if it's actually used.
250  *
251  *    Change order of interception checks to make
252  *    it possible to block or redirect requests for
253  *    the cgi pages.
254  *
255  *    Revision 1.107  2006/11/13 19:05:51  fabiankeil
256  *    Make pthread mutex locking more generic. Instead of
257  *    checking for OSX and OpenBSD, check for FEATURE_PTHREAD
258  *    and use mutex locking unless there is an _r function
259  *    available. Better safe than sorry.
260  *
261  *    Fixes "./configure --disable-pthread" and should result
262  *    in less threading-related problems on pthread-using platforms,
263  *    but it still doesn't fix BR#1122404.
264  *
265  *    Revision 1.106  2006/11/06 19:58:23  fabiankeil
266  *    Move pthread.h inclusion from jcc.c to jcc.h.
267  *    Fixes build on x86-freebsd1 (FreeBSD 5.4-RELEASE).
268  *
269  *    Revision 1.105  2006/11/06 14:26:02  fabiankeil
270  *    Don't exit after receiving the second SIGHUP on Solaris.
271  *
272  *    Fixes BR 1052235, but the same problem may exist on other
273  *    systems. Once 3.0.6 is out we should use sigset()
274  *    where available and see if it breaks anything.
275  *
276  *    Revision 1.104  2006/09/23 13:26:38  roro
277  *    Replace TABs by spaces in source code.
278  *
279  *    Revision 1.103  2006/09/21 12:54:43  fabiankeil
280  *    Fix +redirect{}. Didn't work with -fast-redirects.
281  *
282  *    Revision 1.102  2006/09/06 13:03:04  fabiankeil
283  *    Respond with 400 and a short text message
284  *    if the client tries to use Privoxy as FTP proxy.
285  *
286  *    Revision 1.101  2006/09/06 09:23:37  fabiankeil
287  *    Make number of retries in case of forwarded-connect problems
288  *    a config file option (forwarded-connect-retries) and use 0 as
289  *    default.
290  *
291  *    Revision 1.100  2006/09/03 19:42:59  fabiankeil
292  *    Set random(3) seed.
293  *
294  *    Revision 1.99  2006/09/02 15:36:42  fabiankeil
295  *    Follow the OpenBSD port's lead and protect the resolve
296  *    functions on OpenBSD as well.
297  *
298  *    Revision 1.98  2006/08/24 11:01:34  fabiankeil
299  *    --user fix. Only use the user as group if no group is specified.
300  *    Solves BR 1492612. Thanks to Spinor S. and David Laight.
301  *
302  *    Revision 1.97  2006/08/18 15:23:17  david__schmidt
303  *    Windows service (re-)integration
304  *
305  *    The new args are:
306  *
307  *    --install[:service_name]
308  *    --uninstall[:service_name]
309  *    --service
310  *
311  *    They work as follows:
312  *    --install will create a service for you and then terminate.
313  *    By default the service name will be "privoxy" (without the quotes).
314  *    However you can run multiple services if you wish, just by adding
315  *    a colon and then a name (no spaces).
316  *
317  *    --uninstall follows the exact same rules a --install.
318  *
319  *    --service is used when the program is executed by the service
320  *    control manager, and in normal circumstances would never be
321  *    used as a command line argument.
322  *
323  *    Revision 1.96  2006/08/15 20:12:36  david__schmidt
324  *    Windows service integration
325  *
326  *    Revision 1.95  2006/08/03 02:46:41  david__schmidt
327  *    Incorporate Fabian Keil's patch work:
328 http://www.fabiankeil.de/sourcecode/privoxy/
329  *
330  *    Revision 1.94  2006/07/18 14:48:46  david__schmidt
331  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
332  *    with what was really the latest development (the v_3_0_branch branch)
333  *
334  *    Revision 1.92.2.16  2005/04/03 20:10:50  david__schmidt
335  *    Thanks to Jindrich Makovicka for a race condition fix for the log
336  *    file.  The race condition remains for non-pthread implementations.
337  *    Reference patch #1175720.
338  *
339  *    Revision 1.92.2.15  2004/10/03 12:53:32  david__schmidt
340  *    Add the ability to check jpeg images for invalid
341  *    lengths of comment blocks.  Defensive strategy
342  *    against the exploit:
343  *       Microsoft Security Bulletin MS04-028
344  *       Buffer Overrun in JPEG Processing (GDI+) Could
345  *       Allow Code Execution (833987)
346  *    Enabled with +inspect-jpegs in actions files.
347  *
348  *    Revision 1.92.2.14  2003/12/12 12:52:53  oes
349  *    - Fixed usage info for non-unix platforms
350  *    - Fixed small cmdline parsing bug
351  *
352  *    Revision 1.92.2.13  2003/11/27 19:20:27  oes
353  *    Diagnostics: Now preserve the returncode of pthread_create
354  *    in errno. Closes BR #775721. Thanks to Geoffrey Hausheer.
355  *
356  *    Revision 1.92.2.12  2003/07/11 11:34:19  oes
357  *    No longer ignore SIGCHLD. Fixes bug #769381
358  *
359  *    Revision 1.92.2.11  2003/05/14 12:32:02  oes
360  *    Close jarfile on graceful exit, remove stray line
361  *
362  *    Revision 1.92.2.10  2003/05/08 15:13:46  oes
363  *    Cosmetics: Killed a warning, a typo and an allocation left at exit
364  *
365  *    Revision 1.92.2.9  2003/04/03 15:08:42  oes
366  *    No longer rely on non-POSIX.1 extensions of getcwd().
367  *    Fixes bug #711001
368  *
369  *    Revision 1.92.2.8  2003/03/31 13:12:32  oes
370  *    Replaced setenv() by posix-compliant putenv()
371  *    Thanks to Neil McCalden (nmcc AT users.sf.net).
372  *
373  *    Revision 1.92.2.7  2003/03/17 16:48:59  oes
374  *    Added chroot ability, thanks to patch by Sviatoslav Sviridov
375  *
376  *    Revision 1.92.2.6  2003/03/11 11:55:00  oes
377  *    Clean-up and extension of improvements for forked mode:
378  *     - Child's return code now consists of flags RC_FLAG_*
379  *     - Reporting toggle to parent now properly #ifdef'ed
380  *     - Children now report blocking to parent. This enables
381  *       statistics in forked mode
382  *
383  *    Revision 1.92.2.5  2003/03/10 23:45:32  oes
384  *    Fixed bug #700381: Non-Threaded version now capable of being toggled.
385  *    Children now report having been toggled through _exit(17), parents
386  *    watch for that code and toggle themselves if found.
387  *
388  *    Revision 1.92.2.4  2003/03/07 03:41:04  david__schmidt
389  *    Wrapping all *_r functions (the non-_r versions of them) with 
390  *    mutex semaphores for OSX.  Hopefully this will take care of all 
391  *    of those pesky crash reports.
392  *
393  *    Revision 1.92.2.3  2003/02/28 12:53:06  oes
394  *    Fixed two mostly harmless mem leaks
395  *
396  *    Revision 1.92.2.2  2002/11/20 14:37:47  oes
397  *    Fix: Head of global clients list now initialized to NULL
398  *
399  *    Revision 1.92.2.1  2002/09/25 14:52:24  oes
400  *    Added basic support for OPTIONS and TRACE HTTP methods:
401  *     - New interceptor direct_response() added in chat().
402  *     - sed() moved to earlier in the process, so that the
403  *       Host: header is evaluated before actions and forwarding
404  *       are decided on.
405  *
406  *    Revision 1.92  2002/05/08 16:00:46  oes
407  *    Chat's buffer handling:
408  *     - Fixed bug with unchecked out-of-mem conditions
409  *       while reading client request & server headers
410  *     - No longer predict if the buffer limit will be exceeded
411  *       in the next read -- check add_to_iob's new
412  *       return code. If buffer couldn't be extended
413  *       (policy or out-of-mem) while
414  *       - reading from client: abort
415  *       - reading server headers: send error page
416  *       - buffering server body for filter: flush,
417  *         and if that fails: send error page
418  *
419  *    Revision 1.91  2002/04/08 20:35:58  swa
420  *    fixed JB spelling
421  *
422  *    Revision 1.90  2002/04/02 14:57:28  oes
423  *    Made sending wafers independent of FEATURE_COOKIE_JAR
424  *
425  *    Revision 1.89  2002/03/31 17:18:59  jongfoster
426  *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
427  *
428  *    Revision 1.88  2002/03/27 14:32:43  david__schmidt
429  *    More compiler warning message maintenance
430  *
431  *    Revision 1.87  2002/03/26 22:29:54  swa
432  *    we have a new homepage!
433  *
434  *    Revision 1.86  2002/03/25 17:04:55  david__schmidt
435  *    Workaround for closing the jarfile before load_config() comes around again
436  *
437  *    Revision 1.85  2002/03/24 15:23:33  jongfoster
438  *    Name changes
439  *
440  *    Revision 1.84  2002/03/24 13:25:43  swa
441  *    name change related issues
442  *
443  *    Revision 1.83  2002/03/16 23:54:06  jongfoster
444  *    Adding graceful termination feature, to help look for memory leaks.
445  *    If you enable this (which, by design, has to be done by hand
446  *    editing config.h) and then go to http://i.j.b/die, then the program
447  *    will exit cleanly after the *next* request.  It should free all the
448  *    memory that was used.
449  *
450  *    Revision 1.82  2002/03/13 00:27:05  jongfoster
451  *    Killing warnings
452  *
453  *    Revision 1.81  2002/03/12 01:42:50  oes
454  *    Introduced modular filters
455  *
456  *    Revision 1.80  2002/03/11 22:07:05  david__schmidt
457  *    OS/2 port maintenance:
458  *    - Fixed EMX build - it had decayed a little
459  *    - Fixed inexplicable crash during FD_ZERO - must be due to a bad macro.
460  *      substituted a memset for now.
461  *
462  *    Revision 1.79  2002/03/09 20:03:52  jongfoster
463  *    - Making various functions return int rather than size_t.
464  *      (Undoing a recent change).  Since size_t is unsigned on
465  *      Windows, functions like read_socket that return -1 on
466  *      error cannot return a size_t.
467  *
468  *      THIS WAS A MAJOR BUG - it caused frequent, unpredictable
469  *      crashes, and also frequently caused JB to jump to 100%
470  *      CPU and stay there.  (Because it thought it had just
471  *      read ((unsigned)-1) == 4Gb of data...)
472  *
473  *    - The signature of write_socket has changed, it now simply
474  *      returns success=0/failure=nonzero.
475  *
476  *    - Trying to get rid of a few warnings --with-debug on
477  *      Windows, I've introduced a new type "jb_socket".  This is
478  *      used for the socket file descriptors.  On Windows, this
479  *      is SOCKET (a typedef for unsigned).  Everywhere else, it's
480  *      an int.  The error value can't be -1 any more, so it's
481  *      now JB_INVALID_SOCKET (which is -1 on UNIX, and in
482  *      Windows it maps to the #define INVALID_SOCKET.)
483  *
484  *    - The signature of bind_port has changed.
485  *
486  *    Revision 1.78  2002/03/08 21:35:04  oes
487  *    Added optional group supplement to --user option. Will now use default group of user if no group given
488  *
489  *    Revision 1.77  2002/03/07 03:52:06  oes
490  *     - Fixed compiler warnings etc
491  *     - Improved handling of failed DNS lookups
492  *
493  *    Revision 1.76  2002/03/06 22:54:35  jongfoster
494  *    Automated function-comment nitpicking.
495  *
496  *    Revision 1.75  2002/03/06 10:02:19  oes
497  *    Fixed stupid bug when --user was not given
498  *
499  *    Revision 1.74  2002/03/06 00:49:31  jongfoster
500  *    Fixing warning on Windows
501  *    Making #ifdefs that refer to the same variable consistently
502  *    use #ifdef unix rather than mixing #ifdef unix & #ifndef OS2
503  *
504  *    Revision 1.73  2002/03/05 23:57:30  hal9
505  *    Stray character 's' on line 1618 was breaking build.
506  *
507  *    Revision 1.72  2002/03/05 21:33:45  david__schmidt
508  *    - Re-enable OS/2 building after new parms were added
509  *    - Fix false out of memory report when resolving CGI templates when no IP
510  *      address is available of failed attempt (a la no such domain)
511  *
512  *    Revision 1.71  2002/03/05 18:13:56  oes
513  *    Added --user option
514  *
515  *    Revision 1.70  2002/03/05 04:52:42  oes
516  *    Deleted non-errlog debugging code
517  *
518  *    Revision 1.69  2002/03/04 23:50:00  jongfoster
519  *    Splitting off bind_port() call into bind_port_helper(), with
520  *    improved logging.
521  *
522  *    Revision 1.68  2002/03/04 20:17:32  oes
523  *    Fixed usage info
524  *
525  *    Revision 1.67  2002/03/04 18:18:57  oes
526  *    - Removed _DEBUG mode
527  *    - Cleand up cmdline parsing
528  *    - Introduced --no-daemon, --pidfile options
529  *    - Cleaned up signal handling:
530  *      - Terminate cleanly on INT, TERM and ABRT
531  *      - Schedule logfile for re-opening on HUP
532  *      - Ignore CHLD and PIPE
533  *      - Leave the rest with their default handlers
534  *      - Uniform handler registration
535  *    - Added usage() function
536  *    - Played styleguide police
537  *
538  *    Revision 1.66  2002/03/03 15:06:55  oes
539  *    Re-enabled automatic config reloading
540  *
541  *    Revision 1.65  2002/03/03 14:49:11  oes
542  *    Fixed CLF logging: Now uses client's original HTTP request
543  *
544  *    Revision 1.64  2002/03/03 09:18:03  joergs
545  *    Made jumbjuster work on AmigaOS again.
546  *
547  *    Revision 1.63  2002/03/02 04:14:50  david__schmidt
548  *    Clean up a little CRLF unpleasantness that suddenly appeared
549  *
550  *    Revision 1.62  2002/02/20 23:17:23  jongfoster
551  *    Detecting some out-of memory conditions and exiting with a log message.
552  *
553  *    Revision 1.61  2002/01/17 21:01:52  jongfoster
554  *    Moving all our URL and URL pattern parsing code to urlmatch.c.
555  *
556  *    Revision 1.60  2001/12/30 14:07:32  steudten
557  *    - Add signal handling (unix)
558  *    - Add SIGHUP handler (unix)
559  *    - Add creation of pidfile (unix)
560  *    - Add action 'top' in rc file (RH)
561  *    - Add entry 'SIGNALS' to manpage
562  *    - Add exit message to logfile (unix)
563  *
564  *    Revision 1.59  2001/12/13 14:07:18  oes
565  *    Fixed Bug: 503 error page now sent OK
566  *
567  *    Revision 1.58  2001/11/30 23:37:24  jongfoster
568  *    Renaming the Win32 config file to config.txt - this is almost the
569  *    same as the corresponding UNIX name "config"
570  *
571  *    Revision 1.57  2001/11/16 00:47:43  jongfoster
572  *    Changing the tty-disconnection code to use setsid().
573  *
574  *    Revision 1.56  2001/11/13 20:20:54  jongfoster
575  *    Tabs->spaces, fixing a bug with missing {} around an if()
576  *
577  *    Revision 1.55  2001/11/13 20:14:53  jongfoster
578  *    Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
579  *
580  *    Revision 1.54  2001/11/07 00:03:14  steudten
581  *    Give reliable return value if an error
582  *    occurs not just 0 with new daemon mode.
583  *
584  *    Revision 1.53  2001/11/05 21:41:43  steudten
585  *    Add changes to be a real daemon just for unix os.
586  *    (change cwd to /, detach from controlling tty, set
587  *    process group and session leader to the own process.
588  *    Add DBG() Macro.
589  *    Add some fatal-error log message for failed malloc().
590  *    Add '-d' if compiled with 'configure --with-debug' to
591  *    enable debug output.
592  *
593  *    Revision 1.52  2001/10/26 20:11:20  jongfoster
594  *    Fixing type mismatch
595  *
596  *    Revision 1.51  2001/10/26 17:38:28  oes
597  *    Cosmetics
598  *
599  *    Revision 1.50  2001/10/25 03:40:48  david__schmidt
600  *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
601  *    threads to call select() simultaneously.  So, it's time to do a real, live,
602  *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
603  *    (native). Both versions will work, but using __OS2__ offers multi-threading.
604  *
605  *    Revision 1.49  2001/10/23 21:41:35  jongfoster
606  *    Added call to initialize the (statically-allocated of course)
607  *    "out of memory" CGI response.
608  *
609  *    Revision 1.48  2001/10/10 19:56:46  jongfoster
610  *    Moving some code that wasn't cookie-related out of an #ifdef
611  *    FEATURE_COOKIE_JAR
612  *
613  *    Revision 1.47  2001/10/10 16:44:36  oes
614  *    Added CONNECT destination port limitation check
615  *
616  *    Revision 1.46  2001/10/08 15:17:41  oes
617  *    Re-enabled SSL forwarding
618  *
619  *    Revision 1.45  2001/10/07 15:42:11  oes
620  *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
621  *
622  *    Moved downgrading of the HTTP version from parse_http_request to
623  *      chat(), since we can't decide if it is necessary before we have
624  *      determined the actions for the URL. The HTTP command is now
625  *      *always* re-built so the repairs need no longer be special-cased.
626  *
627  *    filter_popups now gets a csp pointer so it can raise the new
628  *      CSP_FLAG_MODIFIED flag.
629  *
630  *    Bugfix
631  *
632  *    Added configurable size limit for the IOB. If the IOB grows so
633  *      large that the next read would exceed the limit, the header
634  *      is generated, and the header & unfiltered buffer are flushed
635  *      to the client. Chat then continues in non-buffering,
636  *      non-filtering body mode.
637  *
638  *    Revision 1.44  2001/10/02 18:13:57  oes
639  *    Ooops
640  *
641  *    Revision 1.43  2001/10/02 15:32:13  oes
642  *    Moved generation of hdr
643  *
644  *    Revision 1.42  2001/09/21 23:02:02  david__schmidt
645  *    Cleaning up 2 compiler warnings on OS/2.
646  *
647  *    Revision 1.41  2001/09/16 17:05:14  jongfoster
648  *    Removing unused #include showarg.h
649  *
650  *    Revision 1.40  2001/09/16 15:41:45  jongfoster
651  *    Fixing signed/unsigned comparison warning.
652  *
653  *    Revision 1.39  2001/09/16 13:21:27  jongfoster
654  *    Changes to use new list functions.
655  *
656  *    Revision 1.38  2001/09/16 13:01:46  jongfoster
657  *    Removing redundant function call that zeroed zalloc()'d memory.
658  *
659  *    Revision 1.37  2001/09/10 11:12:24  oes
660  *    Deleted unused variable
661  *
662  *    Revision 1.36  2001/09/10 10:56:15  oes
663  *    Silenced compiler warnings
664  *
665  *    Revision 1.35  2001/07/31 14:44:22  oes
666  *    Deleted unused size parameter from filter_popups()
667  *
668  *    Revision 1.34  2001/07/30 22:08:36  jongfoster
669  *    Tidying up #defines:
670  *    - All feature #defines are now of the form FEATURE_xxx
671  *    - Permanently turned off WIN_GUI_EDIT
672  *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
673  *
674  *    Revision 1.33  2001/07/29 19:32:00  jongfoster
675  *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
676  *
677  *    Revision 1.32  2001/07/29 18:47:05  jongfoster
678  *    Adding missing #include "loadcfg.h"
679  *
680  *    Revision 1.31  2001/07/29 12:17:48  oes
681  *    Applied pthread fix by Paul Lieverse
682  *
683  *    Revision 1.30  2001/07/25 22:57:13  jongfoster
684  *    __BEOS__ no longer overrides FEATURE_PTHREAD.
685  *    This is because FEATURE_PTHREAD will soon be widely used, so I
686  *    want to keep it simple.
687  *
688  *    Revision 1.29  2001/07/24 12:47:06  oes
689  *    Applied BeOS support update by Eugenia
690  *
691  *    Revision 1.28  2001/07/23 13:26:12  oes
692  *    Fixed bug in popup-killing for the first read that caused binary garbage to be sent between headers and body
693  *
694  *    Revision 1.27  2001/07/19 19:09:47  haroon
695  *    - Added code to take care of the situation where while processing the first
696  *      server response (which includes the server header), after finding the end
697  *      of the headers we were not looking past the end of the headers for
698  *      content modification. I enabled it for filter_popups.
699  *      Someone else should look to see if other similar operations should be
700  *      done to the discarded portion of the buffer.
701  *
702  *      Note 2001/07/20: No, the other content modification mechanisms will process
703  *                       the whole iob later anyway. --oes
704  *
705  *    Revision 1.26  2001/07/18 12:31:36  oes
706  *    cosmetics
707  *
708  *    Revision 1.25  2001/07/15 19:43:49  jongfoster
709  *    Supports POSIX threads.
710  *    Also removed some unused #includes.
711  *
712  *    Revision 1.24  2001/07/13 14:00:40  oes
713  *     - Generic content modification scheme:
714  *       Each feature has its own applicability flag that is set
715  *       from csp->action->flags.
716  *       Replaced the "filtering" int flag , by a function pointer
717  *       "content_filter" to the function that will do the content
718  *       modification. If it is != NULL, the document will be buffered
719  *       and processed through *content_filter, which must set
720  *       csp->content_length and return a modified copy of the body
721  *       or return NULL (on failiure).
722  *     - Changed csp->is_text to the more generic bitmap csp->content_type
723  *       which can currently take the valued CT_TEXT or CT_GIF
724  *     - Reformatting etc
725  *     - Removed all #ifdef PCRS
726  *
727  *    Revision 1.23  2001/07/02 02:28:25  iwanttokeepanon
728  *    Added "#ifdef ACL_FILES" conditional compilation to line 1291 to exclude
729  *    the `block_acl' call.  This prevents a compilation error when the user
730  *    does not wish to use the "ACL" feature.
731  *
732  *    Revision 1.22  2001/06/29 21:45:41  oes
733  *    Indentation, CRLF->LF, Tab-> Space
734  *
735  *    Revision 1.21  2001/06/29 13:29:36  oes
736  *    - Cleaned up, improved comments
737  *    - Unified all possible interceptors (CGI,
738  *      block, trust, fast_redirect) in one
739  *      place, with one (CGI) answer generation
740  *      mechansim. Much clearer now.
741  *    - Removed the GIF image generation, which
742  *      is now done in filters.c:block_url()
743  *    - Made error conditions like domain lookup
744  *      failiure or (various) problems while talking
745  *      to the server use cgi.c:error_response()
746  *      instead of generating HTML/HTTP in chat() (yuck!)
747  *    - Removed logentry from cancelled commit
748  *
749  *    Revision 1.20  2001/06/09 10:55:28  jongfoster
750  *    Changing BUFSIZ ==> BUFFER_SIZE
751  *
752  *    Revision 1.19  2001/06/07 23:12:52  jongfoster
753  *    Replacing function pointer in struct gateway with a directly
754  *    called function forwarded_connect().
755  *    Replacing struct gateway with struct forward_spec
756  *
757  *    Revision 1.18  2001/06/03 19:12:16  oes
758  *    introduced new cgi handling
759  *
760  *    Revision 1.17  2001/06/01 20:07:23  jongfoster
761  *    Now uses action +image-blocker{} rather than config->tinygif
762  *
763  *    Revision 1.16  2001/06/01 18:49:17  jongfoster
764  *    Replaced "list_share" with "list" - the tiny memory gain was not
765  *    worth the extra complexity.
766  *
767  *    Revision 1.15  2001/05/31 21:24:47  jongfoster
768  *    Changed "permission" to "action" throughout.
769  *    Removed DEFAULT_USER_AGENT - it must now be specified manually.
770  *    Moved vanilla wafer check into chat(), since we must now
771  *    decide whether or not to add it based on the URL.
772  *
773  *    Revision 1.14  2001/05/29 20:14:01  joergs
774  *    AmigaOS bugfix: PCRS needs a lot of stack, stacksize for child threads
775  *    increased.
776  *
777  *    Revision 1.13  2001/05/29 09:50:24  jongfoster
778  *    Unified blocklist/imagelist/permissionslist.
779  *    File format is still under discussion, but the internal changes
780  *    are (mostly) done.
781  *
782  *    Also modified interceptor behaviour:
783  *    - We now intercept all URLs beginning with one of the following
784  *      prefixes (and *only* these prefixes):
785  *        * http://i.j.b/
786  *        * http://ijbswa.sf.net/config/
787  *        * http://ijbswa.sourceforge.net/config/
788  *    - New interceptors "home page" - go to http://i.j.b/ to see it.
789  *    - Internal changes so that intercepted and fast redirect pages
790  *      are not replaced with an image.
791  *    - Interceptors now have the option to send a binary page direct
792  *      to the client. (i.e. ijb-send-banner uses this)
793  *    - Implemented show-url-info interceptor.  (Which is why I needed
794  *      the above interceptors changes - a typical URL is
795  *      "http://i.j.b/show-url-info?url=www.somesite.com/banner.gif".
796  *      The previous mechanism would not have intercepted that, and
797  *      if it had been intercepted then it then it would have replaced
798  *      it with an image.)
799  *
800  *    Revision 1.12  2001/05/27 22:17:04  oes
801  *
802  *    - re_process_buffer no longer writes the modified buffer
803  *      to the client, which was very ugly. It now returns the
804  *      buffer, which it is then written by chat.
805  *
806  *    - content_length now adjusts the Content-Length: header
807  *      for modified documents rather than crunch()ing it.
808  *      (Length info in csp->content_length, which is 0 for
809  *      unmodified documents)
810  *
811  *    - For this to work, sed() is called twice when filtering.
812  *
813  *    Revision 1.11  2001/05/26 17:27:53  jongfoster
814  *    Added support for CLF and fixed LOG_LEVEL_LOG.
815  *    Also did CRLF->LF fix of my previous patch.
816  *
817  *    Revision 1.10  2001/05/26 15:26:15  jongfoster
818  *    ACL feature now provides more security by immediately dropping
819  *    connections from untrusted hosts.
820  *
821  *    Revision 1.9  2001/05/26 00:28:36  jongfoster
822  *    Automatic reloading of config file.
823  *    Removed obsolete SIGHUP support (Unix) and Reload menu option (Win32).
824  *    Most of the global variables have been moved to a new
825  *    struct configuration_spec, accessed through csp->config->globalname
826  *    Most of the globals remaining are used by the Win32 GUI.
827  *
828  *    Revision 1.8  2001/05/25 22:43:18  jongfoster
829  *    Fixing minor memory leak and buffer overflow.
830  *
831  *    Revision 1.7  2001/05/25 22:34:30  jongfoster
832  *    Hard tabs->Spaces
833  *
834  *    Revision 1.6  2001/05/23 00:13:58  joergs
835  *    AmigaOS support fixed.
836  *
837  *    Revision 1.5  2001/05/22 18:46:04  oes
838  *
839  *    - Enabled filtering banners by size rather than URL
840  *      by adding patterns that replace all standard banner
841  *      sizes with the "Junkbuster" gif to the re_filterfile
842  *
843  *    - Enabled filtering WebBugs by providing a pattern
844  *      which kills all 1x1 images
845  *
846  *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
847  *      which is selected by the (nonstandard and therefore
848  *      capital) letter 'U' in the option string.
849  *      It causes the quantifiers to be ungreedy by default.
850  *      Appending a ? turns back to greedy (!).
851  *
852  *    - Added a new interceptor ijb-send-banner, which
853  *      sends back the "Junkbuster" gif. Without imagelist or
854  *      MSIE detection support, or if tinygif = 1, or the
855  *      URL isn't recognized as an imageurl, a lame HTML
856  *      explanation is sent instead.
857  *
858  *    - Added new feature, which permits blocking remote
859  *      script redirects and firing back a local redirect
860  *      to the browser.
861  *      The feature is conditionally compiled, i.e. it
862  *      can be disabled with --disable-fast-redirects,
863  *      plus it must be activated by a "fast-redirects"
864  *      line in the config file, has its own log level
865  *      and of course wants to be displayed by show-proxy-args
866  *      Note: Boy, all the #ifdefs in 1001 locations and
867  *      all the fumbling with configure.in and acconfig.h
868  *      were *way* more work than the feature itself :-(
869  *
870  *    - Because a generic redirect template was needed for
871  *      this, tinygif = 3 now uses the same.
872  *
873  *    - Moved GIFs, and other static HTTP response templates
874  *      to project.h
875  *
876  *    - Some minor fixes
877  *
878  *    - Removed some >400 CRs again (Jon, you really worked
879  *      a lot! ;-)
880  *
881  *    Revision 1.4  2001/05/21 19:34:01  jongfoster
882  *    Made failure to bind() a fatal error.
883  *
884  *    Revision 1.3  2001/05/20 01:21:20  jongfoster
885  *    Version 2.9.4 checkin.
886  *    - Merged popupfile and cookiefile, and added control over PCRS
887  *      filtering, in new "permissionsfile".
888  *    - Implemented LOG_LEVEL_FATAL, so that if there is a configuration
889  *      file error you now get a message box (in the Win32 GUI) rather
890  *      than the program exiting with no explanation.
891  *    - Made killpopup use the PCRS MIME-type checking and HTTP-header
892  *      skipping.
893  *    - Removed tabs from "config"
894  *    - Moved duplicated url parsing code in "loaders.c" to a new funcition.
895  *    - Bumped up version number.
896  *
897  *    Revision 1.2  2001/05/17 22:34:44  oes
898  *     - Added hint on GIF char array generation to jcc.c
899  *     - Cleaned CRLF's from the sources and related files
900  *     - Repaired logging for REF and FRC
901  *
902  *    Revision 1.1.1.1  2001/05/15 13:58:56  oes
903  *    Initial import of version 2.9.3 source tree
904  *
905  *
906  *********************************************************************/
907 \f
908
909 #include "config.h"
910
911 #include <stdio.h>
912 #include <sys/types.h>
913 #include <stdlib.h>
914 #include <string.h>
915 #include <signal.h>
916 #include <fcntl.h>
917 #include <errno.h>
918 #include <assert.h>
919
920 #ifdef _WIN32
921 # ifndef FEATURE_PTHREAD
922 #  ifndef STRICT
923 #   define STRICT
924 #  endif
925 #  include <windows.h>
926 #  include <process.h>
927 # endif /* ndef FEATURE_PTHREAD */
928
929 # include "win32.h"
930 # ifndef _WIN_CONSOLE
931 #  include "w32log.h"
932 # endif /* ndef _WIN_CONSOLE */
933 # include "w32svrapi.h"
934
935 #else /* ifndef _WIN32 */
936
937 # if !defined (__OS2__)
938 # include <unistd.h>
939 # include <sys/wait.h>
940 # endif /* ndef __OS2__ */
941 # include <sys/time.h>
942 # include <sys/stat.h>
943 # include <sys/ioctl.h>
944
945 #ifdef sun
946 #include <sys/termios.h>
947 #endif /* sun */
948
949 #ifdef unix
950 #include <pwd.h>
951 #include <grp.h>
952 #endif
953
954 # include <signal.h>
955
956 # ifdef __BEOS__
957 #  include <socket.h>  /* BeOS has select() for sockets only. */
958 #  include <OS.h>      /* declarations for threads and stuff. */
959 # endif
960
961 # if defined(__EMX__) || defined(__OS2__)
962 #  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
963 # endif
964 # ifdef __OS2__
965 #define INCL_DOS
966 # include <os2.h>
967 #define bzero(B,N) memset(B,0x00,n)
968 # endif
969
970 # ifndef FD_ZERO
971 #  include <select.h>
972 # endif
973
974 #endif
975
976 #include "project.h"
977 #include "list.h"
978 #include "jcc.h"
979 #include "filters.h"
980 #include "loaders.h"
981 #include "parsers.h"
982 #include "killpopup.h"
983 #include "miscutil.h"
984 #include "errlog.h"
985 #include "jbsockets.h"
986 #include "gateway.h"
987 #include "actions.h"
988 #include "cgi.h"
989 #include "loadcfg.h"
990 #include "urlmatch.h"
991
992 const char jcc_h_rcs[] = JCC_H_VERSION;
993 const char project_h_rcs[] = PROJECT_H_VERSION;
994
995 int no_daemon = 0;
996 struct client_state  clients[1];
997 struct file_list     files[1];
998
999 #ifdef FEATURE_STATISTICS
1000 int urls_read     = 0;     /* total nr of urls read inc rejected */
1001 int urls_rejected = 0;     /* total nr of urls rejected */
1002 #endif /* def FEATURE_STATISTICS */
1003
1004 #ifdef FEATURE_GRACEFUL_TERMINATION
1005 int g_terminate = 0;
1006 #endif
1007
1008 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
1009 static void sig_handler(int the_signal);
1010 #endif
1011 static int client_protocol_is_unsupported(const struct client_state *csp, char *req);
1012 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
1013 static jb_err get_server_headers(struct client_state *csp);
1014 static const char *crunch_reason(const struct http_response *rsp);
1015 static void send_crunch_response(struct client_state *csp, struct http_response *rsp);
1016 /*
1017  * static int request_contains_null_bytes(const struct client_state *csp, char *buf, int len);
1018  */
1019 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line);
1020 static jb_err change_request_destination(struct client_state *csp);
1021 static void chat(struct client_state *csp);
1022 static void serve(struct client_state *csp);
1023 #if defined(unix)
1024 static void usage(const char *myname);
1025 #endif
1026 static void initialize_mutexes(void);
1027 static jb_socket bind_port_helper(struct configuration_spec *config);
1028 static void listen_loop(void);
1029
1030 #ifdef AMIGA
1031 void serve(struct client_state *csp);
1032 #else /* ifndef AMIGA */
1033 static void serve(struct client_state *csp);
1034 #endif /* def AMIGA */
1035
1036 #ifdef __BEOS__
1037 static int32 server_thread(void *data);
1038 #endif /* def __BEOS__ */
1039
1040 #ifdef _WIN32
1041 #define sleep(N)  Sleep(((N) * 1000))
1042 #endif
1043
1044 #ifdef __OS2__
1045 #define sleep(N)  DosSleep(((N) * 100))
1046 #endif
1047
1048 #ifdef FEATURE_PTHREAD
1049 pthread_mutex_t log_mutex;
1050 pthread_mutex_t log_init_mutex;
1051
1052 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
1053 pthread_mutex_t resolver_mutex;
1054 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
1055
1056 #ifndef HAVE_GMTIME_R
1057 pthread_mutex_t gmtime_mutex;
1058 #endif /* ndef HAVE_GMTIME_R */
1059
1060 #ifndef HAVE_LOCALTIME_R
1061 pthread_mutex_t localtime_mutex;
1062 #endif /* ndef HAVE_GMTIME_R */
1063
1064 #ifndef HAVE_RANDOM
1065 pthread_mutex_t rand_mutex;
1066 #endif /* ndef HAVE_RANDOM */
1067
1068 #endif /* FEATURE_PTHREAD */
1069
1070 #if defined(unix) || defined(__EMX__)
1071 const char *basedir = NULL;
1072 const char *pidfile = NULL;
1073 int received_hup_signal = 0;
1074 #endif /* defined unix */
1075
1076 /* HTTP snipplets. */
1077 static const char CSUCCEED[] =
1078    "HTTP/1.0 200 Connection established\n"
1079    "Proxy-Agent: Privoxy/" VERSION "\r\n\r\n";
1080
1081 static const char CHEADER[] =
1082    "HTTP/1.0 400 Invalid header received from browser\r\n"
1083    "Proxy-Agent: Privoxy " VERSION "\r\n"
1084    "Content-Type: text/plain\r\n"
1085    "Connection: close\r\n\r\n"
1086    "Invalid header received from browser.\r\n";
1087
1088 static const char CFORBIDDEN[] =
1089    "HTTP/1.0 403 Connection not allowable\r\n"
1090    "Proxy-Agent: Privoxy " VERSION "\r\n"
1091    "X-Hint: If you read this message interactively, then you know why this happens ,-)\r\n"
1092    "Connection: close\r\n\r\n";
1093
1094 static const char FTP_RESPONSE[] =
1095    "HTTP/1.0 400 Invalid request received from browser\r\n"
1096    "Content-Type: text/plain\r\n"
1097    "Connection: close\r\n\r\n"
1098    "Invalid request. Privoxy doesn't support FTP.\r\n";
1099
1100 static const char GOPHER_RESPONSE[] =
1101    "HTTP/1.0 400 Invalid request received from browser\r\n"
1102    "Content-Type: text/plain\r\n"
1103    "Connection: close\r\n\r\n"
1104    "Invalid request. Privoxy doesn't support gopher.\r\n";
1105
1106 /* XXX: should be a template */
1107 static const char MISSING_DESTINATION_RESPONSE[] =
1108    "HTTP/1.0 400 Bad request received from browser\r\n"
1109    "Proxy-Agent: Privoxy " VERSION "\r\n"
1110    "Content-Type: text/plain\r\n"
1111    "Connection: close\r\n\r\n"
1112    "Bad request. Privoxy was unable to extract the destination.\r\n";
1113
1114 /* XXX: should be a template */
1115 static const char NO_SERVER_DATA_RESPONSE[] =
1116    "HTTP/1.0 502 Server or forwarder response empty\r\n"
1117    "Proxy-Agent: Privoxy " VERSION "\r\n"
1118    "Content-Type: text/plain\r\n"
1119    "Connection: close\r\n\r\n"
1120    "Empty server or forwarder response.\r\n"
1121    "The connection was closed without sending any data.\r\n";
1122
1123 #if 0
1124 /* XXX: should be a template */
1125 static const char NULL_BYTE_RESPONSE[] =
1126    "HTTP/1.0 400 Bad request received from browser\r\n"
1127    "Proxy-Agent: Privoxy " VERSION "\r\n"
1128    "Content-Type: text/plain\r\n"
1129    "Connection: close\r\n\r\n"
1130    "Bad request. Null byte(s) before end of request.\r\n";
1131 #endif
1132
1133 /* XXX: should be a template */
1134 static const char MESSED_UP_REQUEST_RESPONSE[] =
1135    "HTTP/1.0 400 Malformed request after rewriting\r\n"
1136    "Proxy-Agent: Privoxy " VERSION "\r\n"
1137    "Content-Type: text/plain\r\n"
1138    "Connection: close\r\n\r\n"
1139    "Bad request. Messed up with header filters.\r\n";
1140
1141 /* A function to crunch a response */
1142 typedef struct http_response *(*crunch_func_ptr)(struct client_state *);
1143
1144 /* Crunch function flags */
1145 #define CF_NO_FLAGS        0
1146 /* Cruncher applies to forced requests as well */
1147 #define CF_IGNORE_FORCE    1
1148 /* Crunched requests are counted for the block statistics */
1149 #define CF_COUNT_AS_REJECT 2
1150
1151 /* A crunch function and its flags */
1152 struct cruncher
1153 {
1154    const crunch_func_ptr cruncher;
1155    const int flags;
1156 };
1157
1158 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[]);
1159
1160 /* Complete list of cruncher functions */
1161 static const struct cruncher crunchers_all[] = {
1162    { direct_response, CF_COUNT_AS_REJECT|CF_IGNORE_FORCE},
1163    { block_url,       CF_COUNT_AS_REJECT },
1164 #ifdef FEATURE_TRUST
1165    { trust_url,       CF_COUNT_AS_REJECT },
1166 #endif /* def FEATURE_TRUST */
1167    { redirect_url,    CF_NO_FLAGS  },
1168    { dispatch_cgi,    CF_IGNORE_FORCE},
1169    { NULL,            0 }
1170 };
1171
1172 /* Light version, used after tags are applied */
1173 static const struct cruncher crunchers_light[] = {
1174    { block_url,       CF_COUNT_AS_REJECT },
1175    { redirect_url,    CF_NO_FLAGS },
1176    { NULL,            0 }
1177 };
1178
1179
1180 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
1181 /*********************************************************************
1182  *
1183  * Function    :  sig_handler 
1184  *
1185  * Description :  Signal handler for different signals.
1186  *                Exit gracefully on TERM and INT
1187  *                or set a flag that will cause the errlog
1188  *                to be reopened by the main thread on HUP.
1189  *
1190  * Parameters  :
1191  *          1  :  the_signal = the signal cause this function to call
1192  *
1193  * Returns     :  - 
1194  *
1195  *********************************************************************/
1196 static void sig_handler(int the_signal)
1197 {
1198    switch(the_signal)
1199    {
1200       case SIGTERM:
1201       case SIGINT:
1202          log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
1203 #if defined(unix)
1204          if(pidfile)
1205          {
1206             unlink(pidfile);
1207          }
1208 #endif /* unix */
1209          exit(the_signal);
1210          break;
1211
1212       case SIGHUP:
1213          received_hup_signal = 1;
1214          break;         
1215
1216       default:
1217          /* 
1218           * We shouldn't be here, unless we catch signals
1219           * in main() that we can't handle here!
1220           */
1221          log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
1222    }
1223    return;
1224
1225 }
1226 #endif
1227
1228
1229 /*********************************************************************
1230  *
1231  * Function    :  client_protocol_is_unsupported
1232  *
1233  * Description :  Checks if the client used a known unsupported
1234  *                protocol and deals with it by sending an error
1235  *                response.
1236  *
1237  * Parameters  :
1238  *          1  :  csp = Current client state (buffers, headers, etc...)
1239  *          2  :  req = the first request line send by the client
1240  *
1241  * Returns     :  TRUE if an error response has been generated, or
1242  *                FALSE if the request doesn't look invalid.
1243  *
1244  *********************************************************************/
1245 static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
1246 {
1247    char buf[BUFFER_SIZE];
1248
1249    /*
1250     * If it's a FTP or gopher request, we don't support it.
1251     *
1252     * These checks are better than nothing, but they might
1253     * not work in all configurations and some clients might
1254     * have problems digesting the answer.
1255     *
1256     * They should, however, never cause more problems than
1257     * Privoxy's old behaviour (returning the misleading HTML
1258     * error message:
1259     *
1260     * "Could not resolve http://(ftp|gopher)://example.org").
1261     */
1262    if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
1263    {
1264       if (!strncmpic(req, "GET ftp://", 10))
1265       {
1266          strlcpy(buf, FTP_RESPONSE, sizeof(buf));
1267          log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s",
1268             csp->ip_addr_str, req);
1269       }
1270       else
1271       {
1272          strlcpy(buf, GOPHER_RESPONSE, sizeof(buf));
1273          log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as gopher proxy: %s",
1274             csp->ip_addr_str, req);
1275       }
1276       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
1277       freez(req);
1278       write_socket(csp->cfd, buf, strlen(buf));
1279
1280       return TRUE;
1281    }
1282
1283    return FALSE;
1284 }
1285
1286
1287 /*********************************************************************
1288  *
1289  * Function    :  get_request_destination_elsewhere
1290  *
1291  * Description :  If the client's request was redirected into
1292  *                Privoxy without the client's knowledge,
1293  *                the request line lacks the destination host.
1294  *
1295  *                This function tries to get it elsewhere,
1296  *                provided accept-intercepted-requests is enabled.
1297  *
1298  *                "Elsewhere" currently only means "Host: header",
1299  *                but in the future we may ask the redirecting
1300  *                packet filter to look the destination up.
1301  *
1302  *                If the destination stays unknown, an error
1303  *                response is send to the client and headers
1304  *                are freed so that chat() can return directly.
1305  *
1306  * Parameters  :
1307  *          1  :  csp = Current client state (buffers, headers, etc...)
1308  *          2  :  headers = a header list
1309  *
1310  * Returns     :  JB_ERR_OK if the destination is now known, or
1311  *                JB_ERR_PARSE if it isn't.
1312  *
1313  *********************************************************************/
1314 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers)
1315 {
1316    char *req;
1317
1318    if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
1319    {
1320       log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
1321          " Privoxy isn't configured to accept intercepted requests.",
1322          csp->ip_addr_str, csp->http->cmd);
1323       /* XXX: Use correct size */
1324       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1325          csp->ip_addr_str, csp->http->cmd);
1326
1327       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1328       destroy_list(headers);
1329
1330       return JB_ERR_PARSE;
1331    }
1332    else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http))
1333    {
1334       /* Split the domain we just got for pattern matching */
1335       init_domain_components(csp->http);
1336
1337       return JB_ERR_OK;
1338    }
1339    else
1340    {
1341       /* We can't work without destination. Go spread the news.*/
1342
1343       req = list_to_text(headers);
1344       chomp(req);
1345       /* XXX: Use correct size */
1346       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1347          csp->ip_addr_str, csp->http->cmd);
1348       log_error(LOG_LEVEL_ERROR,
1349          "Privoxy was unable to get the destination for %s's request:\n%s\n%s",
1350          csp->ip_addr_str, csp->http->cmd, req);
1351       freez(req);
1352
1353       write_socket(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE));
1354       destroy_list(headers);
1355
1356       return JB_ERR_PARSE;
1357    }
1358    /*
1359     * TODO: If available, use PF's ioctl DIOCNATLOOK as last resort
1360     * to get the destination IP address, use it as host directly
1361     * or do a reverse DNS lookup first.
1362     */
1363 }
1364
1365
1366 /*********************************************************************
1367  *
1368  * Function    :  get_server_headers
1369  *
1370  * Description :  Parses server headers in iob and fills them
1371  *                into csp->headers so that they can later be
1372  *                handled by sed().
1373  *
1374  * Parameters  :
1375  *          1  :  csp = Current client state (buffers, headers, etc...)
1376  *
1377  * Returns     :  JB_ERR_OK if everything went fine, or
1378  *                JB_ERR_PARSE if the headers were incomplete.
1379  *
1380  *********************************************************************/
1381 static jb_err get_server_headers(struct client_state *csp)
1382 {
1383    int continue_hack_in_da_house = 0;
1384    char * header;
1385
1386    while (((header = get_header(csp)) != NULL) || continue_hack_in_da_house)
1387    {
1388       if (header == NULL)
1389       {
1390          /*
1391           * continue hack in da house. Ignore the ending of
1392           * this head and continue enlisting header lines.
1393           * The reason is described below.
1394           */
1395          enlist(csp->headers, "");
1396          continue_hack_in_da_house = 0;
1397          continue;
1398       }
1399       else if (0 == strncmpic(header, "HTTP/1.1 100", 12))
1400       {
1401          /*
1402           * It's a bodyless continue response, don't
1403           * stop header parsing after reaching it's end.
1404           *
1405           * As a result Privoxy will concatenate the
1406           * next response's head and parse and deliver
1407           * the headers as if they belonged to one request.
1408           *
1409           * The client will separate them because of the
1410           * empty line between them.
1411           *
1412           * XXX: What we're doing here is clearly against
1413           * the intended purpose of the continue header,
1414           * and under some conditions (HTTP/1.0 client request)
1415           * it's a standard violation.
1416           *
1417           * Anyway, "sort of against the spec" is preferable
1418           * to "always getting confused by Continue responses"
1419           * (Privoxy's behaviour before this hack was added)
1420           */
1421          log_error(LOG_LEVEL_HEADER, "Continue hack in da house.");
1422          continue_hack_in_da_house = 1;
1423       }
1424       else if (*header == '\0') 
1425       {
1426          /*
1427           * If the header is empty, but the Continue hack
1428           * isn't active, we can assume that we reached the
1429           * end of the buffer before we hit the end of the
1430           * head.
1431           *
1432           * Inform the caller an let it decide how to handle it.
1433           */
1434          return JB_ERR_PARSE;
1435       }
1436
1437       /* Enlist header */
1438       if (JB_ERR_MEMORY == enlist(csp->headers, header))
1439       {
1440          /*
1441           * XXX: Should we quit the request and return a
1442           * out of memory error page instead?
1443           */
1444          log_error(LOG_LEVEL_ERROR,
1445             "Out of memory while enlisting server headers. %s lost.",
1446             header);
1447       }
1448       freez(header);
1449    }
1450
1451    return JB_ERR_OK;
1452 }
1453
1454
1455 /*********************************************************************
1456  *
1457  * Function    :  crunch_reason
1458  *
1459  * Description :  Translates the crunch reason code into a string.
1460  *
1461  * Parameters  :
1462  *          1  :  rsp = a http_response
1463  *
1464  * Returns     :  A string with the crunch reason or an error description.
1465  *
1466  *********************************************************************/
1467 static const char *crunch_reason(const struct http_response *rsp)
1468 {
1469    char * reason = NULL;
1470
1471    assert(rsp != NULL);
1472    if (rsp == NULL)
1473    {
1474       return "Internal error while searching for crunch reason";
1475    }
1476
1477    switch (rsp->reason)
1478    {
1479       case RSP_REASON_UNSUPPORTED:
1480          reason = "Unsupported HTTP feature";
1481          break;
1482       case RSP_REASON_BLOCKED:
1483          reason = "Blocked";
1484          break;
1485       case RSP_REASON_UNTRUSTED:
1486          reason = "Untrusted";
1487          break;
1488       case RSP_REASON_REDIRECTED:
1489          reason = "Redirected";
1490          break;
1491       case RSP_REASON_CGI_CALL:
1492          reason = "CGI Call";
1493          break;
1494       case RSP_REASON_NO_SUCH_DOMAIN:
1495          reason = "DNS failure";
1496          break;
1497       case RSP_REASON_FORWARDING_FAILED:
1498          reason = "Forwarding failed";
1499          break;
1500       case RSP_REASON_CONNECT_FAILED:
1501          reason = "Connection failure";
1502          break;
1503       case RSP_REASON_OUT_OF_MEMORY:
1504          reason = "Out of memory (may mask other reasons)";
1505          break;
1506       default:
1507          reason = "No reason recorded";
1508          break;
1509    }
1510
1511    return reason;
1512 }
1513
1514
1515 /*********************************************************************
1516  *
1517  * Function    :  send_crunch_response
1518  *
1519  * Description :  Delivers already prepared response for
1520  *                intercepted requests, logs the interception
1521  *                and frees the response.
1522  *
1523  * Parameters  :
1524  *          1  :  csp = Current client state (buffers, headers, etc...)
1525  *          1  :  rsp = Fully prepared response. Will be freed on exit.
1526  *
1527  * Returns     :  Nothing.
1528  *
1529  *********************************************************************/
1530 static void send_crunch_response(struct client_state *csp, struct http_response *rsp)
1531 {
1532       const struct http_request *http = csp->http;
1533       char status_code[4];
1534
1535       assert(rsp != NULL);
1536       assert(rsp->head != NULL);
1537
1538       if (rsp == NULL)
1539       {
1540          /*
1541           * Not supposed to happen. If it does
1542           * anyway, treat it as an unknown error.
1543           */
1544          cgi_error_unknown(csp, rsp, RSP_REASON_INTERNAL_ERROR);
1545          /* return code doesn't matter */
1546       }
1547
1548       if (rsp == NULL)
1549       {
1550          /* If rsp is still NULL, we have serious internal problems. */
1551          log_error(LOG_LEVEL_FATAL,
1552             "NULL response in send_crunch_response and cgi_error_unknown failed as well.");
1553       }
1554
1555       /*
1556        * Extract the status code from the actual head
1557        * that was send to the client. It is the only
1558        * way to get it right for all requests, including
1559        * the fixed ones for out-of-memory problems.
1560        *
1561        * A head starts like this: 'HTTP/1.1 200...'
1562        *                           0123456789|11
1563        *                                     10
1564        */
1565       status_code[0] = rsp->head[9];
1566       status_code[1] = rsp->head[10];
1567       status_code[2] = rsp->head[11];
1568       status_code[3] = '\0';
1569
1570       /* Write the answer to the client */
1571       if (write_socket(csp->cfd, rsp->head, rsp->head_length)
1572        || write_socket(csp->cfd, rsp->body, rsp->content_length))
1573       {
1574          /* There is nothing we can do about it. */
1575          log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", csp->http->host);
1576       }
1577
1578       /* Log that the request was crunched and why. */
1579       log_error(LOG_LEVEL_GPC, "%s%s crunch! (%s)",
1580          http->hostport, http->path, crunch_reason(rsp));
1581       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %d",
1582          csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
1583
1584       /* Clean up and return */
1585       if (cgi_error_memory() != rsp)
1586       {
1587          free_http_response(rsp);
1588       } 
1589       return;
1590 }
1591
1592
1593 #if 0
1594 /*********************************************************************
1595  *
1596  * Function    :  request_contains_null_bytes
1597  *
1598  * Description :  Checks for NULL bytes in the request and sends
1599  *                an error message to the client if any were found.
1600  *
1601  *                XXX: currently not used, see comment in chat().
1602  *
1603  * Parameters  :
1604  *          1  :  csp = Current client state (buffers, headers, etc...)
1605  *          2  :  buf = Data from the client's request to check.
1606  *          3  :  len = The data length.
1607  *
1608  * Returns     :  TRUE if the request contained one or more NULL bytes, or
1609  *                FALSE otherwise.
1610  *
1611  *********************************************************************/
1612 static int request_contains_null_bytes(const struct client_state *csp, char *buf, int len)
1613 {
1614    size_t c_len; /* Request lenght when treated as C string */
1615
1616    c_len = strlen(buf);
1617
1618    if (c_len < len)
1619    {
1620       /*
1621        * Null byte(s) found. Log the request,
1622        * return an error response and hang up.
1623        */
1624       size_t tmp_len = c_len;
1625
1626       do
1627       {
1628         /*
1629          * Replace NULL byte(s) with '°' characters
1630          * so the request can be logged as string.
1631          * XXX: Is there a better replacement character?
1632          */
1633          buf[tmp_len]='°';
1634          tmp_len += strlen(buf+tmp_len);
1635       } while (tmp_len < len);
1636
1637       log_error(LOG_LEVEL_ERROR, "%s\'s request contains at least one NULL byte "
1638          "(length=%d, strlen=%d).", csp->ip_addr_str, len, c_len);
1639       log_error(LOG_LEVEL_HEADER, 
1640          "Offending request data with NULL bytes turned into \'°\' characters: %s", buf);
1641
1642       write_socket(csp->cfd, NULL_BYTE_RESPONSE, strlen(NULL_BYTE_RESPONSE));
1643
1644       /* XXX: Log correct size */
1645       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
1646
1647       return TRUE;
1648    }
1649
1650    return FALSE;
1651 }
1652 #endif
1653
1654
1655 /*********************************************************************
1656  *
1657  * Function    :  crunch_response_triggered
1658  *
1659  * Description :  Checks if the request has to be crunched,
1660  *                and delivers the crunch response if necessary.
1661  *
1662  * Parameters  :
1663  *          1  :  csp = Current client state (buffers, headers, etc...)
1664  *          2  :  crunchers = list of cruncher functions to run
1665  *
1666  * Returns     :  TRUE if the request was answered with a crunch response
1667  *                FALSE otherwise.
1668  *
1669  *********************************************************************/
1670 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
1671 {
1672    struct http_response *rsp = NULL;
1673    const struct cruncher *c;
1674
1675    /*
1676     * If CGI request crunching is disabled,
1677     * check the CGI dispatcher out of order to
1678     * prevent unintentional blocks or redirects. 
1679     */
1680    if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_CRUNCHING)
1681        && (NULL != (rsp = dispatch_cgi(csp))))
1682    {
1683       /* Deliver, log and free the interception response. */
1684       send_crunch_response(csp, rsp);
1685       return TRUE;
1686    }
1687
1688    for (c = crunchers; c->cruncher != NULL; c++)
1689    {
1690       /*
1691        * Check the cruncher if either Privoxy is toggled
1692        * on and the request isn't forced, or if the cruncher
1693        * applies to forced requests as well.
1694        */
1695       if (((csp->flags & CSP_FLAG_TOGGLED_ON) &&
1696           !(csp->flags & CSP_FLAG_FORCED)) ||
1697           (c->flags & CF_IGNORE_FORCE))
1698       {
1699          rsp = c->cruncher(csp);
1700          if (NULL != rsp)
1701          {
1702             /* Deliver, log and free the interception response. */
1703             send_crunch_response(csp, rsp);
1704 #ifdef FEATURE_STATISTICS
1705             if (c->flags & CF_COUNT_AS_REJECT)
1706             {
1707                csp->flags |= CSP_FLAG_REJECTED;
1708             }
1709 #endif /* def FEATURE_STATISTICS */
1710
1711             return TRUE;
1712          }
1713       }
1714    }
1715
1716    return FALSE;
1717 }
1718
1719
1720 /*********************************************************************
1721  *
1722  * Function    :  build_request_line
1723  *
1724  * Description :  Builds the HTTP request line.
1725  *
1726  *                If a HTTP forwarder is used it expects the whole URL,
1727  *                web servers only get the path.
1728  *
1729  * Parameters  :
1730  *          1  :  csp = Current client state (buffers, headers, etc...)
1731  *          2  :  fwd = The forwarding spec used for the request
1732  *                XXX: Should use http->fwd instead.
1733  *          3  :  request_line = The old request line which will be replaced.
1734  *
1735  * Returns     :  Nothing. Terminates in case of memory problems.
1736  *
1737  *********************************************************************/
1738 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line)
1739 {
1740    struct http_request *http = csp->http;
1741
1742    assert(http->ssl == 0);
1743
1744    /*
1745     * Downgrade http version from 1.1 to 1.0
1746     * if +downgrade action applies.
1747     */
1748    if ( (csp->action->flags & ACTION_DOWNGRADE)
1749      && (!strcmpic(http->ver, "HTTP/1.1")))
1750    {
1751       freez(http->ver);
1752       http->ver = strdup("HTTP/1.0");
1753
1754       if (http->ver == NULL)
1755       {
1756          log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
1757       }
1758    }
1759
1760    /*
1761     * Rebuild the request line.
1762     */
1763    freez(*request_line);
1764    *request_line = strdup(http->gpc);
1765    string_append(request_line, " ");
1766
1767    if (fwd->forward_host)
1768    {
1769       string_append(request_line, http->url);
1770    }
1771    else
1772    {
1773       string_append(request_line, http->path);
1774    }
1775    string_append(request_line, " ");
1776    string_append(request_line, http->ver);
1777
1778    if (*request_line == NULL)
1779    {
1780       log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
1781    }
1782    log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", *request_line);
1783 }
1784
1785
1786 /*********************************************************************
1787  *
1788  * Function    :  change_request_destination
1789  *
1790  * Description :  Parse a (rewritten) request line and regenerate
1791  *                the http request data.
1792  *
1793  * Parameters  :
1794  *          1  :  csp = Current client state (buffers, headers, etc...)
1795  *
1796  * Returns     :  Forwards the parse_http_request() return code.
1797  *                Terminates in case of memory problems.
1798  *
1799  *********************************************************************/
1800 static jb_err change_request_destination(struct client_state *csp)
1801 {
1802    struct http_request *http = csp->http;
1803    jb_err err;
1804
1805    log_error(LOG_LEVEL_INFO, "Rewrite detected: %s", csp->headers->first->str);
1806    free_http_request(http);
1807    err = parse_http_request(csp->headers->first->str, http, csp);
1808    if (JB_ERR_OK != err)
1809    {
1810       log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
1811          jb_err_to_string(err));
1812    }
1813    http->ocmd = strdup(http->cmd); /* XXX: ocmd is a misleading name */
1814    if (http->ocmd == NULL)
1815    {
1816       log_error(LOG_LEVEL_FATAL, "Out of memory copying rewritten HTTP request line");
1817    }
1818
1819    return err;
1820 }
1821
1822
1823 /*********************************************************************
1824  *
1825  * Function    :  chat
1826  *
1827  * Description :  Once a connection to the client has been accepted,
1828  *                this function is called (via serve()) to handle the
1829  *                main business of the communication.  When this
1830  *                function returns, the caller must close the client
1831  *                socket handle.
1832  *
1833  *                FIXME: chat is nearly thousand lines long.
1834  *                Ridiculous.
1835  *
1836  * Parameters  :
1837  *          1  :  csp = Current client state (buffers, headers, etc...)
1838  *
1839  * Returns     :  Nothing.
1840  *
1841  *********************************************************************/
1842 static void chat(struct client_state *csp)
1843 {
1844    char buf[BUFFER_SIZE];
1845    char *hdr;
1846    char *p;
1847    char *req = NULL;
1848    fd_set rfds;
1849    int n;
1850    jb_socket maxfd;
1851    int server_body;
1852    int ms_iis5_hack = 0;
1853    size_t byte_count = 0;
1854    int forwarded_connect_retries = 0;
1855    int max_forwarded_connect_retries = csp->config->forwarded_connect_retries;
1856    const struct forward_spec * fwd;
1857    struct http_request *http;
1858    int len; /* for buffer sizes (and negative error codes) */
1859    jb_err err;
1860 #ifdef FEATURE_KILL_POPUPS
1861    int block_popups_now = 0; /* bool, 1==currently blocking popups */
1862 #endif /* def FEATURE_KILL_POPUPS */
1863
1864    /* Function that does the content filtering for the current request */
1865    filter_function_ptr content_filter = NULL;
1866
1867    /* Skeleton for HTTP response, if we should intercept the request */
1868    struct http_response *rsp;
1869
1870    /* Temporary copy of the client's headers before they get enlisted in csp->headers */
1871    struct list header_list;
1872    struct list *headers = &header_list;
1873
1874    http = csp->http;
1875
1876    memset(buf, 0, sizeof(buf));
1877
1878    /*
1879     * Read the client's request.  Note that since we're not using select() we
1880     * could get blocked here if a client connected, then didn't say anything!
1881     */
1882
1883    do
1884    {
1885       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1886
1887       if (len <= 0) break;      /* error! */
1888
1889       /*
1890        * If there is no memory left for buffering the
1891        * request, there is nothing we can do but hang up
1892        */
1893       if (add_to_iob(csp, buf, len))
1894       {
1895          return;
1896       }
1897
1898       req = get_header(csp);
1899
1900    } while ((NULL != req) && ('\0' == *req));
1901
1902    if ((NULL != req) && ('\0' != *req))
1903    {
1904       /* Request received. Validate and parse it. */
1905
1906 #if 0
1907       /*
1908        * XXX: Temporary disabled to prevent problems
1909        * with POST requests whose bodies are allowed to
1910        * contain NULL bytes. BR#1730105.
1911        *
1912        * The main purpose of this check is to properly
1913        * log stuff like BitTorrent traffic and other junk
1914        * that hits public proxies. It's not required for
1915        * Privoxy to functions as those requests are discarded
1916        * later on anyway.
1917        *
1918        * It probably should be rewritten to only check
1919        * the head of the request. Another option would
1920        * be to let all POST requests pass, although that
1921        * may not be good enough.
1922        */
1923       if (request_contains_null_bytes(csp, buf, len))
1924       {
1925          /* NULL bytes found and dealt with, just hang up. */
1926          return;
1927       }
1928 #endif
1929
1930       /* Does the request line look invalid? */
1931       if (client_protocol_is_unsupported(csp, req))
1932       {
1933          /* 
1934           * Yes. The request has already been
1935           * answered with a error response, the buffers
1936           * were freed and we're done with chatting.
1937           */
1938          return;
1939       }
1940
1941 #ifdef FEATURE_FORCE_LOAD
1942       /*
1943        * If this request contains the FORCE_PREFIX and blocks
1944        * aren't enforced, get rid of it and set the force flag.
1945        */
1946       if (strstr(req, FORCE_PREFIX))
1947       {
1948          if (csp->config->feature_flags & RUNTIME_FEATURE_ENFORCE_BLOCKS)
1949          {
1950             log_error(LOG_LEVEL_FORCE,
1951                "Ignored force prefix in request: \"%s\".", req);
1952          }
1953          else
1954          {
1955             strclean(req, FORCE_PREFIX);
1956             log_error(LOG_LEVEL_FORCE, "Enforcing request: \"%s\".", req);
1957             csp->flags |= CSP_FLAG_FORCED;
1958          }
1959       }
1960
1961 #endif /* def FEATURE_FORCE_LOAD */
1962       err = parse_http_request(req, http, csp);
1963       if (JB_ERR_OK != err)
1964       {
1965          log_error(LOG_LEVEL_ERROR, "Couldn't parse request: %s.", jb_err_to_string(err));
1966       }
1967
1968       freez(req);
1969    }
1970
1971    if (http->cmd == NULL)
1972    {
1973       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1974       /* XXX: Use correct size */
1975       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
1976       log_error(LOG_LEVEL_ERROR, "Invalid header received from %s.", csp->ip_addr_str);
1977
1978       free_http_request(http);
1979       return;
1980    }
1981
1982    /* grab the rest of the client's headers */
1983    init_list(headers);
1984    for (;;)
1985    {
1986       if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
1987       {
1988          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1989          if (len <= 0)
1990          {
1991             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
1992             return;
1993          }
1994          
1995          /*
1996           * If there is no memory left for buffering the
1997           * request, there is nothing we can do but hang up
1998           */
1999          if (add_to_iob(csp, buf, len))
2000          {
2001             return;
2002          }
2003          continue;
2004       }
2005
2006       if (p == NULL) break;
2007
2008       enlist(headers, p);
2009       freez(p);
2010
2011    }
2012
2013    if (http->host == NULL)
2014    {
2015       /*
2016        * If we still don't know the request destination,
2017        * the request is invalid or the client uses
2018        * Privoxy without its knowledge.
2019        */
2020       if (JB_ERR_OK != get_request_destination_elsewhere(csp, headers))
2021       {
2022          /*
2023           * Our attempts to get the request destination
2024           * elsewhere failed or Privoxy is configured
2025           * to only accept proxy requests.
2026           *
2027           * An error response has already been send
2028           * and we're done here.
2029           */
2030           return;
2031       }
2032    }
2033
2034    /*
2035     * Determine the actions for this URL
2036     */
2037 #ifdef FEATURE_TOGGLE
2038    if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
2039    {
2040       /* Most compatible set of actions (i.e. none) */
2041       init_current_action(csp->action);
2042    }
2043    else
2044 #endif /* ndef FEATURE_TOGGLE */
2045    {
2046       url_actions(http, csp);
2047    }
2048
2049    /* 
2050     * Save a copy of the original request for logging
2051     */
2052    http->ocmd = strdup(http->cmd);
2053
2054    if (http->ocmd == NULL)
2055    {
2056       log_error(LOG_LEVEL_FATAL, "Out of memory copying HTTP request line");
2057    }
2058
2059    enlist(csp->headers, http->cmd);
2060
2061    /* Append the previously read headers */
2062    list_append_list_unique(csp->headers, headers);
2063    destroy_list(headers);
2064
2065    err = sed(client_patterns, add_client_headers, csp);
2066    if (JB_ERR_OK != err)
2067    {
2068       assert(err == JB_ERR_PARSE);
2069       log_error(LOG_LEVEL_FATAL, "Failed to parse client headers");
2070    }
2071    csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
2072
2073    /* Check request line for rewrites. */
2074    if ((NULL == csp->headers->first->str)
2075       || (strcmp(http->cmd, csp->headers->first->str) &&
2076          (JB_ERR_OK != change_request_destination(csp))))
2077    {
2078       /*
2079        * A header filter broke the request line - bail out.
2080        */
2081       write_socket(csp->cfd, MESSED_UP_REQUEST_RESPONSE, strlen(MESSED_UP_REQUEST_RESPONSE));
2082       /* XXX: Use correct size */
2083       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request generated\" 500 0", csp->ip_addr_str);
2084       log_error(LOG_LEVEL_ERROR, "Invalid request line after applying header filters.");
2085
2086       free_http_request(http);
2087       return;
2088    }
2089
2090    /* decide how to route the HTTP request */
2091    if (NULL == (fwd = forward_url(http, csp)))
2092    {
2093       log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
2094       /* Never get here - LOG_LEVEL_FATAL causes program exit */
2095    }
2096
2097    /*
2098     * build the http request to send to the server
2099     * we have to do one of the following:
2100     *
2101     * create = use the original HTTP request to create a new
2102     *          HTTP request that has either the path component
2103     *          without the http://domainspec (w/path) or the
2104     *          full orininal URL (w/url)
2105     *          Note that the path and/or the HTTP version may
2106     *          have been altered by now.
2107     *
2108     * connect = Open a socket to the host:port of the server
2109     *           and short-circuit server and client socket.
2110     *
2111     * pass =  Pass the request unchanged if forwarding a CONNECT
2112     *         request to a parent proxy. Note that we'll be sending
2113     *         the CFAIL message ourselves if connecting to the parent
2114     *         fails, but we won't send a CSUCCEED message if it works,
2115     *         since that would result in a double message (ours and the
2116     *         parent's). After sending the request to the parent, we simply
2117     *         tunnel.
2118     *
2119     * here's the matrix:
2120     *                        SSL
2121     *                    0        1
2122     *                +--------+--------+
2123     *                |        |        |
2124     *             0  | create | connect|
2125     *                | w/path |        |
2126     *  Forwarding    +--------+--------+
2127     *                |        |        |
2128     *             1  | create | pass   |
2129     *                | w/url  |        |
2130     *                +--------+--------+
2131     *
2132     */
2133
2134    /*
2135     * Check if a CONNECT request is allowable:
2136     * In the absence of a +limit-connect action, allow only port 443.
2137     * If there is an action, allow whatever matches the specificaton.
2138     */
2139    if(http->ssl)
2140    {
2141       if(  ( !(csp->action->flags & ACTION_LIMIT_CONNECT) && csp->http->port != 443)
2142            || (csp->action->flags & ACTION_LIMIT_CONNECT
2143               && !match_portlist(csp->action->string[ACTION_STRING_LIMIT_CONNECT], csp->http->port)) )
2144       {
2145          if (csp->action->flags & ACTION_TREAT_FORBIDDEN_CONNECTS_LIKE_BLOCKS)
2146          {
2147             /*
2148              * The response may confuse some clients,
2149              * but makes unblocking easier.
2150              *
2151              * XXX: It seems to work with all major browsers,
2152              * so we should consider returning a body by default someday ... 
2153              */
2154             log_error(LOG_LEVEL_INFO, "Request from %s marked for blocking. "
2155                "limit-connect{%s} doesn't allow CONNECT requests to port %d.",
2156                csp->ip_addr_str, csp->action->string[ACTION_STRING_LIMIT_CONNECT],
2157                csp->http->port);
2158             csp->action->flags |= ACTION_BLOCK;
2159             http->ssl = 0;
2160          }
2161          else
2162          {
2163             write_socket(csp->cfd, CFORBIDDEN, strlen(CFORBIDDEN));
2164             log_error(LOG_LEVEL_INFO, "Request from %s denied. "
2165                "limit-connect{%s} doesn't allow CONNECT requests to port %d.",
2166                csp->ip_addr_str, csp->action->string[ACTION_STRING_LIMIT_CONNECT],
2167                csp->http->port);
2168             assert(NULL != csp->http->ocmd);
2169             log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 403 0", csp->ip_addr_str, csp->http->ocmd);
2170
2171             list_remove_all(csp->headers);
2172             /*
2173              * XXX: For consistency we might want to log a crunch message here.
2174              */
2175             return;
2176          }
2177       }
2178    }
2179
2180    if (http->ssl == 0)
2181    {
2182       freez(csp->headers->first->str);
2183       build_request_line(csp, fwd, &csp->headers->first->str);
2184    }
2185
2186    hdr = list_to_text(csp->headers);
2187    if (hdr == NULL)
2188    {
2189       /* FIXME Should handle error properly */
2190       log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
2191    }
2192
2193    /*
2194     * We have a request. Check if one of the crunchers wants it.
2195     */
2196    if (crunch_response_triggered(csp, crunchers_all))
2197    {
2198       /*
2199        * Yes. The client got the crunch response
2200        * and we are done here after cleaning up.
2201        */
2202       freez(hdr);
2203       list_remove_all(csp->headers);
2204
2205       return;
2206    }
2207
2208    /*
2209     * The headers can't be removed earlier because
2210     * they were still needed for the referrer check
2211     * in case of CGI crunches.
2212     *
2213     * XXX: Would it be worth to move the referrer check
2214     * into client_referrer() and set a flag if it's trusted?
2215     */
2216    list_remove_all(csp->headers);
2217
2218    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
2219
2220    if (fwd->forward_host)
2221    {
2222       log_error(LOG_LEVEL_CONNECT, "via %s:%d to: %s",
2223                fwd->forward_host, fwd->forward_port, http->hostport);
2224    }
2225    else
2226    {
2227       log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
2228    }
2229
2230    /* here we connect to the server, gateway, or the forwarder */
2231
2232    while ( (csp->sfd = forwarded_connect(fwd, http, csp))
2233          && (errno == EINVAL) && (forwarded_connect_retries++ < max_forwarded_connect_retries))
2234    {
2235       log_error(LOG_LEVEL_ERROR, "failed request #%u to connect to %s. Trying again.",
2236                 forwarded_connect_retries, http->hostport);
2237    }
2238
2239    if (csp->sfd == JB_INVALID_SOCKET)
2240    {
2241       if (fwd->type != SOCKS_NONE)
2242       {
2243          /* Socks error. */
2244          rsp = error_response(csp, "forwarding-failed", errno);
2245       }
2246       else if (errno == EINVAL)
2247       {
2248          rsp = error_response(csp, "no-such-domain", errno);
2249       }
2250       else
2251       {
2252          rsp = error_response(csp, "connect-failed", errno);
2253          log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E",
2254                 http->hostport);
2255       }
2256
2257
2258       /* Write the answer to the client */
2259       if (rsp != NULL)
2260       {
2261          send_crunch_response(csp, rsp);
2262       }
2263
2264       freez(hdr);
2265       return;
2266    }
2267
2268    if (fwd->forward_host || (http->ssl == 0))
2269    {
2270       /* write the client's (modified) header to the server
2271        * (along with anything else that may be in the buffer)
2272        */
2273
2274       if (write_socket(csp->sfd, hdr, strlen(hdr))
2275        || (flush_socket(csp->sfd, csp) <  0))
2276       {
2277          log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E",
2278                     http->hostport);
2279
2280          rsp = error_response(csp, "connect-failed", errno);
2281
2282          if(rsp)
2283          {
2284             send_crunch_response(csp, rsp);
2285          }
2286
2287          freez(hdr);
2288          return;
2289       }
2290    }
2291    else
2292    {
2293       /*
2294        * We're running an SSL tunnel and we're not forwarding,
2295        * so just send the "connect succeeded" message to the
2296        * client, flush the rest, and get out of the way.
2297        */
2298       if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
2299       {
2300          freez(hdr);
2301          return;
2302       }
2303       IOB_RESET(csp);
2304    }
2305
2306    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
2307
2308    /* we're finished with the client's header */
2309    freez(hdr);
2310
2311    maxfd = ( csp->cfd > csp->sfd ) ? csp->cfd : csp->sfd;
2312
2313    /* pass data between the client and server
2314     * until one or the other shuts down the connection.
2315     */
2316
2317    server_body = 0;
2318
2319    for (;;)
2320    {
2321 #ifdef __OS2__
2322       /*
2323        * FD_ZERO here seems to point to an errant macro which crashes.
2324        * So do this by hand for now...
2325        */
2326       memset(&rfds,0x00,sizeof(fd_set));
2327 #else
2328       FD_ZERO(&rfds);
2329 #endif
2330       FD_SET(csp->cfd, &rfds);
2331       FD_SET(csp->sfd, &rfds);
2332
2333       n = select((int)maxfd+1, &rfds, NULL, NULL, NULL);
2334
2335       if (n < 0)
2336       {
2337          log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
2338          return;
2339       }
2340
2341       /* this is the body of the browser's request
2342        * just read it and write it.
2343        */
2344
2345       if (FD_ISSET(csp->cfd, &rfds))
2346       {
2347          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
2348
2349          if (len <= 0)
2350          {
2351             break; /* "game over, man" */
2352          }
2353
2354          if (write_socket(csp->sfd, buf, (size_t)len))
2355          {
2356             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
2357             return;
2358          }
2359          continue;
2360       }
2361
2362       /*
2363        * The server wants to talk.  It could be the header or the body.
2364        * If `hdr' is null, then it's the header otherwise it's the body.
2365        * FIXME: Does `hdr' really mean `host'? No.
2366        */
2367
2368
2369       if (FD_ISSET(csp->sfd, &rfds))
2370       {
2371          fflush( 0 );
2372          len = read_socket(csp->sfd, buf, sizeof(buf) - 1);
2373
2374          if (len < 0)
2375          {
2376             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
2377
2378             if (http->ssl && (fwd->forward_host == NULL))
2379             {
2380                /*
2381                 * Just hang up. We already confirmed the client's CONNECT
2382                 * request with status code 200 and unencrypted content is
2383                 * no longer welcome.
2384                 */
2385                log_error(LOG_LEVEL_ERROR,
2386                   "CONNECT already confirmed. Unable to tell the client about the problem.");
2387                return;
2388             }
2389             else if (byte_count)
2390             {
2391                /*
2392                 * Just hang up. We already transmitted the original headers
2393                 * and parts of the original content and therefore missed the
2394                 * chance to send an error message (without risking data corruption).
2395                 *
2396                 * XXX: we could retry with a fancy range request here.
2397                 */
2398                log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
2399                   "Unable to tell the client about the problem.");
2400                return;
2401             }
2402
2403             rsp = error_response(csp, "connect-failed", errno);
2404
2405             if (rsp)
2406             {
2407                send_crunch_response(csp, rsp);
2408             }
2409
2410             return;
2411          }
2412
2413          /* Add a trailing zero.  This lets filter_popups
2414           * use string operations.
2415           */
2416          buf[len] = '\0';
2417
2418 #ifdef FEATURE_KILL_POPUPS
2419          /* Filter the popups on this read. */
2420          if (block_popups_now)
2421          {
2422             filter_popups(buf, csp);
2423          }
2424 #endif /* def FEATURE_KILL_POPUPS */
2425
2426          /* Normally, this would indicate that we've read
2427           * as much as the server has sent us and we can
2428           * close the client connection.  However, Microsoft
2429           * in its wisdom has released IIS/5 with a bug that
2430           * prevents it from sending the trailing \r\n in
2431           * a 302 redirect header (and possibly other headers).
2432           * To work around this if we've haven't parsed
2433           * a full header we'll append a trailing \r\n
2434           * and see if this now generates a valid one.
2435           *
2436           * This hack shouldn't have any impacts.  If we've
2437           * already transmitted the header or if this is a
2438           * SSL connection, then we won't bother with this
2439           * hack.  So we only work on partially received
2440           * headers.  If we append a \r\n and this still
2441           * doesn't generate a valid header, then we won't
2442           * transmit anything to the client.
2443           */
2444          if (len == 0)
2445          {
2446
2447             if (server_body || http->ssl)
2448             {
2449                /*
2450                 * If we have been buffering up the document,
2451                 * now is the time to apply content modification
2452                 * and send the result to the client.
2453                 */
2454                if (content_filter)
2455                {
2456                   p = execute_content_filter(csp, content_filter);
2457                   /*
2458                    * If the content filter fails, use the original
2459                    * buffer and length.
2460                    * (see p != NULL ? p : csp->iob->cur below)
2461                    */
2462                   if (NULL == p)
2463                   {
2464                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
2465                   }
2466
2467                   if (JB_ERR_OK != sed(server_patterns_light, NULL, csp))
2468                   {
2469                      log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
2470                   }
2471
2472                   hdr = list_to_text(csp->headers);
2473                   if (hdr == NULL)
2474                   {
2475                      /* FIXME Should handle error properly */
2476                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2477                   }
2478
2479                   /*
2480                    * Shouldn't happen because this was the second sed run
2481                    * and tags are only created for the first one.
2482                    */
2483                   assert(!crunch_response_triggered(csp, crunchers_all));
2484
2485                   if (write_socket(csp->cfd, hdr, strlen(hdr))
2486                    || write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length))
2487                   {
2488                      log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
2489                      freez(hdr);
2490                      freez(p);
2491                      return;
2492                   }
2493
2494                   freez(hdr);
2495                   freez(p);
2496                }
2497
2498                break; /* "game over, man" */
2499             }
2500
2501             /*
2502              * This is NOT the body, so
2503              * Let's pretend the server just sent us a blank line.
2504              */
2505             snprintf(buf, sizeof(buf), "\r\n");
2506             len = (int)strlen(buf);
2507
2508             /*
2509              * Now, let the normal header parsing algorithm below do its
2510              * job.  If it fails, we'll exit instead of continuing.
2511              */
2512
2513             ms_iis5_hack = 1;
2514          }
2515
2516          /*
2517           * If this is an SSL connection or we're in the body
2518           * of the server document, just write it to the client,
2519           * unless we need to buffer the body for later content-filtering
2520           */
2521
2522          if (server_body || http->ssl)
2523          {
2524             if (content_filter)
2525             {
2526                /*
2527                 * If there is no memory left for buffering the content, or the buffer limit
2528                 * has been reached, switch to non-filtering mode, i.e. make & write the
2529                 * header, flush the iob and buf, and get out of the way.
2530                 */
2531                if (add_to_iob(csp, buf, len))
2532                {
2533                   size_t hdrlen;
2534                   int flushed;
2535
2536                   log_error(LOG_LEVEL_ERROR, "Flushing header and buffers. Stepping back from filtering.");
2537
2538                   hdr = list_to_text(csp->headers);
2539                   if (hdr == NULL)
2540                   {
2541                      /* 
2542                       * Memory is too tight to even generate the header.
2543                       * Send our static "Out-of-memory" page.
2544                       */
2545                      log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
2546                      rsp = cgi_error_memory();
2547                      send_crunch_response(csp, rsp);
2548
2549                      return;
2550                   }
2551                   hdrlen = strlen(hdr);
2552
2553                   if (write_socket(csp->cfd, hdr, hdrlen)
2554                    || ((flushed = flush_socket(csp->cfd, csp)) < 0)
2555                    || (write_socket(csp->cfd, buf, (size_t)len)))
2556                   {
2557                      log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E");
2558
2559                      freez(hdr);
2560                      return;
2561                   }
2562
2563                   /*
2564                    * Reset the byte_count to the amount of bytes
2565                    * we just flushed. len will be added a few lines below,
2566                    * hdrlen doesn't matter for LOG_LEVEL_CLF.
2567                    */
2568                   byte_count = (size_t)flushed;
2569                   freez(hdr);
2570                   content_filter = NULL;
2571                   server_body = 1;
2572                }
2573             }
2574             else
2575             {
2576                if (write_socket(csp->cfd, buf, (size_t)len))
2577                {
2578                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
2579                   return;
2580                }
2581             }
2582             byte_count += (size_t)len;
2583             continue;
2584          }
2585          else
2586          {
2587             /* we're still looking for the end of the
2588              * server's header ... (does that make header
2589              * parsing an "out of body experience" ?
2590              */
2591
2592             /* 
2593              * buffer up the data we just read.  If that fails, 
2594              * there's little we can do but send our static
2595              * out-of-memory page.
2596              */
2597             if (add_to_iob(csp, buf, len))
2598             {
2599                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
2600                rsp = cgi_error_memory();
2601                send_crunch_response(csp, rsp);               
2602
2603                return;
2604             }
2605
2606             /* Convert iob into something sed() can digest */
2607             if (JB_ERR_PARSE == get_server_headers(csp))
2608             {
2609                if (ms_iis5_hack)
2610                {
2611                   /* Well, we tried our MS IIS/5
2612                    * hack and it didn't work.
2613                    * The header is incomplete
2614                    * and there isn't anything
2615                    * we can do about it.
2616                    */
2617                   break;
2618                }
2619                else
2620                {
2621                   /* Since we have to wait for
2622                    * more from the server before
2623                    * we can parse the headers
2624                    * we just continue here.
2625                    */
2626                   continue;
2627                }
2628             }
2629
2630             /* Did we actually get anything? */
2631             if (NULL == csp->headers->first)
2632             {
2633                log_error(LOG_LEVEL_ERROR, "Empty server or forwarder response.");
2634                log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2635                write_socket(csp->cfd, NO_SERVER_DATA_RESPONSE, strlen(NO_SERVER_DATA_RESPONSE));
2636                free_http_request(http);
2637                return;
2638             }
2639
2640             /* we have now received the entire header.
2641              * filter it and send the result to the client
2642              */
2643             if (JB_ERR_OK != sed(server_patterns, add_server_headers, csp))
2644             {
2645                log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
2646             }
2647             hdr = list_to_text(csp->headers);
2648             if (hdr == NULL)
2649             {
2650                /* FIXME Should handle error properly */
2651                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2652             }
2653
2654             if (crunch_response_triggered(csp, crunchers_light))
2655             {
2656                /*
2657                 * One of the tags created by a server-header
2658                 * tagger triggered a crunch. We already
2659                 * delivered the crunch response to the client
2660                 * and are done here after cleaning up.
2661                 */
2662                 freez(hdr);
2663                 return;
2664             }
2665             /* Buffer and pcrs filter this if appropriate. */
2666
2667             if (!http->ssl) /* We talk plaintext */
2668             {
2669
2670 #ifdef FEATURE_KILL_POPUPS
2671                /* Start blocking popups if appropriate. */
2672                if ((csp->content_type & CT_TEXT) &&               /* It's a text / * MIME-Type */
2673                    (csp->action->flags & ACTION_NO_POPUPS) != 0)  /* Policy allows */
2674                {
2675                   block_popups_now = 1;
2676                   /*
2677                    * Filter the part of the body that came in the same read
2678                    * as the last headers:
2679                    */
2680                   filter_popups(csp->iob->cur, csp);
2681                }
2682 #endif /* def FEATURE_KILL_POPUPS */
2683                content_filter = get_filter_function(csp);
2684             }
2685             /*
2686              * Only write if we're not buffering for content modification
2687              */
2688             if (!content_filter)
2689             {
2690                /* write the server's (modified) header to
2691                 * the client (along with anything else that
2692                 * may be in the buffer)
2693                 */
2694
2695                if (write_socket(csp->cfd, hdr, strlen(hdr))
2696                 || ((len = flush_socket(csp->cfd, csp)) < 0))
2697                {
2698                   log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
2699
2700                   /* the write failed, so don't bother
2701                    * mentioning it to the client...
2702                    * it probably can't hear us anyway.
2703                    */
2704                   freez(hdr);
2705                   return;
2706                }
2707
2708                byte_count += (size_t)len;
2709             }
2710
2711             /* we're finished with the server's header */
2712
2713             freez(hdr);
2714             server_body = 1;
2715
2716             /* If this was a MS IIS/5 hack then it means
2717              * the server has already closed the
2718              * connection.  Nothing more to read.  Time
2719              * to bail.
2720              */
2721             if (ms_iis5_hack)
2722             {
2723                break;
2724             }
2725          }
2726          continue;
2727       }
2728
2729       return; /* huh? we should never get here */
2730    }
2731
2732    if (csp->content_length == 0)
2733    {
2734       /*
2735        * If Privoxy didn't recalculate the
2736        * Content-Lenght, byte_count is still
2737        * correct.
2738        */
2739       csp->content_length = byte_count;
2740    }
2741
2742    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %d",
2743       csp->ip_addr_str, http->ocmd, csp->content_length);
2744 }
2745
2746
2747 /*********************************************************************
2748  *
2749  * Function    :  serve
2750  *
2751  * Description :  This is little more than chat.  We only "serve" to
2752  *                to close any socket that chat may have opened.
2753  *
2754  * Parameters  :
2755  *          1  :  csp = Current client state (buffers, headers, etc...)
2756  *
2757  * Returns     :  N/A
2758  *
2759  *********************************************************************/
2760 #ifdef AMIGA
2761 void serve(struct client_state *csp)
2762 #else /* ifndef AMIGA */
2763 static void serve(struct client_state *csp)
2764 #endif /* def AMIGA */
2765 {
2766    chat(csp);
2767    close_socket(csp->cfd);
2768
2769    if (csp->sfd != JB_INVALID_SOCKET)
2770    {
2771       close_socket(csp->sfd);
2772    }
2773
2774    csp->flags &= ~CSP_FLAG_ACTIVE;
2775
2776 }
2777
2778
2779 #ifdef __BEOS__
2780 /*********************************************************************
2781  *
2782  * Function    :  server_thread
2783  *
2784  * Description :  We only exist to call `serve' in a threaded environment.
2785  *
2786  * Parameters  :
2787  *          1  :  data = Current client state (buffers, headers, etc...)
2788  *
2789  * Returns     :  Always 0.
2790  *
2791  *********************************************************************/
2792 static int32 server_thread(void *data)
2793 {
2794    serve((struct client_state *) data);
2795    return 0;
2796
2797 }
2798 #endif
2799
2800
2801 #if defined(unix)
2802 /*********************************************************************
2803  *
2804  * Function    :  usage
2805  *
2806  * Description :  Print usage info & exit.
2807  *
2808  * Parameters  :  Pointer to argv[0] for identifying ourselves
2809  *
2810  * Returns     :  No. ,-)
2811  *
2812  *********************************************************************/
2813 static void usage(const char *myname)
2814 {
2815    printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
2816           "Usage: %s "
2817 #if defined(unix)
2818           "[--chroot] "
2819 #endif /* defined(unix) */
2820           "[--help] "
2821 #if defined(unix)
2822           "[--no-daemon] [--pidfile pidfile] [--pre-chroot-nslookup hostname] [--user user[.group]] "
2823 #endif /* defined(unix) */
2824           "[--version] [configfile]\n"
2825           "Aborting\n", myname);
2826
2827    exit(2);
2828
2829 }
2830 #endif /* defined(unix) */
2831
2832
2833 /*********************************************************************
2834  *
2835  * Function    :  initialize_mutexes
2836  *
2837  * Description :  Prepares mutexes if mutex support is available.
2838  *
2839  * Parameters  :  None
2840  *
2841  * Returns     :  Void, exits in case of errors.
2842  *
2843  *********************************************************************/
2844 static void initialize_mutexes(void)
2845 {
2846    int err = 0;
2847
2848 #ifdef FEATURE_PTHREAD
2849    /*
2850     * Prepare global mutex semaphores
2851     */
2852    err = pthread_mutex_init(&log_mutex, 0);
2853
2854    if (!err) err = pthread_mutex_init(&log_init_mutex, 0);
2855
2856    /*
2857     * XXX: The assumptions below are a bit naive
2858     * and can cause locks that aren't necessary.
2859     *
2860     * For example older FreeBSD versions (< 6.x?)
2861     * have no gethostbyname_r, but gethostbyname is
2862     * thread safe.
2863     */
2864 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
2865    if (!err) err = pthread_mutex_init(&resolver_mutex, 0);
2866 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
2867    /*
2868     * XXX: should we use a single mutex for
2869     * localtime() and gmtime() as well?
2870     */
2871 #ifndef HAVE_GMTIME_R
2872    if (!err) err = pthread_mutex_init(&gmtime_mutex, 0);
2873 #endif /* ndef HAVE_GMTIME_R */
2874
2875 #ifndef HAVE_LOCALTIME_R
2876    if (!err) err = pthread_mutex_init(&localtime_mutex, 0);
2877 #endif /* ndef HAVE_GMTIME_R */
2878
2879 #ifndef HAVE_RANDOM
2880    if (!err) err = pthread_mutex_init(&rand_mutex, 0);
2881 #endif /* ndef HAVE_RANDOM */
2882 #endif /* FEATURE_PTHREAD */
2883
2884    /*
2885     * TODO: mutex support for mingw32 would be swell.
2886     */
2887
2888    if (err)
2889    {
2890       printf("Fatal error. Mutex initialization failed: %s.\n",
2891          strerror(err));
2892       exit(1);
2893    }
2894
2895    return;
2896 }
2897
2898
2899 /*********************************************************************
2900  *
2901  * Function    :  main
2902  *
2903  * Description :  Load the config file and start the listen loop.
2904  *                This function is a lot more *sane* with the `load_config'
2905  *                and `listen_loop' functions; although it stills does
2906  *                a *little* too much for my taste.
2907  *
2908  * Parameters  :
2909  *          1  :  argc = Number of parameters (including $0).
2910  *          2  :  argv = Array of (char *)'s to the parameters.
2911  *
2912  * Returns     :  1 if : can't open config file, unrecognized directive,
2913  *                stats requested in multi-thread mode, can't open the
2914  *                log file, can't open the jar file, listen port is invalid,
2915  *                any load fails, and can't bind port.
2916  *
2917  *                Else main never returns, the process must be signaled
2918  *                to terminate execution.  Or, on Windows, use the
2919  *                "File", "Exit" menu option.
2920  *
2921  *********************************************************************/
2922 #ifdef __MINGW32__
2923 int real_main(int argc, const char *argv[])
2924 #else
2925 int main(int argc, const char *argv[])
2926 #endif
2927 {
2928    int argc_pos = 0;
2929    unsigned int random_seed;
2930 #ifdef unix
2931    struct passwd *pw = NULL;
2932    struct group *grp = NULL;
2933    char *p;
2934    int do_chroot = 0;
2935    char *pre_chroot_nslookup_to_load_resolver = NULL;
2936 #endif
2937
2938    Argc = argc;
2939    Argv = argv;
2940
2941    configfile =
2942 #if !defined(_WIN32)
2943    "config"
2944 #else
2945    "config.txt"
2946 #endif
2947       ;
2948
2949    init_log_module(Argv[0]);
2950
2951    /*
2952     * Parse the command line arguments
2953     *
2954     * XXX: simply printing usage information in case of
2955     * invalid arguments isn't particular user friendly.
2956     */
2957    while (++argc_pos < argc)
2958    {
2959 #ifdef _WIN32
2960       /* Check to see if the service must be installed or uninstalled */
2961       if (strncmp(argv[argc_pos], "--install", 9) == 0)
2962       {
2963          const char *pName = argv[argc_pos] + 9;
2964          if (*pName == ':')
2965             pName++;
2966          exit( (install_service(pName)) ? 0 : 1 );
2967       }
2968       else if (strncmp(argv[argc_pos], "--uninstall", + 11) == 0)
2969       {
2970          const char *pName = argv[argc_pos] + 11;
2971          if (*pName == ':')
2972             pName++;
2973          exit((uninstall_service(pName)) ? 0 : 1);
2974       }
2975       else if (strcmp(argv[argc_pos], "--service" ) == 0)
2976       {
2977          bRunAsService = TRUE;
2978          w32_set_service_cwd();
2979          atexit(w32_service_exit_notify);
2980       }
2981       else
2982 #endif /* defined(_WIN32) */
2983
2984
2985 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
2986
2987       if (strcmp(argv[argc_pos], "--help") == 0)
2988       {
2989          usage(argv[0]);
2990       }
2991
2992       else if(strcmp(argv[argc_pos], "--version") == 0)
2993       {
2994          printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
2995          exit(0);
2996       }
2997
2998 #if defined(unix)
2999
3000       else if (strcmp(argv[argc_pos], "--no-daemon" ) == 0)
3001       {
3002          no_daemon = 1;
3003       }
3004
3005       else if (strcmp(argv[argc_pos], "--pidfile" ) == 0)
3006       {
3007          if (++argc_pos == argc) usage(argv[0]);
3008          pidfile = strdup(argv[argc_pos]);
3009       }
3010
3011       else if (strcmp(argv[argc_pos], "--user" ) == 0)
3012       {
3013          if (++argc_pos == argc) usage(argv[argc_pos]);
3014
3015          if ((NULL != (p = strchr(argv[argc_pos], '.'))) && *(p + 1) != '0')
3016          {
3017             *p++ = '\0';
3018             if (NULL == (grp = getgrnam(p)))
3019             {
3020                log_error(LOG_LEVEL_FATAL, "Group %s not found.", p);
3021             }
3022          }
3023
3024          if (NULL == (pw = getpwnam(argv[argc_pos])))
3025          {
3026             log_error(LOG_LEVEL_FATAL, "User %s not found.", argv[argc_pos]);
3027          }
3028
3029          if (p != NULL) *--p = '\0';
3030       }
3031
3032       else if (strcmp(argv[argc_pos], "--pre-chroot-nslookup" ) == 0)
3033       {
3034          if (++argc_pos == argc) usage(argv[0]);
3035          pre_chroot_nslookup_to_load_resolver = strdup(argv[argc_pos]);
3036       }
3037
3038       else if (strcmp(argv[argc_pos], "--chroot" ) == 0)
3039       {
3040          do_chroot = 1;
3041       }
3042 #endif /* defined(unix) */
3043
3044       else if (argc_pos + 1 != argc)
3045       {
3046          /*
3047           * This is neither the last command line
3048           * option, nor was it recognized before,
3049           * therefore it must be invalid.
3050           */
3051          usage(argv[0]);
3052       }
3053       else
3054
3055 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
3056       {
3057          configfile = argv[argc_pos];
3058       }
3059
3060    } /* -END- while (more arguments) */
3061
3062 #if defined(unix)
3063    if ( *configfile != '/' )
3064    {
3065       char cwd[BUFFER_SIZE];
3066       char *abs_file;
3067       size_t abs_file_size; 
3068
3069       /* make config-filename absolute here */
3070       if (NULL == getcwd(cwd, sizeof(cwd)))
3071       {
3072          perror("failed to get current working directory");
3073          exit( 1 );
3074       }
3075
3076       /* XXX: why + 5? */
3077       abs_file_size = strlen(cwd) + strlen(configfile) + 5;
3078       basedir = strdup(cwd);
3079
3080       if (NULL == basedir ||
3081           NULL == (abs_file = malloc(abs_file_size)))
3082       {
3083          perror("malloc failed");
3084          exit( 1 );
3085       }
3086       strlcpy(abs_file, basedir, abs_file_size);
3087       strlcat(abs_file, "/", abs_file_size );
3088       strlcat(abs_file, configfile, abs_file_size);
3089       configfile = abs_file;
3090    }
3091 #endif /* defined unix */
3092
3093
3094    files->next = NULL;
3095    clients->next = NULL;
3096
3097 #ifdef AMIGA
3098    InitAmiga();
3099 #elif defined(_WIN32)
3100    InitWin32();
3101 #endif
3102
3103    /* Prepare mutexes if supported and necessary. */
3104    initialize_mutexes();
3105
3106    random_seed = (unsigned int)time(NULL);
3107 #ifdef HAVE_RANDOM
3108    srandom(random_seed);
3109 #else
3110    srand(random_seed);
3111 #endif /* ifdef HAVE_RANDOM */
3112
3113    /*
3114     * Unix signal handling
3115     *
3116     * Catch the abort, interrupt and terminate signals for a graceful exit
3117     * Catch the hangup signal so the errlog can be reopened.
3118     * Ignore the broken pipe signals (FIXME: Why?)
3119     */
3120 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
3121 {
3122    int idx;
3123    const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP, 0 };
3124    const int ignored_signals[] = { SIGPIPE, 0 };
3125
3126    for (idx = 0; catched_signals[idx] != 0; idx++)
3127    {
3128 #ifdef sun /* FIXME: Is it safe to check for HAVE_SIGSET instead? */ 
3129       if (sigset(catched_signals[idx], sig_handler) == SIG_ERR)
3130 #else
3131       if (signal(catched_signals[idx], sig_handler) == SIG_ERR)
3132 #endif /* ifdef sun */
3133       {
3134          log_error(LOG_LEVEL_FATAL, "Can't set signal-handler for signal %d: %E", catched_signals[idx]);
3135       }
3136    }
3137
3138    for (idx = 0; ignored_signals[idx] != 0; idx++)
3139    {
3140       if (signal(ignored_signals[idx], SIG_IGN) == SIG_ERR)
3141       {
3142          log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for signal %d: %E", ignored_signals[idx]);
3143       }
3144    }
3145
3146 }
3147 #else /* ifdef _WIN32 */
3148 # ifdef _WIN_CONSOLE
3149    /*
3150     * We *are* in a windows console app.
3151     * Print a verbose messages about FAQ's and such
3152     */
3153    printf("%s", win32_blurb);
3154 # endif /* def _WIN_CONSOLE */
3155 #endif /* def _WIN32 */
3156
3157
3158    /* Initialize the CGI subsystem */
3159    cgi_init_error_messages();
3160
3161    /*
3162     * If runnig on unix and without the --nodaemon
3163     * option, become a daemon. I.e. fork, detach
3164     * from tty and get process group leadership
3165     */
3166 #if defined(unix)
3167 {
3168    pid_t pid = 0;
3169 #if 0
3170    int   fd;
3171 #endif
3172
3173    if (!no_daemon)
3174    {
3175       pid  = fork();
3176
3177       if ( pid < 0 ) /* error */
3178       {
3179          perror("fork");
3180          exit( 3 );
3181       }
3182       else if ( pid != 0 ) /* parent */
3183       {
3184          int status;
3185          pid_t wpid;
3186          /*
3187           * must check for errors
3188           * child died due to missing files aso
3189           */
3190          sleep( 1 );
3191          wpid = waitpid( pid, &status, WNOHANG );
3192          if ( wpid != 0 )
3193          {
3194             exit( 1 );
3195          }
3196          exit( 0 );
3197       }
3198       /* child */
3199 #if 1
3200       /* Should be more portable, but not as well tested */
3201       setsid();
3202 #else /* !1 */
3203 #ifdef __FreeBSD__
3204       setpgrp(0,0);
3205 #else /* ndef __FreeBSD__ */
3206       setpgrp();
3207 #endif /* ndef __FreeBSD__ */
3208       fd = open("/dev/tty", O_RDONLY);
3209       if ( fd )
3210       {
3211          /* no error check here */
3212          ioctl( fd, TIOCNOTTY,0 );
3213          close ( fd );
3214       }
3215 #endif /* 1 */
3216       /*
3217        * stderr (fd 2) will be closed later on, when the
3218        * log file has been parsed.
3219        */
3220
3221       close( 0 );
3222       close( 1 );
3223       chdir("/");
3224
3225    } /* -END- if (!no_daemon) */
3226
3227    /*
3228     * As soon as we have written the PID file, we can switch
3229     * to the user and group ID indicated by the --user option
3230     */
3231    write_pid_file();
3232
3233    if (NULL != pw)
3234    {
3235       if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid))
3236       {
3237          log_error(LOG_LEVEL_FATAL, "Cannot setgid(): Insufficient permissions.");
3238       }
3239       if (do_chroot)
3240       {
3241          if (!pw->pw_dir)
3242          {
3243             log_error(LOG_LEVEL_FATAL, "Home directory for %s undefined", pw->pw_name);
3244          }
3245          /* Read the time zone file from /etc before doing chroot. */
3246          tzset();
3247          if (NULL != pre_chroot_nslookup_to_load_resolver
3248              && '\0' != pre_chroot_nslookup_to_load_resolver[0])
3249          {
3250             /* Initialize resolver library. */
3251             (void) resolve_hostname_to_ip(pre_chroot_nslookup_to_load_resolver);
3252          }
3253          if (chroot(pw->pw_dir) < 0)
3254          {
3255             log_error(LOG_LEVEL_FATAL, "Cannot chroot to %s", pw->pw_dir);
3256          }
3257          if (chdir ("/"))
3258          {
3259             log_error(LOG_LEVEL_FATAL, "Cannot chdir /");
3260          }
3261       }
3262       if (setuid(pw->pw_uid))
3263       {
3264          log_error(LOG_LEVEL_FATAL, "Cannot setuid(): Insufficient permissions.");
3265       }
3266       if (do_chroot)
3267       {
3268          char putenv_dummy[64];
3269
3270          strlcpy(putenv_dummy, "HOME=/", sizeof(putenv_dummy));
3271          if (putenv(putenv_dummy) != 0)
3272          {
3273             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): HOME");
3274          }                
3275
3276          snprintf(putenv_dummy, sizeof(putenv_dummy), "USER=%s", pw->pw_name);
3277          if (putenv(putenv_dummy) != 0)
3278          {
3279             log_error(LOG_LEVEL_FATAL, "Cannot putenv(): USER");
3280          }
3281       }
3282    }
3283    else if (do_chroot)
3284    {
3285       log_error(LOG_LEVEL_FATAL, "Cannot chroot without --user argument.");
3286    }
3287 }
3288 #endif /* defined unix */
3289
3290 #ifdef _WIN32
3291    /* This will be FALSE unless the command line specified --service
3292     */
3293    if (bRunAsService)
3294    {
3295       /* Yup, so now we must attempt to establish a connection 
3296        * with the service dispatcher. This will only work if this
3297        * process was launched by the service control manager to
3298        * actually run as a service. If this isn't the case, i've
3299        * known it take around 30 seconds or so for the call to return.
3300        */
3301
3302       /* The StartServiceCtrlDispatcher won't return until the service is stopping */
3303       if (w32_start_service_ctrl_dispatcher(w32ServiceDispatchTable))
3304       {
3305          /* Service has run, and at this point is now being stopped, so just return */
3306          return 0;
3307       }
3308
3309 #ifdef _WIN_CONSOLE
3310       printf("Warning: Failed to connect to Service Control Dispatcher\nwhen starting as a service!\n");
3311 #endif
3312       /* An error occurred. Usually it's because --service was wrongly specified
3313        * and we were unable to connect to the Service Control Dispatcher because
3314        * it wasn't expecting us and is therefore not listening.
3315        *
3316        * For now, just continue below to call the listen_loop function.
3317        */
3318    }
3319 #endif /* def _WIN32 */
3320
3321    listen_loop();
3322
3323    /* NOTREACHED */
3324    return(-1);
3325
3326 }
3327
3328
3329 /*********************************************************************
3330  *
3331  * Function    :  bind_port_helper
3332  *
3333  * Description :  Bind the listen port.  Handles logging, and aborts
3334  *                on failure.
3335  *
3336  * Parameters  :
3337  *          1  :  config = Privoxy configuration.  Specifies port
3338  *                         to bind to.
3339  *
3340  * Returns     :  Port that was opened.
3341  *
3342  *********************************************************************/
3343 static jb_socket bind_port_helper(struct configuration_spec * config)
3344 {
3345    int result;
3346    jb_socket bfd;
3347
3348    if ( (config->haddr != NULL)
3349      && (config->haddr[0] == '1')
3350      && (config->haddr[1] == '2')
3351      && (config->haddr[2] == '7')
3352      && (config->haddr[3] == '.') )
3353    {
3354       log_error(LOG_LEVEL_INFO, "Listening on port %d for local connections only",
3355                 config->hport);
3356    }
3357    else if (config->haddr == NULL)
3358    {
3359       log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
3360                 config->hport);
3361    }
3362    else
3363    {
3364       log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
3365                 config->hport, config->haddr);
3366    }
3367
3368    result = bind_port(config->haddr, config->hport, &bfd);
3369
3370    if (result < 0)
3371    {
3372       switch(result)
3373       {
3374          case -3 :
3375             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: "
3376                "There may be another Privoxy or some other "
3377                "proxy running on port %d",
3378                (NULL != config->haddr) ? config->haddr : "INADDR_ANY",
3379                       config->hport, config->hport);
3380
3381          case -2 :
3382             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: " 
3383                "The hostname is not resolvable",
3384                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
3385
3386          default :
3387             log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E",
3388                (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
3389       }
3390
3391       /* shouldn't get here */
3392       return JB_INVALID_SOCKET;
3393    }
3394
3395    config->need_bind = 0;
3396
3397    return bfd;
3398 }
3399
3400
3401 #ifdef _WIN32
3402 /* Without this simple workaround we get this compiler warning from _beginthread
3403  *     warning C4028: formal parameter 1 different from declaration
3404  */
3405 void w32_service_listen_loop(void *p)
3406 {
3407    listen_loop();
3408 }
3409 #endif /* def _WIN32 */
3410
3411
3412 /*********************************************************************
3413  *
3414  * Function    :  listen_loop
3415  *
3416  * Description :  bind the listen port and enter a "FOREVER" listening loop.
3417  *
3418  * Parameters  :  N/A
3419  *
3420  * Returns     :  Never.
3421  *
3422  *********************************************************************/
3423 static void listen_loop(void)
3424 {
3425    struct client_state *csp = NULL;
3426    jb_socket bfd;
3427    struct configuration_spec * config;
3428
3429    config = load_config();
3430
3431    bfd = bind_port_helper(config);
3432
3433 #ifdef FEATURE_GRACEFUL_TERMINATION
3434    while (!g_terminate)
3435 #else
3436    for (;;)
3437 #endif
3438    {
3439 #if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
3440       while (waitpid(-1, NULL, WNOHANG) > 0)
3441       {
3442          /* zombie children */
3443       }
3444 #endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
3445
3446       /*
3447        * Free data that was used by died threads
3448        */
3449       sweep();
3450
3451 #if defined(unix)
3452       /*
3453        * Re-open the errlog after HUP signal
3454        */
3455       if (received_hup_signal)
3456       {
3457          init_error_log(Argv[0], config->logfile);
3458          received_hup_signal = 0;
3459       }
3460 #endif
3461
3462 #ifdef __OS2__
3463 #ifdef FEATURE_COOKIE_JAR
3464       /*
3465        * Need a workaround here: we have to fclose() the jarfile, or we die because it's
3466        * already open.  I think unload_configfile() is not being run, which should do
3467        * this work.  Until that can get resolved, we'll use this workaround.
3468        */
3469        if (csp)
3470          if(csp->config)
3471            if (csp->config->jar)
3472            {
3473              fclose(csp->config->jar);
3474              csp->config->jar = NULL;
3475            }
3476 #endif /* FEATURE_COOKIE_JAR */
3477 #endif /* __OS2__ */
3478
3479       if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
3480       {
3481          log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
3482          continue;
3483       }
3484
3485       csp->flags |= CSP_FLAG_ACTIVE;
3486       csp->sfd    = JB_INVALID_SOCKET;
3487
3488       csp->config = config = load_config();
3489
3490       if ( config->need_bind )
3491       {
3492          /*
3493           * Since we were listening to the "old port", we will not see
3494           * a "listen" param change until the next IJB request.  So, at
3495           * least 1 more request must be made for us to find the new
3496           * setting.  I am simply closing the old socket and binding the
3497           * new one.
3498           *
3499           * Which-ever is correct, we will serve 1 more page via the
3500           * old settings.  This should probably be a "show-proxy-args"
3501           * request.  This should not be a so common of an operation
3502           * that this will hurt people's feelings.
3503           */
3504
3505          close_socket(bfd);
3506
3507          bfd = bind_port_helper(config);
3508       }
3509
3510       log_error(LOG_LEVEL_CONNECT, "Listening for new connections ... ");
3511
3512       if (!accept_connection(csp, bfd))
3513       {
3514          log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
3515
3516 #ifdef AMIGA
3517          if(!childs)
3518          {
3519             exit(1);
3520          }
3521 #endif
3522          freez(csp);
3523          continue;
3524       }
3525       else
3526       {
3527          log_error(LOG_LEVEL_CONNECT, "accepted connection from %s", csp->ip_addr_str);
3528       }
3529
3530 #ifdef FEATURE_TOGGLE
3531       if (global_toggle_state)
3532       {
3533          csp->flags |= CSP_FLAG_TOGGLED_ON;
3534       }
3535 #endif /* def FEATURE_TOGGLE */
3536
3537       if (run_loader(csp))
3538       {
3539          log_error(LOG_LEVEL_FATAL, "a loader failed - must exit");
3540          /* Never get here - LOG_LEVEL_FATAL causes program exit */
3541       }
3542
3543 #ifdef FEATURE_ACL
3544       if (block_acl(NULL,csp))
3545       {
3546          log_error(LOG_LEVEL_CONNECT, "Connection from %s dropped due to ACL", csp->ip_addr_str);
3547          close_socket(csp->cfd);
3548          freez(csp);
3549          continue;
3550       }
3551 #endif /* def FEATURE_ACL */
3552
3553       /* add it to the list of clients */
3554       csp->next = clients->next;
3555       clients->next = csp;
3556
3557       if (config->multi_threaded)
3558       {
3559          int child_id;
3560
3561 /* this is a switch () statment in the C preprocessor - ugh */
3562 #undef SELECTED_ONE_OPTION
3563
3564 /* Use Pthreads in preference to native code */
3565 #if defined(FEATURE_PTHREAD) && !defined(SELECTED_ONE_OPTION)
3566 #define SELECTED_ONE_OPTION
3567          {
3568             pthread_t the_thread;
3569             pthread_attr_t attrs;
3570
3571             pthread_attr_init(&attrs);
3572             pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
3573             errno = pthread_create(&the_thread, &attrs,
3574                (void * (*)(void *))serve, csp);
3575             child_id = errno ? -1 : 0;
3576             pthread_attr_destroy(&attrs);
3577          }
3578 #endif
3579
3580 #if defined(_WIN32) && !defined(_CYGWIN) && !defined(SELECTED_ONE_OPTION)
3581 #define SELECTED_ONE_OPTION
3582          child_id = _beginthread(
3583             (void (*)(void *))serve,
3584             64 * 1024,
3585             csp);
3586 #endif
3587
3588 #if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
3589 #define SELECTED_ONE_OPTION
3590          child_id = _beginthread(
3591             (void(* _Optlink)(void*))serve,
3592             NULL,
3593             64 * 1024,
3594             csp);
3595 #endif
3596
3597 #if defined(__BEOS__) && !defined(SELECTED_ONE_OPTION)
3598 #define SELECTED_ONE_OPTION
3599          {
3600             thread_id tid = spawn_thread
3601                (server_thread, "server", B_NORMAL_PRIORITY, csp);
3602
3603             if ((tid >= 0) && (resume_thread(tid) == B_OK))
3604             {
3605                child_id = (int) tid;
3606             }
3607             else
3608             {
3609                child_id = -1;
3610             }
3611          }
3612 #endif
3613
3614 #if defined(AMIGA) && !defined(SELECTED_ONE_OPTION)
3615 #define SELECTED_ONE_OPTION
3616          csp->cfd = ReleaseSocket(csp->cfd, -1);
3617          
3618 #ifdef __amigaos4__
3619          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
3620                                            NP_Output, Output(),
3621                                            NP_CloseOutput, FALSE,
3622                                            NP_Name, (ULONG)"privoxy child",
3623                                            NP_Child, TRUE,
3624                                            TAG_DONE);
3625 #else
3626          child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread,
3627                                            NP_Output, Output(),
3628                                            NP_CloseOutput, FALSE,
3629                                            NP_Name, (ULONG)"privoxy child",
3630                                            NP_StackSize, 200*1024,
3631                                            TAG_DONE);
3632 #endif
3633          if(0 != child_id)
3634          {
3635             childs++;
3636             ((struct Task *)child_id)->tc_UserData = csp;
3637             Signal((struct Task *)child_id, SIGF_SINGLE);
3638             Wait(SIGF_SINGLE);
3639          }
3640 #endif
3641
3642 #if !defined(SELECTED_ONE_OPTION)
3643          child_id = fork();
3644
3645          /* This block is only needed when using fork().
3646           * When using threads, the server thread was
3647           * created and run by the call to _beginthread().
3648           */
3649          if (child_id == 0)   /* child */
3650          {
3651             int rc = 0;
3652 #ifdef FEATURE_TOGGLE
3653             int inherited_toggle_state = global_toggle_state;
3654 #endif /* def FEATURE_TOGGLE */
3655
3656             serve(csp);
3657
3658             /* 
3659              * If we've been toggled or we've blocked the request, tell Mom
3660              */
3661
3662 #ifdef FEATURE_TOGGLE
3663             if (inherited_toggle_state != global_toggle_state)
3664             {
3665                rc |= RC_FLAG_TOGGLED;
3666             }
3667 #endif /* def FEATURE_TOGGLE */
3668
3669 #ifdef FEATURE_STATISTICS  
3670             if (csp->flags & CSP_FLAG_REJECTED)
3671             {
3672                rc |= RC_FLAG_BLOCKED;
3673             }
3674 #endif /* ndef FEATURE_STATISTICS */
3675
3676             _exit(rc);
3677          }
3678          else if (child_id > 0) /* parent */
3679          {
3680             /* in a fork()'d environment, the parent's
3681              * copy of the client socket and the CSP
3682              * are not used.
3683              */
3684             int child_status;
3685 #if !defined(_WIN32) && !defined(__CYGWIN__)
3686
3687             wait( &child_status );
3688
3689             /* 
3690              * Evaluate child's return code: If the child has
3691              *  - been toggled, toggle ourselves
3692              *  - blocked its request, bump up the stats counter
3693              */
3694
3695 #ifdef FEATURE_TOGGLE
3696             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_TOGGLED))
3697             {
3698                global_toggle_state = !global_toggle_state;
3699             }
3700 #endif /* def FEATURE_TOGGLE */
3701
3702 #ifdef FEATURE_STATISTICS
3703             urls_read++;
3704             if (WIFEXITED(child_status) && (WEXITSTATUS(child_status) & RC_FLAG_BLOCKED))
3705             {
3706                urls_rejected++;
3707             }
3708 #endif /* def FEATURE_STATISTICS */ 
3709
3710 #endif /* !defined(_WIN32) && defined(__CYGWIN__) */
3711             close_socket(csp->cfd);
3712             csp->flags &= ~CSP_FLAG_ACTIVE;
3713          }
3714 #endif
3715
3716 #undef SELECTED_ONE_OPTION
3717 /* end of cpp switch () */
3718
3719          if (child_id < 0) /* failed */
3720          {
3721             char buf[BUFFER_SIZE];
3722
3723             log_error(LOG_LEVEL_ERROR, "can't fork: %E");
3724
3725             snprintf(buf , sizeof(buf), "Privoxy: can't fork: errno = %d", errno);
3726
3727             write_socket(csp->cfd, buf, strlen(buf));
3728             close_socket(csp->cfd);
3729             csp->flags &= ~CSP_FLAG_ACTIVE;
3730             sleep(5);
3731             continue;
3732          }
3733       }
3734       else
3735       {
3736          serve(csp);
3737       }
3738    }
3739
3740    /* NOTREACHED unless FEATURE_GRACEFUL_TERMINATION is defined */
3741
3742    /* Clean up.  Aim: free all memory (no leaks) */
3743 #ifdef FEATURE_GRACEFUL_TERMINATION
3744
3745    log_error(LOG_LEVEL_ERROR, "Graceful termination requested");
3746
3747    unload_current_config_file();
3748    unload_current_actions_file();
3749    unload_current_re_filterfile();
3750 #ifdef FEATURE_TRUST
3751    unload_current_trust_file();
3752 #endif
3753
3754    if (config->multi_threaded)
3755    {
3756       int i = 60;
3757       do
3758       {
3759          sleep(1);
3760          sweep();
3761       } while ((clients->next != NULL) && (--i > 0));
3762
3763       if (i <= 0)
3764       {
3765          log_error(LOG_LEVEL_ERROR, "Graceful termination failed - still some live clients after 1 minute wait.");
3766       }
3767    }
3768    sweep();
3769    sweep();
3770
3771 #if defined(unix)
3772    freez(basedir);
3773 #endif
3774    freez(configfile);
3775
3776 #ifdef FEATURE_COOKIE_JAR
3777    if (NULL != config->jar)
3778    {
3779       fclose(config->jar);
3780    }
3781 #endif
3782
3783 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
3784    /* Cleanup - remove taskbar icon etc. */
3785    TermLogWindow();
3786 #endif
3787
3788    exit(0);
3789 #endif /* FEATURE_GRACEFUL_TERMINATION */
3790
3791 }
3792
3793
3794 /*
3795   Local Variables:
3796   tab-width: 3
3797   end:
3798 */