get rid of a compiler warning
[privoxy.git] / jcc.c
1 /*********************************************************************
2  *
3  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
4  *
5  * Purpose     :  Main file.  Contains main() method, main loop, and
6  *                the main connection-handling function.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001-2017 the
9  *                Privoxy team. http://www.privoxy.org/
10  *
11  *                Based on the Internet Junkbuster originally written
12  *                by and Copyright (C) 1997 Anonymous Coders and
13  *                Junkbusters Corporation.  http://www.junkbusters.com
14  *
15  *                This program is free software; you can redistribute it
16  *                and/or modify it under the terms of the GNU General
17  *                Public License as published by the Free Software
18  *                Foundation; either version 2 of the License, or (at
19  *                your option) any later version.
20  *
21  *                This program is distributed in the hope that it will
22  *                be useful, but WITHOUT ANY WARRANTY; without even the
23  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
24  *                PARTICULAR PURPOSE.  See the GNU General Public
25  *                License for more details.
26  *
27  *                The GNU General Public License should be included with
28  *                this file.  If not, you can view it at
29  *                http://www.gnu.org/copyleft/gpl.html
30  *                or write to the Free Software Foundation, Inc., 59
31  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  *
33  *********************************************************************/
34
35
36 #include "config.h"
37
38 #include <stdio.h>
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <assert.h>
46
47 #ifdef _WIN32
48 # ifndef FEATURE_PTHREAD
49 #  ifndef STRICT
50 #   define STRICT
51 #  endif
52 #  include <winsock2.h>
53 #  include <windows.h>
54 #  include <process.h>
55 # endif /* ndef FEATURE_PTHREAD */
56
57 # include "win32.h"
58 # ifndef _WIN_CONSOLE
59 #  include "w32log.h"
60 # endif /* ndef _WIN_CONSOLE */
61 # include "w32svrapi.h"
62
63 #else /* ifndef _WIN32 */
64
65 # if !defined (__OS2__)
66 # include <unistd.h>
67 # include <sys/wait.h>
68 # endif /* ndef __OS2__ */
69 # include <sys/time.h>
70 # include <sys/stat.h>
71 # include <sys/ioctl.h>
72
73 #ifdef sun
74 #include <sys/termios.h>
75 #endif /* sun */
76
77 #ifdef unix
78 #include <pwd.h>
79 #include <grp.h>
80 #endif
81
82 # include <signal.h>
83
84 # ifdef __BEOS__
85 #  include <socket.h>  /* BeOS has select() for sockets only. */
86 #  include <OS.h>      /* declarations for threads and stuff. */
87 # endif
88
89 # if defined(__EMX__) || defined(__OS2__)
90 #  include <sys/select.h>  /* OS/2/EMX needs a little help with select */
91 # endif
92 # ifdef __OS2__
93 #define INCL_DOS
94 # include <os2.h>
95 # endif
96
97 #ifdef HAVE_POLL
98 #ifdef __GLIBC__
99 #include <sys/poll.h>
100 #else
101 #include <poll.h>
102 #endif /* def __GLIBC__ */
103 #else
104 # ifndef FD_ZERO
105 #  include <select.h>
106 # endif
107 #warning poll() appears to be unavailable. Your platform will become unsupported in the future.
108 #endif /* HAVE_POLL */
109
110 #endif
111
112 #include "project.h"
113 #include "list.h"
114 #include "jcc.h"
115 #include "filters.h"
116 #include "loaders.h"
117 #include "parsers.h"
118 #include "miscutil.h"
119 #include "errlog.h"
120 #include "jbsockets.h"
121 #include "gateway.h"
122 #include "actions.h"
123 #include "cgi.h"
124 #include "loadcfg.h"
125 #include "urlmatch.h"
126 #ifdef FEATURE_CLIENT_TAGS
127 #include "client-tags.h"
128 #endif
129
130 int daemon_mode = 1;
131 struct client_states clients[1];
132 struct file_list     files[1];
133
134 #ifdef FEATURE_STATISTICS
135 int urls_read     = 0;     /* total nr of urls read inc rejected */
136 int urls_rejected = 0;     /* total nr of urls rejected */
137 #endif /* def FEATURE_STATISTICS */
138
139 #ifdef FEATURE_GRACEFUL_TERMINATION
140 int g_terminate = 0;
141 #endif
142
143 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
144 static void sig_handler(int the_signal);
145 #endif
146 static int client_protocol_is_unsupported(const struct client_state *csp, char *req);
147 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
148 static jb_err get_server_headers(struct client_state *csp);
149 static const char *crunch_reason(const struct http_response *rsp);
150 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
151 static char *get_request_line(struct client_state *csp);
152 static jb_err receive_client_request(struct client_state *csp);
153 static jb_err parse_client_request(struct client_state *csp);
154 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line);
155 static jb_err change_request_destination(struct client_state *csp);
156 static void chat(struct client_state *csp);
157 static void serve(struct client_state *csp);
158 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
159 static void usage(const char *myname);
160 #endif
161 static void initialize_mutexes(void);
162 static jb_socket bind_port_helper(const char *haddr, int hport, int backlog);
163 static void bind_ports_helper(struct configuration_spec *config, jb_socket sockets[]);
164 static void close_ports_helper(jb_socket sockets[]);
165 static void listen_loop(void);
166
167 #ifdef AMIGA
168 void serve(struct client_state *csp);
169 #else /* ifndef AMIGA */
170 static void serve(struct client_state *csp);
171 #endif /* def AMIGA */
172
173 #ifdef __BEOS__
174 static int32 server_thread(void *data);
175 #endif /* def __BEOS__ */
176
177 #ifdef _WIN32
178 #define sleep(N)  Sleep(((N) * 1000))
179 #endif
180
181 #ifdef __OS2__
182 #define sleep(N)  DosSleep(((N) * 100))
183 #endif
184
185 #ifdef FUZZ
186 int process_fuzzed_input(char *fuzz_input_type, char *fuzz_input_file);
187 void show_fuzz_usage(const char *name);
188 #endif
189
190 #ifdef MUTEX_LOCKS_AVAILABLE
191 /*
192  * XXX: Does the locking stuff really belong in this file?
193  */
194 privoxy_mutex_t log_mutex;
195 privoxy_mutex_t log_init_mutex;
196 privoxy_mutex_t connection_reuse_mutex;
197
198 #ifdef FEATURE_EXTERNAL_FILTERS
199 privoxy_mutex_t external_filter_mutex;
200 #endif
201 #ifdef FEATURE_CLIENT_TAGS
202 privoxy_mutex_t client_tags_mutex;
203 #endif
204
205 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
206 privoxy_mutex_t resolver_mutex;
207 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
208
209 #ifndef HAVE_GMTIME_R
210 privoxy_mutex_t gmtime_mutex;
211 #endif /* ndef HAVE_GMTIME_R */
212
213 #ifndef HAVE_LOCALTIME_R
214 privoxy_mutex_t localtime_mutex;
215 #endif /* ndef HAVE_GMTIME_R */
216
217 #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_RANDOM)
218 privoxy_mutex_t rand_mutex;
219 #endif /* !defined(HAVE_ARC4RANDOM) && !defined(HAVE_RANDOM) */
220
221 #endif /* def MUTEX_LOCKS_AVAILABLE */
222
223 #if defined(unix)
224 const char *basedir = NULL;
225 const char *pidfile = NULL;
226 static int received_hup_signal = 0;
227 #endif /* defined unix */
228
229 /* HTTP snipplets. */
230 static const char CSUCCEED[] =
231    "HTTP/1.1 200 Connection established\r\n\r\n";
232
233 static const char CHEADER[] =
234    "HTTP/1.1 400 Invalid header received from client\r\n"
235    "Content-Type: text/plain\r\n"
236    "Connection: close\r\n\r\n"
237    "Invalid header received from client.\r\n";
238
239 static const char FTP_RESPONSE[] =
240    "HTTP/1.1 400 Invalid request received from client\r\n"
241    "Content-Type: text/plain\r\n"
242    "Connection: close\r\n\r\n"
243    "Invalid request. Privoxy doesn't support FTP.\r\n";
244
245 static const char GOPHER_RESPONSE[] =
246    "HTTP/1.1 400 Invalid request received from client\r\n"
247    "Content-Type: text/plain\r\n"
248    "Connection: close\r\n\r\n"
249    "Invalid request. Privoxy doesn't support gopher.\r\n";
250
251 /* XXX: should be a template */
252 static const char MISSING_DESTINATION_RESPONSE[] =
253    "HTTP/1.1 400 Bad request received from client\r\n"
254    "Content-Type: text/plain\r\n"
255    "Connection: close\r\n\r\n"
256    "Bad request. Privoxy was unable to extract the destination.\r\n";
257
258 /* XXX: should be a template */
259 static const char INVALID_SERVER_HEADERS_RESPONSE[] =
260    "HTTP/1.1 502 Server or forwarder response invalid\r\n"
261    "Content-Type: text/plain\r\n"
262    "Connection: close\r\n\r\n"
263    "Bad response. The server or forwarder response doesn't look like HTTP.\r\n";
264
265 /* XXX: should be a template */
266 static const char MESSED_UP_REQUEST_RESPONSE[] =
267    "HTTP/1.1 400 Malformed request after rewriting\r\n"
268    "Content-Type: text/plain\r\n"
269    "Connection: close\r\n\r\n"
270    "Bad request. Messed up with header filters.\r\n";
271
272 static const char TOO_MANY_CONNECTIONS_RESPONSE[] =
273    "HTTP/1.1 503 Too many open connections\r\n"
274    "Content-Type: text/plain\r\n"
275    "Connection: close\r\n\r\n"
276    "Maximum number of open connections reached.\r\n";
277
278 static const char CLIENT_CONNECTION_TIMEOUT_RESPONSE[] =
279    "HTTP/1.1 504 Connection timeout\r\n"
280    "Content-Type: text/plain\r\n"
281    "Connection: close\r\n\r\n"
282    "The connection timed out because the client request didn't arrive in time.\r\n";
283
284 static const char CLIENT_BODY_PARSE_ERROR_RESPONSE[] =
285    "HTTP/1.1 400 Failed reading client body\r\n"
286    "Content-Type: text/plain\r\n"
287    "Connection: close\r\n\r\n"
288    "Failed parsing or buffering the chunk-encoded client body.\r\n";
289
290 static const char UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE[] =
291    "HTTP/1.1 417 Expecting too much\r\n"
292    "Content-Type: text/plain\r\n"
293    "Connection: close\r\n\r\n"
294    "Privoxy detected an unsupported Expect header value.\r\n";
295
296 /* A function to crunch a response */
297 typedef struct http_response *(*crunch_func_ptr)(struct client_state *);
298
299 /* Crunch function flags */
300 #define CF_NO_FLAGS        0
301 /* Cruncher applies to forced requests as well */
302 #define CF_IGNORE_FORCE    1
303 /* Crunched requests are counted for the block statistics */
304 #define CF_COUNT_AS_REJECT 2
305
306 /* A crunch function and its flags */
307 struct cruncher
308 {
309    const crunch_func_ptr cruncher;
310    const int flags;
311 };
312
313 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[]);
314
315 /* Complete list of cruncher functions */
316 static const struct cruncher crunchers_all[] = {
317    { direct_response, CF_COUNT_AS_REJECT|CF_IGNORE_FORCE},
318    { block_url,       CF_COUNT_AS_REJECT },
319 #ifdef FEATURE_TRUST
320    { trust_url,       CF_COUNT_AS_REJECT },
321 #endif /* def FEATURE_TRUST */
322    { redirect_url,    CF_NO_FLAGS  },
323    { dispatch_cgi,    CF_IGNORE_FORCE},
324    { NULL,            0 }
325 };
326
327 /* Light version, used after tags are applied */
328 static const struct cruncher crunchers_light[] = {
329    { block_url,       CF_COUNT_AS_REJECT },
330    { redirect_url,    CF_NO_FLAGS },
331    { NULL,            0 }
332 };
333
334
335 /*
336  * XXX: Don't we really mean
337  *
338  * #if defined(unix)
339  *
340  * here?
341  */
342 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
343 /*********************************************************************
344  *
345  * Function    :  sig_handler
346  *
347  * Description :  Signal handler for different signals.
348  *                Exit gracefully on TERM and INT
349  *                or set a flag that will cause the errlog
350  *                to be reopened by the main thread on HUP.
351  *
352  * Parameters  :
353  *          1  :  the_signal = the signal cause this function to call
354  *
355  * Returns     :  -
356  *
357  *********************************************************************/
358 static void sig_handler(int the_signal)
359 {
360    switch(the_signal)
361    {
362       case SIGTERM:
363       case SIGINT:
364          log_error(LOG_LEVEL_INFO, "exiting by signal %d .. bye", the_signal);
365 #if defined(unix)
366          if (pidfile)
367          {
368             unlink(pidfile);
369          }
370 #endif /* unix */
371          exit(the_signal);
372          break;
373
374       case SIGHUP:
375 #if defined(unix)
376          received_hup_signal = 1;
377 #endif
378          break;
379
380       default:
381          /*
382           * We shouldn't be here, unless we catch signals
383           * in main() that we can't handle here!
384           */
385          log_error(LOG_LEVEL_FATAL, "sig_handler: exiting on unexpected signal %d", the_signal);
386    }
387    return;
388
389 }
390 #endif
391
392
393 /*********************************************************************
394  *
395  * Function    :  client_protocol_is_unsupported
396  *
397  * Description :  Checks if the client used a known unsupported
398  *                protocol and deals with it by sending an error
399  *                response.
400  *
401  * Parameters  :
402  *          1  :  csp = Current client state (buffers, headers, etc...)
403  *          2  :  req = the first request line send by the client
404  *
405  * Returns     :  TRUE if an error response has been generated, or
406  *                FALSE if the request doesn't look invalid.
407  *
408  *********************************************************************/
409 static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
410 {
411    /*
412     * If it's a FTP or gopher request, we don't support it.
413     *
414     * These checks are better than nothing, but they might
415     * not work in all configurations and some clients might
416     * have problems digesting the answer.
417     *
418     * They should, however, never cause more problems than
419     * Privoxy's old behaviour (returning the misleading HTML
420     * error message:
421     *
422     * "Could not resolve http://(ftp|gopher)://example.org").
423     */
424    if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
425    {
426       const char *response = NULL;
427       const char *protocol = NULL;
428
429       if (!strncmpic(req, "GET ftp://", 10))
430       {
431          response = FTP_RESPONSE;
432          protocol = "FTP";
433       }
434       else
435       {
436          response = GOPHER_RESPONSE;
437          protocol = "GOPHER";
438       }
439       log_error(LOG_LEVEL_ERROR,
440          "%s tried to use Privoxy as %s proxy: %s",
441          csp->ip_addr_str, protocol, req);
442       log_error(LOG_LEVEL_CLF,
443          "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
444       freez(req);
445       write_socket(csp->cfd, response, strlen(response));
446
447       return TRUE;
448    }
449
450    return FALSE;
451 }
452
453
454 /*********************************************************************
455  *
456  * Function    :  client_has_unsupported_expectations
457  *
458  * Description :  Checks if the client used an unsupported expectation
459  *                in which case an error message is delivered.
460  *
461  * Parameters  :
462  *          1  :  csp = Current client state (buffers, headers, etc...)
463  *
464  * Returns     :  TRUE if an error response has been generated, or
465  *                FALSE if the request doesn't look invalid.
466  *
467  *********************************************************************/
468 static int client_has_unsupported_expectations(const struct client_state *csp)
469 {
470    if ((csp->flags & CSP_FLAG_UNSUPPORTED_CLIENT_EXPECTATION))
471    {
472       log_error(LOG_LEVEL_ERROR,
473          "Rejecting request from client %s with unsupported Expect header value",
474          csp->ip_addr_str);
475       log_error(LOG_LEVEL_CLF,
476          "%s - - [%T] \"%s\" 417 0", csp->ip_addr_str, csp->http->cmd);
477       write_socket(csp->cfd, UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE,
478          strlen(UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE));
479
480       return TRUE;
481    }
482
483    return FALSE;
484
485 }
486
487
488 /*********************************************************************
489  *
490  * Function    :  get_request_destination_elsewhere
491  *
492  * Description :  If the client's request was redirected into
493  *                Privoxy without the client's knowledge,
494  *                the request line lacks the destination host.
495  *
496  *                This function tries to get it elsewhere,
497  *                provided accept-intercepted-requests is enabled.
498  *
499  *                "Elsewhere" currently only means "Host: header",
500  *                but in the future we may ask the redirecting
501  *                packet filter to look the destination up.
502  *
503  *                If the destination stays unknown, an error
504  *                response is send to the client and headers
505  *                are freed so that chat() can return directly.
506  *
507  * Parameters  :
508  *          1  :  csp = Current client state (buffers, headers, etc...)
509  *          2  :  headers = a header list
510  *
511  * Returns     :  JB_ERR_OK if the destination is now known, or
512  *                JB_ERR_PARSE if it isn't.
513  *
514  *********************************************************************/
515 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers)
516 {
517    char *req;
518
519    if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS))
520    {
521       log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid."
522          " Privoxy isn't configured to accept intercepted requests.",
523          csp->ip_addr_str, csp->http->cmd);
524       /* XXX: Use correct size */
525       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
526          csp->ip_addr_str, csp->http->cmd);
527
528       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
529       destroy_list(headers);
530
531       return JB_ERR_PARSE;
532    }
533    else if (JB_ERR_OK == get_destination_from_headers(headers, csp->http))
534    {
535 #ifndef FEATURE_EXTENDED_HOST_PATTERNS
536       /* Split the domain we just got for pattern matching */
537       init_domain_components(csp->http);
538 #endif
539
540       return JB_ERR_OK;
541    }
542    else
543    {
544       /* We can't work without destination. Go spread the news.*/
545
546       req = list_to_text(headers);
547       chomp(req);
548       /* XXX: Use correct size */
549       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
550          csp->ip_addr_str, csp->http->cmd);
551       log_error(LOG_LEVEL_ERROR,
552          "Privoxy was unable to get the destination for %s's request:\n%s\n%s",
553          csp->ip_addr_str, csp->http->cmd, req);
554       freez(req);
555
556       write_socket(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE));
557       destroy_list(headers);
558
559       return JB_ERR_PARSE;
560    }
561    /*
562     * TODO: If available, use PF's ioctl DIOCNATLOOK as last resort
563     * to get the destination IP address, use it as host directly
564     * or do a reverse DNS lookup first.
565     */
566 }
567
568
569 /*********************************************************************
570  *
571  * Function    :  get_server_headers
572  *
573  * Description :  Parses server headers in iob and fills them
574  *                into csp->headers so that they can later be
575  *                handled by sed().
576  *
577  * Parameters  :
578  *          1  :  csp = Current client state (buffers, headers, etc...)
579  *
580  * Returns     :  JB_ERR_OK if everything went fine, or
581  *                JB_ERR_PARSE if the headers were incomplete.
582  *
583  *********************************************************************/
584 static jb_err get_server_headers(struct client_state *csp)
585 {
586    int continue_hack_in_da_house = 0;
587    char * header;
588
589    while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house)
590    {
591       if (header == NULL)
592       {
593          /*
594           * continue hack in da house. Ignore the ending of
595           * this head and continue enlisting header lines.
596           * The reason is described below.
597           */
598          enlist(csp->headers, "");
599          continue_hack_in_da_house = 0;
600          continue;
601       }
602       else if (0 == strncmpic(header, "HTTP/1.1 100", 12))
603       {
604          /*
605           * It's a bodyless continue response, don't
606           * stop header parsing after reaching its end.
607           *
608           * As a result Privoxy will concatenate the
609           * next response's head and parse and deliver
610           * the headers as if they belonged to one request.
611           *
612           * The client will separate them because of the
613           * empty line between them.
614           *
615           * XXX: What we're doing here is clearly against
616           * the intended purpose of the continue header,
617           * and under some conditions (HTTP/1.0 client request)
618           * it's a standard violation.
619           *
620           * Anyway, "sort of against the spec" is preferable
621           * to "always getting confused by Continue responses"
622           * (Privoxy's behaviour before this hack was added)
623           */
624          log_error(LOG_LEVEL_HEADER, "Continue hack in da house.");
625          continue_hack_in_da_house = 1;
626       }
627       else if (*header == '\0')
628       {
629          /*
630           * If the header is empty, but the Continue hack
631           * isn't active, we can assume that we reached the
632           * end of the buffer before we hit the end of the
633           * head.
634           *
635           * Inform the caller an let it decide how to handle it.
636           */
637          return JB_ERR_PARSE;
638       }
639
640       if (JB_ERR_MEMORY == enlist(csp->headers, header))
641       {
642          /*
643           * XXX: Should we quit the request and return a
644           * out of memory error page instead?
645           */
646          log_error(LOG_LEVEL_ERROR,
647             "Out of memory while enlisting server headers. %s lost.",
648             header);
649       }
650       freez(header);
651    }
652
653    return JB_ERR_OK;
654 }
655
656
657 /*********************************************************************
658  *
659  * Function    :  crunch_reason
660  *
661  * Description :  Translates the crunch reason code into a string.
662  *
663  * Parameters  :
664  *          1  :  rsp = a http_response
665  *
666  * Returns     :  A string with the crunch reason or an error description.
667  *
668  *********************************************************************/
669 static const char *crunch_reason(const struct http_response *rsp)
670 {
671    char * reason = NULL;
672
673    assert(rsp != NULL);
674    if (rsp == NULL)
675    {
676       return "Internal error while searching for crunch reason";
677    }
678
679    switch (rsp->crunch_reason)
680    {
681       case UNSUPPORTED:
682          reason = "Unsupported HTTP feature";
683          break;
684       case BLOCKED:
685          reason = "Blocked";
686          break;
687       case UNTRUSTED:
688          reason = "Untrusted";
689          break;
690       case REDIRECTED:
691          reason = "Redirected";
692          break;
693       case CGI_CALL:
694          reason = "CGI Call";
695          break;
696       case NO_SUCH_DOMAIN:
697          reason = "DNS failure";
698          break;
699       case FORWARDING_FAILED:
700          reason = "Forwarding failed";
701          break;
702       case CONNECT_FAILED:
703          reason = "Connection failure";
704          break;
705       case OUT_OF_MEMORY:
706          reason = "Out of memory (may mask other reasons)";
707          break;
708       case CONNECTION_TIMEOUT:
709          reason = "Connection timeout";
710          break;
711       case NO_SERVER_DATA:
712          reason = "No server data received";
713          break;
714       default:
715          reason = "No reason recorded";
716          break;
717    }
718
719    return reason;
720 }
721
722
723 /*********************************************************************
724  *
725  * Function    :  log_applied_actions
726  *
727  * Description :  Logs the applied actions if LOG_LEVEL_ACTIONS is
728  *                enabled.
729  *
730  * Parameters  :
731  *          1  :  actions = Current action spec to log
732  *
733  * Returns     :  Nothing.
734  *
735  *********************************************************************/
736 static void log_applied_actions(const struct current_action_spec *actions)
737 {
738    /*
739     * The conversion to text requires lots of memory allocations so
740     * we only do the conversion if the user is actually interested.
741     */
742    if (debug_level_is_enabled(LOG_LEVEL_ACTIONS))
743    {
744       char *actions_as_text = actions_to_line_of_text(actions);
745       log_error(LOG_LEVEL_ACTIONS, "%s", actions_as_text);
746       freez(actions_as_text);
747    }
748 }
749
750
751 /*********************************************************************
752  *
753  * Function    :  send_crunch_response
754  *
755  * Description :  Delivers already prepared response for
756  *                intercepted requests, logs the interception
757  *                and frees the response.
758  *
759  * Parameters  :
760  *          1  :  csp = Current client state (buffers, headers, etc...)
761  *          1  :  rsp = Fully prepared response. Will be freed on exit.
762  *
763  * Returns     :  Nothing.
764  *
765  *********************************************************************/
766 static void send_crunch_response(const struct client_state *csp, struct http_response *rsp)
767 {
768       const struct http_request *http = csp->http;
769       char status_code[4];
770
771       assert(rsp != NULL);
772       assert(rsp->head != NULL);
773
774       if (rsp == NULL)
775       {
776          log_error(LOG_LEVEL_FATAL, "NULL response in send_crunch_response.");
777       }
778
779       /*
780        * Extract the status code from the actual head
781        * that will be send to the client. It is the only
782        * way to get it right for all requests, including
783        * the fixed ones for out-of-memory problems.
784        *
785        * A head starts like this: 'HTTP/1.1 200...'
786        *                           0123456789|11
787        *                                     10
788        */
789       status_code[0] = rsp->head[9];
790       status_code[1] = rsp->head[10];
791       status_code[2] = rsp->head[11];
792       status_code[3] = '\0';
793
794       /* Log that the request was crunched and why. */
795       log_applied_actions(csp->action);
796       log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
797       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
798          csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
799
800       /* Write the answer to the client */
801       if (write_socket(csp->cfd, rsp->head, rsp->head_length)
802        || write_socket(csp->cfd, rsp->body, rsp->content_length))
803       {
804          /* There is nothing we can do about it. */
805          log_error(LOG_LEVEL_ERROR,
806             "Couldn't deliver the error message through client socket %d: %E",
807             csp->cfd);
808       }
809
810       /* Clean up and return */
811       if (cgi_error_memory() != rsp)
812       {
813          free_http_response(rsp);
814       }
815       return;
816 }
817
818
819 /*********************************************************************
820  *
821  * Function    :  crunch_response_triggered
822  *
823  * Description :  Checks if the request has to be crunched,
824  *                and delivers the crunch response if necessary.
825  *
826  * Parameters  :
827  *          1  :  csp = Current client state (buffers, headers, etc...)
828  *          2  :  crunchers = list of cruncher functions to run
829  *
830  * Returns     :  TRUE if the request was answered with a crunch response
831  *                FALSE otherwise.
832  *
833  *********************************************************************/
834 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[])
835 {
836    struct http_response *rsp = NULL;
837    const struct cruncher *c;
838
839    /*
840     * If CGI request crunching is disabled,
841     * check the CGI dispatcher out of order to
842     * prevent unintentional blocks or redirects.
843     */
844    if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_CRUNCHING)
845        && (NULL != (rsp = dispatch_cgi(csp))))
846    {
847       /* Deliver, log and free the interception response. */
848       send_crunch_response(csp, rsp);
849       csp->flags |= CSP_FLAG_CRUNCHED;
850       return TRUE;
851    }
852
853    for (c = crunchers; c->cruncher != NULL; c++)
854    {
855       /*
856        * Check the cruncher if either Privoxy is toggled
857        * on and the request isn't forced, or if the cruncher
858        * applies to forced requests as well.
859        */
860       if (((csp->flags & CSP_FLAG_TOGGLED_ON) &&
861           !(csp->flags & CSP_FLAG_FORCED)) ||
862           (c->flags & CF_IGNORE_FORCE))
863       {
864          rsp = c->cruncher(csp);
865          if (NULL != rsp)
866          {
867             /* Deliver, log and free the interception response. */
868             send_crunch_response(csp, rsp);
869             csp->flags |= CSP_FLAG_CRUNCHED;
870 #ifdef FEATURE_STATISTICS
871             if (c->flags & CF_COUNT_AS_REJECT)
872             {
873                csp->flags |= CSP_FLAG_REJECTED;
874             }
875 #endif /* def FEATURE_STATISTICS */
876
877             return TRUE;
878          }
879       }
880    }
881
882    return FALSE;
883 }
884
885
886 /*********************************************************************
887  *
888  * Function    :  build_request_line
889  *
890  * Description :  Builds the HTTP request line.
891  *
892  *                If a HTTP forwarder is used it expects the whole URL,
893  *                web servers only get the path.
894  *
895  * Parameters  :
896  *          1  :  csp = Current client state (buffers, headers, etc...)
897  *          2  :  fwd = The forwarding spec used for the request
898  *                XXX: Should use http->fwd instead.
899  *          3  :  request_line = The old request line which will be replaced.
900  *
901  * Returns     :  Nothing. Terminates in case of memory problems.
902  *
903  *********************************************************************/
904 static void build_request_line(struct client_state *csp, const struct forward_spec *fwd, char **request_line)
905 {
906    struct http_request *http = csp->http;
907
908    assert(http->ssl == 0);
909
910    /*
911     * Downgrade http version from 1.1 to 1.0
912     * if +downgrade action applies.
913     */
914    if ((csp->action->flags & ACTION_DOWNGRADE)
915      && (!strcmpic(http->ver, "HTTP/1.1")))
916    {
917       freez(http->ver);
918       http->ver = strdup_or_die("HTTP/1.0");
919    }
920
921    /*
922     * Rebuild the request line.
923     */
924    freez(*request_line);
925    *request_line = strdup(http->gpc);
926    string_append(request_line, " ");
927
928    if (fwd->forward_host && fwd->type != FORWARD_WEBSERVER)
929    {
930       string_append(request_line, http->url);
931    }
932    else
933    {
934       string_append(request_line, http->path);
935    }
936    string_append(request_line, " ");
937    string_append(request_line, http->ver);
938
939    if (*request_line == NULL)
940    {
941       log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
942    }
943    log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", *request_line);
944 }
945
946
947 /*********************************************************************
948  *
949  * Function    :  change_request_destination
950  *
951  * Description :  Parse a (rewritten) request line and regenerate
952  *                the http request data.
953  *
954  * Parameters  :
955  *          1  :  csp = Current client state (buffers, headers, etc...)
956  *
957  * Returns     :  Forwards the parse_http_request() return code.
958  *                Terminates in case of memory problems.
959  *
960  *********************************************************************/
961 static jb_err change_request_destination(struct client_state *csp)
962 {
963    struct http_request *http = csp->http;
964    jb_err err;
965
966    log_error(LOG_LEVEL_REDIRECTS, "Rewrite detected: %s",
967       csp->headers->first->str);
968    free_http_request(http);
969    err = parse_http_request(csp->headers->first->str, http);
970    if (JB_ERR_OK != err)
971    {
972       log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
973          jb_err_to_string(err));
974    }
975
976    return err;
977 }
978
979
980 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
981 /*********************************************************************
982  *
983  * Function    :  server_response_is_complete
984  *
985  * Description :  Determines whether we should stop reading
986  *                from the server socket.
987  *
988  * Parameters  :
989  *          1  :  csp = Current client state (buffers, headers, etc...)
990  *          2  :  content_length = Length of content received so far.
991  *
992  * Returns     :  TRUE if the response is complete,
993  *                FALSE otherwise.
994  *
995  *********************************************************************/
996 static int server_response_is_complete(struct client_state *csp,
997    unsigned long long content_length)
998 {
999    int content_length_known = !!(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET);
1000
1001    if (!strcmpic(csp->http->gpc, "HEAD"))
1002    {
1003       /*
1004        * "HEAD" implies no body, we are thus expecting
1005        * no content. XXX: incomplete "list" of methods?
1006        */
1007       csp->expected_content_length = 0;
1008       content_length_known = TRUE;
1009       csp->flags |= CSP_FLAG_SERVER_CONTENT_LENGTH_SET;
1010    }
1011
1012    if (csp->http->status == 204 || csp->http->status == 304)
1013    {
1014       /*
1015        * Expect no body. XXX: incomplete "list" of status codes?
1016        */
1017       csp->expected_content_length = 0;
1018       content_length_known = TRUE;
1019       csp->flags |= CSP_FLAG_SERVER_CONTENT_LENGTH_SET;
1020    }
1021
1022    return (content_length_known && ((0 == csp->expected_content_length)
1023             || (csp->expected_content_length <= content_length)));
1024 }
1025
1026
1027 #ifdef FEATURE_CONNECTION_SHARING
1028 /*********************************************************************
1029  *
1030  * Function    :  wait_for_alive_connections
1031  *
1032  * Description :  Waits for alive connections to timeout.
1033  *
1034  * Parameters  :  N/A
1035  *
1036  * Returns     :  N/A
1037  *
1038  *********************************************************************/
1039 static void wait_for_alive_connections(void)
1040 {
1041    int connections_alive = close_unusable_connections();
1042
1043    while (0 < connections_alive)
1044    {
1045       log_error(LOG_LEVEL_CONNECT,
1046          "Waiting for %d connections to timeout.",
1047          connections_alive);
1048       sleep(60);
1049       connections_alive = close_unusable_connections();
1050    }
1051
1052    log_error(LOG_LEVEL_CONNECT, "No connections to wait for left.");
1053
1054 }
1055 #endif /* def FEATURE_CONNECTION_SHARING */
1056
1057
1058 /*********************************************************************
1059  *
1060  * Function    :  save_connection_destination
1061  *
1062  * Description :  Remembers a connection for reuse later on.
1063  *
1064  * Parameters  :
1065  *          1  :  sfd  = Open socket to remember.
1066  *          2  :  http = The destination for the connection.
1067  *          3  :  fwd  = The forwarder settings used.
1068  *          3  :  server_connection  = storage.
1069  *
1070  * Returns     : void
1071  *
1072  *********************************************************************/
1073 void save_connection_destination(jb_socket sfd,
1074                                  const struct http_request *http,
1075                                  const struct forward_spec *fwd,
1076                                  struct reusable_connection *server_connection)
1077 {
1078    assert(sfd != JB_INVALID_SOCKET);
1079    assert(NULL != http->host);
1080
1081    server_connection->sfd = sfd;
1082    server_connection->host = strdup_or_die(http->host);
1083    server_connection->port = http->port;
1084
1085    assert(NULL != fwd);
1086    assert(server_connection->gateway_host == NULL);
1087    assert(server_connection->gateway_port == 0);
1088    assert(server_connection->forwarder_type == 0);
1089    assert(server_connection->forward_host == NULL);
1090    assert(server_connection->forward_port == 0);
1091
1092    server_connection->forwarder_type = fwd->type;
1093    if (NULL != fwd->gateway_host)
1094    {
1095       server_connection->gateway_host = strdup_or_die(fwd->gateway_host);
1096    }
1097    else
1098    {
1099       server_connection->gateway_host = NULL;
1100    }
1101    server_connection->gateway_port = fwd->gateway_port;
1102
1103    if (NULL != fwd->forward_host)
1104    {
1105       server_connection->forward_host = strdup_or_die(fwd->forward_host);
1106    }
1107    else
1108    {
1109       server_connection->forward_host = NULL;
1110    }
1111    server_connection->forward_port = fwd->forward_port;
1112 }
1113
1114
1115 /*********************************************************************
1116  *
1117  * Function    : verify_request_length
1118  *
1119  * Description : Checks if we already got the whole client requests
1120  *               and sets CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ if
1121  *               we do.
1122  *
1123  *               Data that doesn't belong to the current request is
1124  *               either thrown away to let the client retry on a clean
1125  *               socket, or stashed to be dealt with after the current
1126  *               request is served.
1127  *
1128  * Parameters  :
1129  *          1  :  csp = Current client state (buffers, headers, etc...)
1130  *
1131  * Returns     :  void
1132  *
1133  *********************************************************************/
1134 static void verify_request_length(struct client_state *csp)
1135 {
1136    unsigned long long buffered_request_bytes =
1137       (unsigned long long)(csp->client_iob->eod - csp->client_iob->cur);
1138
1139    if ((csp->expected_client_content_length != 0)
1140       && (buffered_request_bytes != 0))
1141    {
1142       if (csp->expected_client_content_length >= buffered_request_bytes)
1143       {
1144          csp->expected_client_content_length -= buffered_request_bytes;
1145          log_error(LOG_LEVEL_CONNECT, "Reduced expected bytes to %llu "
1146             "to account for the %llu ones we already got.",
1147             csp->expected_client_content_length, buffered_request_bytes);
1148       }
1149       else
1150       {
1151          assert(csp->client_iob->eod > csp->client_iob->cur + csp->expected_client_content_length);
1152          csp->client_iob->eod = csp->client_iob->cur + csp->expected_client_content_length;
1153          log_error(LOG_LEVEL_CONNECT, "Reducing expected bytes to 0. "
1154             "Marking the server socket tainted after throwing %llu bytes away.",
1155             buffered_request_bytes - csp->expected_client_content_length);
1156          csp->expected_client_content_length = 0;
1157          csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1158       }
1159
1160       if (csp->expected_client_content_length == 0)
1161       {
1162          csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1163       }
1164    }
1165
1166    if (!(csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)
1167       && ((csp->client_iob->cur < csp->client_iob->eod)
1168          || (csp->expected_client_content_length != 0)))
1169    {
1170       if (strcmpic(csp->http->gpc, "GET")
1171          && strcmpic(csp->http->gpc, "HEAD")
1172          && strcmpic(csp->http->gpc, "TRACE")
1173          && strcmpic(csp->http->gpc, "OPTIONS")
1174          && strcmpic(csp->http->gpc, "DELETE"))
1175       {
1176          /* XXX: this is an incomplete hack */
1177          csp->flags &= ~CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1178          log_error(LOG_LEVEL_CONNECT, "There better be a request body.");
1179       }
1180       else
1181       {
1182          csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1183
1184          if ((csp->config->feature_flags & RUNTIME_FEATURE_TOLERATE_PIPELINING) == 0)
1185          {
1186             csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1187             log_error(LOG_LEVEL_CONNECT,
1188                "Possible pipeline attempt detected. The connection will not "
1189                "be kept alive and we will only serve the first request.");
1190             /* Nuke the pipelined requests from orbit, just to be sure. */
1191             clear_iob(csp->client_iob);
1192          }
1193          else
1194          {
1195             /*
1196              * Keep the pipelined data around for now, we'll deal with
1197              * it once we're done serving the current request.
1198              */
1199             csp->flags |= CSP_FLAG_PIPELINED_REQUEST_WAITING;
1200             assert(csp->client_iob->eod >= csp->client_iob->cur);
1201             log_error(LOG_LEVEL_CONNECT, "Complete client request followed by "
1202                "%d bytes of pipelined data received.",
1203                (int)(csp->client_iob->eod - csp->client_iob->cur));
1204          }
1205       }
1206    }
1207    else
1208    {
1209       csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
1210       log_error(LOG_LEVEL_CONNECT, "Complete client request received.");
1211    }
1212 }
1213 #endif /* FEATURE_CONNECTION_KEEP_ALIVE */
1214
1215
1216 /*********************************************************************
1217  *
1218  * Function    :  mark_server_socket_tainted
1219  *
1220  * Description :  Makes sure we don't reuse a server socket
1221  *                (if we didn't read everything the server sent
1222  *                us reusing the socket would lead to garbage).
1223  *
1224  * Parameters  :
1225  *          1  :  csp = Current client state (buffers, headers, etc...)
1226  *
1227  * Returns     :  void.
1228  *
1229  *********************************************************************/
1230 static void mark_server_socket_tainted(struct client_state *csp)
1231 {
1232    /*
1233     * For consistency we always mark the server socket
1234     * tainted, however, to reduce the log noise we only
1235     * emit a log message if the server socket could have
1236     * actually been reused.
1237     */
1238    if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
1239       && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
1240    {
1241       log_error(LOG_LEVEL_CONNECT,
1242          "Marking the server socket %d tainted.",
1243          csp->server_connection.sfd);
1244    }
1245    csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1246 }
1247
1248 /*********************************************************************
1249  *
1250  * Function    :  get_request_line
1251  *
1252  * Description : Read the client request line.
1253  *
1254  * Parameters  :
1255  *          1  :  csp = Current client state (buffers, headers, etc...)
1256  *
1257  * Returns     :  Pointer to request line or NULL in case of errors.
1258  *
1259  *********************************************************************/
1260 static char *get_request_line(struct client_state *csp)
1261 {
1262    char buf[BUFFER_SIZE];
1263    char *request_line = NULL;
1264    int len;
1265
1266    memset(buf, 0, sizeof(buf));
1267
1268    if ((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) != 0)
1269    {
1270       /*
1271        * If there are multiple pipelined requests waiting,
1272        * the flag will be set again once the next request
1273        * has been parsed.
1274        */
1275       csp->flags &= ~CSP_FLAG_PIPELINED_REQUEST_WAITING;
1276
1277       request_line = get_header(csp->client_iob);
1278       if ((NULL != request_line) && ('\0' != *request_line))
1279       {
1280          return request_line;
1281       }
1282       else
1283       {
1284          log_error(LOG_LEVEL_CONNECT, "No complete request line "
1285             "received yet. Continuing reading from %d.", csp->cfd);
1286       }
1287    }
1288
1289    do
1290    {
1291       if (
1292 #ifdef FUZZ
1293           0 == (csp->flags & CSP_FLAG_FUZZED_INPUT) &&
1294 #endif
1295           !data_is_available(csp->cfd, csp->config->socket_timeout)
1296           )
1297       {
1298          if (socket_is_still_alive(csp->cfd))
1299          {
1300             log_error(LOG_LEVEL_CONNECT,
1301                "No request line on socket %d received in time. Timeout: %d.",
1302                csp->cfd, csp->config->socket_timeout);
1303             write_socket(csp->cfd, CLIENT_CONNECTION_TIMEOUT_RESPONSE,
1304                strlen(CLIENT_CONNECTION_TIMEOUT_RESPONSE));
1305          }
1306          else
1307          {
1308             log_error(LOG_LEVEL_CONNECT,
1309                "The client side of the connection on socket %d got "
1310                "closed without sending a complete request line.", csp->cfd);
1311          }
1312          return NULL;
1313       }
1314
1315       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1316
1317       if (len <= 0) return NULL;
1318
1319       /*
1320        * If there is no memory left for buffering the
1321        * request, there is nothing we can do but hang up
1322        */
1323       if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1324       {
1325          return NULL;
1326       }
1327
1328       request_line = get_header(csp->client_iob);
1329
1330    } while ((NULL != request_line) && ('\0' == *request_line));
1331
1332    return request_line;
1333
1334 }
1335
1336 enum chunk_status
1337 {
1338    CHUNK_STATUS_MISSING_DATA,
1339    CHUNK_STATUS_BODY_COMPLETE,
1340    CHUNK_STATUS_PARSE_ERROR
1341 };
1342
1343
1344 /*********************************************************************
1345  *
1346  * Function    :  chunked_body_is_complete
1347  *
1348  * Description :  Figures out whether or not a chunked body is complete.
1349  *
1350  *                Currently it always starts at the beginning of the
1351  *                buffer which is somewhat wasteful and prevents Privoxy
1352  *                from starting to forward the correctly parsed chunks
1353  *                as soon as theoretically possible.
1354  *
1355  *                Should be modified to work with a common buffer,
1356  *                and allow the caller to skip already parsed chunks.
1357  *
1358  *                This would allow the function to be used for unbuffered
1359  *                response bodies as well.
1360  *
1361  * Parameters  :
1362  *          1  :  iob = Buffer with the body to check.
1363  *          2  :  length = Length of complete body
1364  *
1365  * Returns     :  Enum with the result of the check.
1366  *
1367  *********************************************************************/
1368 static enum chunk_status chunked_body_is_complete(struct iob *iob, size_t *length)
1369 {
1370    unsigned int chunksize;
1371    char *p = iob->cur;
1372
1373    do
1374    {
1375       /*
1376        * We need at least a single digit, followed by "\r\n",
1377        * followed by an unknown amount of data, followed by "\r\n".
1378        */
1379       if (p + 5 > iob->eod)
1380       {
1381          return CHUNK_STATUS_MISSING_DATA;
1382       }
1383       if (sscanf(p, "%x", &chunksize) != 1)
1384       {
1385          return CHUNK_STATUS_PARSE_ERROR;
1386       }
1387
1388       /*
1389        * We want at least a single digit, followed by "\r\n",
1390        * followed by the specified amount of data, followed by "\r\n".
1391        */
1392       if (p + chunksize + 5 > iob->eod)
1393       {
1394          return CHUNK_STATUS_MISSING_DATA;
1395       }
1396
1397       /* Skip chunk-size. */
1398       p = strstr(p, "\r\n");
1399       if (NULL == p)
1400       {
1401          return CHUNK_STATUS_PARSE_ERROR;
1402       }
1403       /* Move beyond the chunkdata. */
1404       p += 2 + chunksize;
1405
1406       /* There should be another "\r\n" to skip */
1407       if (memcmp(p, "\r\n", 2))
1408       {
1409          return CHUNK_STATUS_PARSE_ERROR;
1410       }
1411       p += 2;
1412    } while (chunksize > 0U);
1413
1414    *length = (size_t)(p - iob->cur);
1415    assert(*length <= (size_t)(iob->eod - iob->cur));
1416    assert(p <= iob->eod);
1417
1418    return CHUNK_STATUS_BODY_COMPLETE;
1419
1420 }
1421
1422
1423 /*********************************************************************
1424  *
1425  * Function    : receive_chunked_client_request_body
1426  *
1427  * Description : Read the chunk-encoded client request body.
1428  *               Failures are dealt with.
1429  *
1430  * Parameters  :
1431  *          1  :  csp = Current client state (buffers, headers, etc...)
1432  *
1433  * Returns     :  JB_ERR_OK or JB_ERR_PARSE
1434  *
1435  *********************************************************************/
1436 static jb_err receive_chunked_client_request_body(struct client_state *csp)
1437 {
1438    size_t body_length;
1439    enum chunk_status status;
1440
1441    while (CHUNK_STATUS_MISSING_DATA ==
1442       (status = chunked_body_is_complete(csp->client_iob, &body_length)))
1443    {
1444       char buf[BUFFER_SIZE];
1445       int len;
1446
1447       if (!data_is_available(csp->cfd, csp->config->socket_timeout))
1448       {
1449          log_error(LOG_LEVEL_ERROR,
1450             "Timeout while waiting for the client body.");
1451          break;
1452       }
1453       len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1454       if (len <= 0)
1455       {
1456          log_error(LOG_LEVEL_ERROR, "Read the client body failed: %E");
1457          break;
1458       }
1459       if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1460       {
1461          break;
1462       }
1463    }
1464    if (status != CHUNK_STATUS_BODY_COMPLETE)
1465    {
1466       write_socket(csp->cfd, CLIENT_BODY_PARSE_ERROR_RESPONSE,
1467          strlen(CLIENT_BODY_PARSE_ERROR_RESPONSE));
1468       log_error(LOG_LEVEL_CLF,
1469          "%s - - [%T] \"Failed reading chunked client body\" 400 0", csp->ip_addr_str);
1470       return JB_ERR_PARSE;
1471    }
1472    log_error(LOG_LEVEL_CONNECT,
1473       "Chunked client body completely read. Length: %d", body_length);
1474    csp->expected_client_content_length = body_length;
1475
1476    return JB_ERR_OK;
1477
1478 }
1479
1480
1481 #ifdef FUZZ
1482 /*********************************************************************
1483  *
1484  * Function    :  fuzz_chunked_transfer_encoding
1485  *
1486  * Description :  Treat the fuzzed input as chunked transfer encoding
1487  *                to check and dechunk.
1488  *
1489  * Parameters  :
1490  *          1  :  csp      = Used to store the data.
1491  *          2  :  fuzz_input_file = File to read the input from.
1492  *
1493  * Returns     : Result of dechunking
1494  *
1495  *********************************************************************/
1496 extern int fuzz_chunked_transfer_encoding(struct client_state *csp, char *fuzz_input_file)
1497 {
1498    size_t length;
1499    size_t size = (size_t)(csp->iob->eod - csp->iob->cur);
1500    enum chunk_status status;
1501
1502    status = chunked_body_is_complete(csp->iob, &length);
1503    if (CHUNK_STATUS_BODY_COMPLETE != status)
1504    {
1505       log_error(LOG_LEVEL_INFO, "Chunked body is incomplete or invalid");
1506    }
1507
1508    return (JB_ERR_OK == remove_chunked_transfer_coding(csp->iob->cur, &size));
1509
1510 }
1511
1512
1513 /*********************************************************************
1514  *
1515  * Function    : fuzz_client_request
1516  *
1517  * Description : Try to get a client request from the fuzzed input.
1518  *
1519  * Parameters  :
1520  *          1  :  csp = Current client state (buffers, headers, etc...)
1521  *          2  :  fuzz_input_file = File to read the input from.
1522  *
1523  * Returns     :  Result of fuzzing.
1524  *
1525  *********************************************************************/
1526 extern int fuzz_client_request(struct client_state *csp, char *fuzz_input_file)
1527 {
1528    jb_err err;
1529
1530    csp->cfd = 0;
1531    csp->ip_addr_str = "fuzzer";
1532
1533    if (strcmp(fuzz_input_file, "-") != 0)
1534    {
1535       log_error(LOG_LEVEL_FATAL,
1536          "Fuzzed client requests can currenty only be read from stdin (-).");
1537    }
1538    err = receive_client_request(csp);
1539    if (err != JB_ERR_OK)
1540    {
1541       return 1;
1542    }
1543    err = parse_client_request(csp);
1544    if (err != JB_ERR_OK)
1545    {
1546       return 1;
1547    }
1548
1549    return 0;
1550
1551 }
1552 #endif  /* def FUZZ */
1553
1554
1555 #ifdef FEATURE_FORCE_LOAD
1556 /*********************************************************************
1557  *
1558  * Function    :  force_required
1559  *
1560  * Description : Checks a request line to see if it contains
1561  *               the FORCE_PREFIX. If it does, it is removed
1562  *               unless enforcing requests has beend disabled.
1563  *
1564  * Parameters  :
1565  *          1  :  request_line = HTTP request line
1566  *
1567  * Returns     :  TRUE if force is required, FALSE otherwise.
1568  *
1569  *********************************************************************/
1570 static int force_required(const struct client_state *csp, char *request_line)
1571 {
1572    char *p;
1573
1574    p = strstr(request_line, "http://");
1575    if (p != NULL)
1576    {
1577       /* Skip protocol */
1578       p += strlen("http://");
1579    }
1580    else
1581    {
1582       /* Intercepted request usually don't specify the protocol. */
1583       p = request_line;
1584    }
1585
1586    /* Go to the beginning of the path */
1587    p = strstr(p, "/");
1588    if (p == NULL)
1589    {
1590       /*
1591        * If the path is missing the request line is invalid and we
1592        * are done here. The client-visible rejection happens later on.
1593        */
1594       return 0;
1595    }
1596
1597    if (0 == strncmpic(p, FORCE_PREFIX, strlen(FORCE_PREFIX) - 1))
1598    {
1599       if (!(csp->config->feature_flags & RUNTIME_FEATURE_ENFORCE_BLOCKS))
1600       {
1601          /* XXX: Should clean more carefully */
1602          strclean(request_line, FORCE_PREFIX);
1603          log_error(LOG_LEVEL_FORCE,
1604             "Enforcing request: \"%s\".", request_line);
1605
1606          return 1;
1607       }
1608       log_error(LOG_LEVEL_FORCE,
1609          "Ignored force prefix in request: \"%s\".", request_line);
1610    }
1611
1612    return 0;
1613
1614 }
1615 #endif /* def FEATURE_FORCE_LOAD */
1616
1617
1618 /*********************************************************************
1619  *
1620  * Function    :  receive_client_request
1621  *
1622  * Description : Read the client's request (more precisely the
1623  *               client headers) and answer it if necessary.
1624  *
1625  * Parameters  :
1626  *          1  :  csp = Current client state (buffers, headers, etc...)
1627  *
1628  * Returns     :  JB_ERR_OK, JB_ERR_PARSE or JB_ERR_MEMORY
1629  *
1630  *********************************************************************/
1631 static jb_err receive_client_request(struct client_state *csp)
1632 {
1633    char buf[BUFFER_SIZE];
1634    char *p;
1635    char *req = NULL;
1636    struct http_request *http;
1637    int len;
1638    jb_err err;
1639
1640    /* Temporary copy of the client's headers before they get enlisted in csp->headers */
1641    struct list header_list;
1642    struct list *headers = &header_list;
1643
1644    /* We don't care if the arriving data is a valid HTTP request or not. */
1645    csp->requests_received_total++;
1646
1647    http = csp->http;
1648
1649    memset(buf, 0, sizeof(buf));
1650
1651    req = get_request_line(csp);
1652    if (req == NULL)
1653    {
1654       mark_server_socket_tainted(csp);
1655       return JB_ERR_PARSE;
1656    }
1657    assert(*req != '\0');
1658
1659    if (client_protocol_is_unsupported(csp, req))
1660    {
1661       return JB_ERR_PARSE;
1662    }
1663
1664 #ifdef FEATURE_FORCE_LOAD
1665    if (force_required(csp, req))
1666    {
1667       csp->flags |= CSP_FLAG_FORCED;
1668    }
1669 #endif /* def FEATURE_FORCE_LOAD */
1670
1671    err = parse_http_request(req, http);
1672    freez(req);
1673    if (JB_ERR_OK != err)
1674    {
1675       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1676       /* XXX: Use correct size */
1677       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
1678       log_error(LOG_LEVEL_ERROR,
1679          "Couldn't parse request line received from %s: %s",
1680          csp->ip_addr_str, jb_err_to_string(err));
1681
1682       free_http_request(http);
1683       return JB_ERR_PARSE;
1684    }
1685
1686    /* grab the rest of the client's headers */
1687    init_list(headers);
1688    for (;;)
1689    {
1690       p = get_header(csp->client_iob);
1691
1692       if (p == NULL)
1693       {
1694          /* There are no additional headers to read. */
1695          break;
1696       }
1697
1698       if (*p == '\0')
1699       {
1700          /*
1701           * We didn't receive a complete header
1702           * line yet, get the rest of it.
1703           */
1704          if (!data_is_available(csp->cfd, csp->config->socket_timeout))
1705          {
1706             log_error(LOG_LEVEL_ERROR,
1707                "Stopped grabbing the client headers.");
1708             destroy_list(headers);
1709             return JB_ERR_PARSE;
1710          }
1711
1712          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
1713          if (len <= 0)
1714          {
1715             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
1716             destroy_list(headers);
1717             return JB_ERR_PARSE;
1718          }
1719
1720          if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len))
1721          {
1722             /*
1723              * If there is no memory left for buffering the
1724              * request, there is nothing we can do but hang up
1725              */
1726             destroy_list(headers);
1727             return JB_ERR_MEMORY;
1728          }
1729       }
1730       else
1731       {
1732          if (!strncmpic(p, "Transfer-Encoding:", 18))
1733          {
1734             /*
1735              * XXX: should be called through sed()
1736              *      but currently can't.
1737              */
1738             client_transfer_encoding(csp, &p);
1739          }
1740          /*
1741           * We were able to read a complete
1742           * header and can finally enlist it.
1743           */
1744          enlist(headers, p);
1745          freez(p);
1746       }
1747    }
1748
1749    if (http->host == NULL)
1750    {
1751       /*
1752        * If we still don't know the request destination,
1753        * the request is invalid or the client uses
1754        * Privoxy without its knowledge.
1755        */
1756       if (JB_ERR_OK != get_request_destination_elsewhere(csp, headers))
1757       {
1758          /*
1759           * Our attempts to get the request destination
1760           * elsewhere failed or Privoxy is configured
1761           * to only accept proxy requests.
1762           *
1763           * An error response has already been send
1764           * and we're done here.
1765           */
1766          return JB_ERR_PARSE;
1767       }
1768    }
1769
1770 #ifdef FEATURE_CLIENT_TAGS
1771    /* XXX: If the headers were enlisted sooner, passing csp would do. */
1772    set_client_address(csp, headers);
1773    get_tag_list_for_client(csp->client_tags, csp->client_address);
1774 #endif
1775
1776    /*
1777     * Determine the actions for this URL
1778     */
1779 #ifdef FEATURE_TOGGLE
1780    if (!(csp->flags & CSP_FLAG_TOGGLED_ON))
1781    {
1782       /* Most compatible set of actions (i.e. none) */
1783       init_current_action(csp->action);
1784    }
1785    else
1786 #endif /* ndef FEATURE_TOGGLE */
1787    {
1788       get_url_actions(csp, http);
1789    }
1790
1791    enlist(csp->headers, http->cmd);
1792
1793    /* Append the previously read headers */
1794    err = list_append_list_unique(csp->headers, headers);
1795    destroy_list(headers);
1796
1797    return err;
1798
1799 }
1800
1801
1802 /*********************************************************************
1803  *
1804  * Function    : parse_client_request
1805  *
1806  * Description : Parses the client's request and decides what to do
1807  *               with it.
1808  *
1809  *               Note that since we're not using select() we could get
1810  *               blocked here if a client connected, then didn't say
1811  *               anything!
1812  *
1813  * Parameters  :
1814  *          1  :  csp = Current client state (buffers, headers, etc...)
1815  *
1816  * Returns     :  JB_ERR_OK or JB_ERR_PARSE
1817  *
1818  *********************************************************************/
1819 static jb_err parse_client_request(struct client_state *csp)
1820 {
1821    struct http_request *http = csp->http;
1822    jb_err err;
1823
1824 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1825    if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
1826     && (!strcmpic(csp->http->ver, "HTTP/1.1"))
1827     && (csp->http->ssl == 0))
1828    {
1829       /* Assume persistence until further notice */
1830       csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
1831    }
1832
1833    if (csp->http->ssl == 0)
1834    {
1835       /*
1836        * This whole block belongs to chat() but currently
1837        * has to be executed before sed().
1838        */
1839       if (csp->flags & CSP_FLAG_CHUNKED_CLIENT_BODY)
1840       {
1841          if (receive_chunked_client_request_body(csp) != JB_ERR_OK)
1842          {
1843             return JB_ERR_PARSE;
1844          }
1845       }
1846       else
1847       {
1848          csp->expected_client_content_length = get_expected_content_length(csp->headers);
1849       }
1850       verify_request_length(csp);
1851    }
1852    else
1853    {
1854       csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
1855    }
1856 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
1857
1858    err = sed(csp, FILTER_CLIENT_HEADERS);
1859    if (JB_ERR_OK != err)
1860    {
1861       log_error(LOG_LEVEL_ERROR, "Failed to parse client request from %s.",
1862          csp->ip_addr_str);
1863       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
1864          csp->ip_addr_str, csp->http->cmd);
1865       write_socket(csp->cfd, CHEADER, strlen(CHEADER));
1866       return JB_ERR_PARSE;
1867    }
1868    csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
1869
1870    /* Check request line for rewrites. */
1871    if ((NULL == csp->headers->first->str)
1872       || (strcmp(http->cmd, csp->headers->first->str) &&
1873          (JB_ERR_OK != change_request_destination(csp))))
1874    {
1875       /*
1876        * A header filter broke the request line - bail out.
1877        */
1878       write_socket(csp->cfd, MESSED_UP_REQUEST_RESPONSE, strlen(MESSED_UP_REQUEST_RESPONSE));
1879       /* XXX: Use correct size */
1880       log_error(LOG_LEVEL_CLF,
1881          "%s - - [%T] \"Invalid request generated\" 500 0", csp->ip_addr_str);
1882       log_error(LOG_LEVEL_ERROR,
1883          "Invalid request line after applying header filters.");
1884       free_http_request(http);
1885
1886       return JB_ERR_PARSE;
1887    }
1888
1889    if (client_has_unsupported_expectations(csp))
1890    {
1891       return JB_ERR_PARSE;
1892    }
1893
1894    return JB_ERR_OK;
1895
1896 }
1897
1898
1899 /*********************************************************************
1900  *
1901  * Function    : send_http_request
1902  *
1903  * Description : Sends the HTTP headers from the client request
1904  *               and all the body data that has already been received.
1905  *
1906  * Parameters  :
1907  *          1  :  csp = Current client state (buffers, headers, etc...)
1908  *
1909  * Returns     :  0 on success, anything else is na error.
1910  *
1911  *********************************************************************/
1912 static int send_http_request(struct client_state *csp)
1913 {
1914    char *hdr;
1915    int write_failure;
1916
1917    hdr = list_to_text(csp->headers);
1918    if (hdr == NULL)
1919    {
1920       /* FIXME Should handle error properly */
1921       log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
1922    }
1923    list_remove_all(csp->headers);
1924
1925    /*
1926     * Write the client's (modified) header to the server
1927     * (along with anything else that may be in the buffer)
1928     */
1929    write_failure = 0 != write_socket(csp->server_connection.sfd, hdr, strlen(hdr));
1930    freez(hdr);
1931
1932    if (write_failure)
1933    {
1934       log_error(LOG_LEVEL_CONNECT, "Failed sending request headers to: %s: %E",
1935          csp->http->hostport);
1936    }
1937    else if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) == 0)
1938       && (flush_socket(csp->server_connection.sfd, csp->client_iob) < 0))
1939    {
1940       write_failure = 1;
1941       log_error(LOG_LEVEL_CONNECT, "Failed sending request body to: %s: %E",
1942          csp->http->hostport);
1943    }
1944
1945    return write_failure;
1946
1947 }
1948
1949
1950 /*********************************************************************
1951  *
1952  * Function    :  handle_established_connection
1953  *
1954  * Description :  Shuffle data between client and server once the
1955  *                connection has been established.
1956  *
1957  * Parameters  :
1958  *          1  :  csp = Current client state (buffers, headers, etc...)
1959  *
1960  * Returns     :  Nothing.
1961  *
1962  *********************************************************************/
1963 static void handle_established_connection(struct client_state *csp)
1964 {
1965    char *hdr;
1966    char *p;
1967    int n;
1968 #ifdef HAVE_POLL
1969    struct pollfd poll_fds[2];
1970 #else
1971    fd_set rfds;
1972    jb_socket maxfd;
1973    struct timeval timeout;
1974 #endif
1975    int server_body;
1976    int ms_iis5_hack = 0;
1977    unsigned long long byte_count = 0;
1978    struct http_request *http;
1979    long len = 0; /* for buffer sizes (and negative error codes) */
1980    int buffer_and_filter_content = 0;
1981
1982    /* Skeleton for HTTP response, if we should intercept the request */
1983    struct http_response *rsp;
1984 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
1985    int watch_client_socket;
1986 #endif
1987
1988    csp->receive_buffer_size = csp->config->receive_buffer_size;
1989    csp->receive_buffer = zalloc(csp->receive_buffer_size + 1);
1990    if (csp->receive_buffer == NULL)
1991    {
1992       log_error(LOG_LEVEL_ERROR,
1993          "Out of memory. Failed to allocate the receive buffer.");
1994       rsp = cgi_error_memory();
1995       send_crunch_response(csp, rsp);
1996       return;
1997    }
1998
1999    http = csp->http;
2000
2001 #ifndef HAVE_POLL
2002    maxfd = (csp->cfd > csp->server_connection.sfd) ?
2003       csp->cfd : csp->server_connection.sfd;
2004 #endif
2005
2006    /* pass data between the client and server
2007     * until one or the other shuts down the connection.
2008     */
2009
2010    server_body = 0;
2011
2012 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2013    watch_client_socket = 0 == (csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING);
2014 #endif
2015
2016    for (;;)
2017    {
2018 #ifndef HAVE_POLL
2019 #ifdef __OS2__
2020       /*
2021        * FD_ZERO here seems to point to an errant macro which crashes.
2022        * So do this by hand for now...
2023        */
2024       memset(&rfds,0x00,sizeof(fd_set));
2025 #else
2026       FD_ZERO(&rfds);
2027 #endif
2028 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2029       if (!watch_client_socket)
2030       {
2031          maxfd = csp->server_connection.sfd;
2032       }
2033       else
2034 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2035       {
2036          FD_SET(csp->cfd, &rfds);
2037       }
2038
2039       FD_SET(csp->server_connection.sfd, &rfds);
2040 #endif /* ndef HAVE_POLL */
2041
2042 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2043       if ((csp->flags & CSP_FLAG_CHUNKED)
2044          && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2045          && ((csp->iob->eod - csp->iob->cur) >= 5)
2046          && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
2047       {
2048          /*
2049           * XXX: This check should be obsolete now,
2050           *      but let's wait a while to be sure.
2051           */
2052          log_error(LOG_LEVEL_CONNECT,
2053             "Looks like we got the last chunk together with "
2054             "the server headers but didn't detect it earlier. "
2055             "We better stop reading.");
2056          byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2057          csp->expected_content_length = byte_count;
2058          csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2059       }
2060       if (server_body && server_response_is_complete(csp, byte_count))
2061       {
2062          if (csp->expected_content_length == byte_count)
2063          {
2064             log_error(LOG_LEVEL_CONNECT,
2065                "Done reading from server. Content length: %llu as expected. "
2066                "Bytes most recently read: %d.",
2067                byte_count, len);
2068          }
2069          else
2070          {
2071             log_error(LOG_LEVEL_CONNECT,
2072                "Done reading from server. Expected content length: %llu. "
2073                "Actual content length: %llu. Bytes most recently read: %d.",
2074                csp->expected_content_length, byte_count, len);
2075          }
2076          len = 0;
2077          /*
2078           * XXX: should not jump around,
2079           * chat() is complicated enough already.
2080           */
2081          goto reading_done;
2082       }
2083 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
2084
2085 #ifdef HAVE_POLL
2086       poll_fds[0].fd = csp->cfd;
2087 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2088       if (!watch_client_socket)
2089       {
2090          /*
2091           * Ignore incoming data, but still watch out
2092           * for disconnects etc. These flags are always
2093           * implied anyway but explicitly setting them
2094           * doesn't hurt.
2095           */
2096          poll_fds[0].events = POLLERR|POLLHUP;
2097       }
2098       else
2099 #endif
2100       {
2101          poll_fds[0].events = POLLIN;
2102       }
2103       poll_fds[1].fd = csp->server_connection.sfd;
2104       poll_fds[1].events = POLLIN;
2105       n = poll(poll_fds, 2, csp->config->socket_timeout * 1000);
2106 #else
2107       timeout.tv_sec = csp->config->socket_timeout;
2108       timeout.tv_usec = 0;
2109       n = select((int)maxfd+1, &rfds, NULL, NULL, &timeout);
2110 #endif /* def HAVE_POLL */
2111
2112       if (n == 0)
2113       {
2114          log_error(LOG_LEVEL_CONNECT, "Socket timeout %d reached: %s",
2115             csp->config->socket_timeout, http->url);
2116          if ((byte_count == 0) && (http->ssl == 0))
2117          {
2118             send_crunch_response(csp, error_response(csp, "connection-timeout"));
2119          }
2120          mark_server_socket_tainted(csp);
2121          return;
2122       }
2123       else if (n < 0)
2124       {
2125 #ifdef HAVE_POLL
2126          log_error(LOG_LEVEL_ERROR, "poll() failed!: %E");
2127 #else
2128          log_error(LOG_LEVEL_ERROR, "select() failed!: %E");
2129 #endif
2130          mark_server_socket_tainted(csp);
2131          return;
2132       }
2133
2134       /*
2135        * This is the body of the browser's request,
2136        * just read and write it.
2137        *
2138        * XXX: Make sure the client doesn't use pipelining
2139        * behind Privoxy's back.
2140        */
2141 #ifdef HAVE_POLL
2142       if ((poll_fds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) != 0)
2143       {
2144          log_error(LOG_LEVEL_CONNECT,
2145             "The client socket %d has become unusable while "
2146             "the server socket %d is still open.",
2147             csp->cfd, csp->server_connection.sfd);
2148          mark_server_socket_tainted(csp);
2149          break;
2150       }
2151
2152       if (poll_fds[0].revents != 0)
2153 #else
2154       if (FD_ISSET(csp->cfd, &rfds))
2155 #endif /* def HAVE_POLL*/
2156       {
2157          int max_bytes_to_read = (int)csp->receive_buffer_size;
2158
2159 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2160          if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
2161          {
2162             if (data_is_available(csp->cfd, 0))
2163             {
2164                /*
2165                 * If the next request is already waiting, we have
2166                 * to stop select()ing the client socket. Otherwise
2167                 * we would always return right away and get nothing
2168                 * else done.
2169                 */
2170                watch_client_socket = 0;
2171                log_error(LOG_LEVEL_CONNECT,
2172                   "Stop watching client socket %d. "
2173                   "There's already another request waiting.",
2174                   csp->cfd);
2175                continue;
2176             }
2177             /*
2178              * If the client socket is set, but there's no data
2179              * available on the socket, the client went fishing
2180              * and continuing talking to the server makes no sense.
2181              */
2182             log_error(LOG_LEVEL_CONNECT,
2183                "The client closed socket %d while "
2184                "the server socket %d is still open.",
2185                csp->cfd, csp->server_connection.sfd);
2186             mark_server_socket_tainted(csp);
2187             break;
2188          }
2189          if (csp->expected_client_content_length != 0)
2190          {
2191             if (csp->expected_client_content_length < csp->receive_buffer_size)
2192             {
2193                max_bytes_to_read = (int)csp->expected_client_content_length;
2194             }
2195             log_error(LOG_LEVEL_CONNECT,
2196                "Waiting for up to %d bytes from the client.",
2197                max_bytes_to_read);
2198          }
2199          assert(max_bytes_to_read <= csp->receive_buffer_size);
2200 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2201
2202          len = read_socket(csp->cfd, csp->receive_buffer, max_bytes_to_read);
2203
2204          if (len <= 0)
2205          {
2206             /* XXX: not sure if this is necessary. */
2207             mark_server_socket_tainted(csp);
2208             break; /* "game over, man" */
2209          }
2210
2211 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2212          if (csp->expected_client_content_length != 0)
2213          {
2214             assert(len <= max_bytes_to_read);
2215             csp->expected_client_content_length -= (unsigned)len;
2216             log_error(LOG_LEVEL_CONNECT,
2217                "Expected client content length set to %llu "
2218                "after reading %d bytes.",
2219                csp->expected_client_content_length, len);
2220             if (csp->expected_client_content_length == 0)
2221             {
2222                log_error(LOG_LEVEL_CONNECT,
2223                   "Done reading from the client.");
2224                csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
2225             }
2226          }
2227 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2228
2229          if (write_socket(csp->server_connection.sfd, csp->receive_buffer, (size_t)len))
2230          {
2231             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
2232             mark_server_socket_tainted(csp);
2233             return;
2234          }
2235          continue;
2236       }
2237
2238       /*
2239        * The server wants to talk. It could be the header or the body.
2240        * If `hdr' is null, then it's the header otherwise it's the body.
2241        * FIXME: Does `hdr' really mean `host'? No.
2242        */
2243 #ifdef HAVE_POLL
2244       if (poll_fds[1].revents != 0)
2245 #else
2246       if (FD_ISSET(csp->server_connection.sfd, &rfds))
2247 #endif /* HAVE_POLL */
2248       {
2249 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2250          /*
2251           * If we are buffering content, we don't want to eat up to
2252           * buffer-limit bytes if the client no longer cares about them.
2253           * If we aren't buffering, however, a dead client socket will be
2254           * noticed pretty much right away anyway, so we can reduce the
2255           * overhead by skipping the check.
2256           */
2257          if (buffer_and_filter_content && !socket_is_still_alive(csp->cfd))
2258          {
2259 #ifdef _WIN32
2260             log_error(LOG_LEVEL_CONNECT,
2261                "The server still wants to talk, but the client may already have hung up on us.");
2262 #else
2263             log_error(LOG_LEVEL_CONNECT,
2264                "The server still wants to talk, but the client hung up on us.");
2265             mark_server_socket_tainted(csp);
2266             return;
2267 #endif /* def _WIN32 */
2268          }
2269 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2270
2271          len = read_socket(csp->server_connection.sfd, csp->receive_buffer, (int)csp->receive_buffer_size);
2272
2273          if (len < 0)
2274          {
2275             log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host);
2276
2277             if (http->ssl && (csp->fwd == NULL))
2278             {
2279                /*
2280                 * Just hang up. We already confirmed the client's CONNECT
2281                 * request with status code 200 and unencrypted content is
2282                 * no longer welcome.
2283                 */
2284                log_error(LOG_LEVEL_ERROR,
2285                   "CONNECT already confirmed. Unable to tell the client about the problem.");
2286                return;
2287             }
2288             else if (byte_count)
2289             {
2290                /*
2291                 * Just hang up. We already transmitted the original headers
2292                 * and parts of the original content and therefore missed the
2293                 * chance to send an error message (without risking data corruption).
2294                 *
2295                 * XXX: we could retry with a fancy range request here.
2296                 */
2297                log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. "
2298                   "Unable to tell the client about the problem.");
2299                mark_server_socket_tainted(csp);
2300                return;
2301             }
2302             /*
2303              * XXX: Consider handling the cases above the same.
2304              */
2305             mark_server_socket_tainted(csp);
2306             len = 0;
2307          }
2308
2309 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2310          if (csp->flags & CSP_FLAG_CHUNKED)
2311          {
2312             if ((len >= 5) && !memcmp(csp->receive_buffer+len-5, "0\r\n\r\n", 5))
2313             {
2314                /* XXX: this is a temporary hack */
2315                log_error(LOG_LEVEL_CONNECT,
2316                   "Looks like we reached the end of the last chunk. "
2317                   "We better stop reading.");
2318                csp->expected_content_length = byte_count + (unsigned long long)len;
2319                csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2320             }
2321          }
2322          reading_done:
2323 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
2324
2325          /*
2326           * This is guaranteed by allocating with zalloc_or_die()
2327           * and never (intentionally) writing to the last byte.
2328           *
2329           * csp->receive_buffer_size is the size of the part of the
2330           * buffer we intentionally write to, but we actually
2331           * allocated csp->receive_buffer_size+1 bytes so the assertion
2332           * stays within the allocated range.
2333           */
2334          assert(csp->receive_buffer[csp->receive_buffer_size] == '\0');
2335
2336          /*
2337           * Add a trailing zero to let be able to use string operations.
2338           * XXX: do we still need this with filter_popups gone?
2339           */
2340          assert(len <= csp->receive_buffer_size);
2341          csp->receive_buffer[len] = '\0';
2342
2343          /*
2344           * Normally, this would indicate that we've read
2345           * as much as the server has sent us and we can
2346           * close the client connection.  However, Microsoft
2347           * in its wisdom has released IIS/5 with a bug that
2348           * prevents it from sending the trailing \r\n in
2349           * a 302 redirect header (and possibly other headers).
2350           * To work around this if we've haven't parsed
2351           * a full header we'll append a trailing \r\n
2352           * and see if this now generates a valid one.
2353           *
2354           * This hack shouldn't have any impacts.  If we've
2355           * already transmitted the header or if this is a
2356           * SSL connection, then we won't bother with this
2357           * hack.  So we only work on partially received
2358           * headers.  If we append a \r\n and this still
2359           * doesn't generate a valid header, then we won't
2360           * transmit anything to the client.
2361           */
2362          if (len == 0)
2363          {
2364
2365             if (server_body || http->ssl)
2366             {
2367                /*
2368                 * If we have been buffering up the document,
2369                 * now is the time to apply content modification
2370                 * and send the result to the client.
2371                 */
2372                if (buffer_and_filter_content)
2373                {
2374                   p = execute_content_filters(csp);
2375                   /*
2376                    * If content filtering fails, use the original
2377                    * buffer and length.
2378                    * (see p != NULL ? p : csp->iob->cur below)
2379                    */
2380                   if (NULL == p)
2381                   {
2382                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
2383                   }
2384 #ifdef FEATURE_COMPRESSION
2385                   else if ((csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE)
2386                      && (csp->content_length > LOWER_LENGTH_LIMIT_FOR_COMPRESSION))
2387                   {
2388                      char *compressed_content = compress_buffer(p,
2389                         (size_t *)&csp->content_length, csp->config->compression_level);
2390                      if (compressed_content != NULL)
2391                      {
2392                         freez(p);
2393                         p = compressed_content;
2394                         csp->flags |= CSP_FLAG_BUFFERED_CONTENT_DEFLATED;
2395                      }
2396                   }
2397 #endif
2398
2399                   if (JB_ERR_OK != update_server_headers(csp))
2400                   {
2401                      log_error(LOG_LEVEL_FATAL,
2402                         "Failed to update server headers. after filtering.");
2403                   }
2404
2405                   hdr = list_to_text(csp->headers);
2406                   if (hdr == NULL)
2407                   {
2408                      /* FIXME Should handle error properly */
2409                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2410                   }
2411
2412                   if (write_socket(csp->cfd, hdr, strlen(hdr))
2413                    || write_socket(csp->cfd,
2414                          ((p != NULL) ? p : csp->iob->cur), (size_t)csp->content_length))
2415                   {
2416                      log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
2417                      freez(hdr);
2418                      freez(p);
2419                      mark_server_socket_tainted(csp);
2420                      return;
2421                   }
2422
2423                   freez(hdr);
2424                   freez(p);
2425                }
2426
2427                break; /* "game over, man" */
2428             }
2429
2430             /*
2431              * This is NOT the body, so
2432              * Let's pretend the server just sent us a blank line.
2433              */
2434             snprintf(csp->receive_buffer, csp->receive_buffer_size, "\r\n");
2435             len = (int)strlen(csp->receive_buffer);
2436
2437             /*
2438              * Now, let the normal header parsing algorithm below do its
2439              * job.  If it fails, we'll exit instead of continuing.
2440              */
2441
2442             ms_iis5_hack = 1;
2443          }
2444
2445          /*
2446           * If this is an SSL connection or we're in the body
2447           * of the server document, just write it to the client,
2448           * unless we need to buffer the body for later content-filtering
2449           */
2450          if (server_body || http->ssl)
2451          {
2452             if (buffer_and_filter_content)
2453             {
2454                /*
2455                 * If there is no memory left for buffering the content, or the buffer limit
2456                 * has been reached, switch to non-filtering mode, i.e. make & write the
2457                 * header, flush the iob and buf, and get out of the way.
2458                 */
2459                if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len))
2460                {
2461                   size_t hdrlen;
2462                   long flushed;
2463
2464                   log_error(LOG_LEVEL_INFO,
2465                      "Flushing header and buffers. Stepping back from filtering.");
2466
2467                   hdr = list_to_text(csp->headers);
2468                   if (hdr == NULL)
2469                   {
2470                      /*
2471                       * Memory is too tight to even generate the header.
2472                       * Send our static "Out-of-memory" page.
2473                       */
2474                      log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
2475                      rsp = cgi_error_memory();
2476                      send_crunch_response(csp, rsp);
2477                      mark_server_socket_tainted(csp);
2478                      return;
2479                   }
2480                   hdrlen = strlen(hdr);
2481
2482                   if (write_socket(csp->cfd, hdr, hdrlen)
2483                    || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0)
2484                    || (write_socket(csp->cfd, csp->receive_buffer, (size_t)len)))
2485                   {
2486                      log_error(LOG_LEVEL_CONNECT,
2487                         "Flush header and buffers to client failed: %E");
2488                      freez(hdr);
2489                      mark_server_socket_tainted(csp);
2490                      return;
2491                   }
2492
2493                   /*
2494                    * Reset the byte_count to the amount of bytes
2495                    * we just flushed. len will be added a few lines below,
2496                    * hdrlen doesn't matter for LOG_LEVEL_CLF.
2497                    */
2498                   byte_count = (unsigned long long)flushed;
2499                   freez(hdr);
2500                   buffer_and_filter_content = 0;
2501                   server_body = 1;
2502                }
2503             }
2504             else
2505             {
2506                if (write_socket(csp->cfd, csp->receive_buffer, (size_t)len))
2507                {
2508                   log_error(LOG_LEVEL_ERROR, "write to client failed: %E");
2509                   mark_server_socket_tainted(csp);
2510                   return;
2511                }
2512             }
2513             byte_count += (unsigned long long)len;
2514             continue;
2515          }
2516          else
2517          {
2518             /*
2519              * We're still looking for the end of the server's header.
2520              * Buffer up the data we just read.  If that fails, there's
2521              * little we can do but send our static out-of-memory page.
2522              */
2523             if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len))
2524             {
2525                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
2526                rsp = cgi_error_memory();
2527                send_crunch_response(csp, rsp);
2528                mark_server_socket_tainted(csp);
2529                return;
2530             }
2531
2532             /* Convert iob into something sed() can digest */
2533             if (JB_ERR_PARSE == get_server_headers(csp))
2534             {
2535                if (ms_iis5_hack)
2536                {
2537                   /*
2538                    * Well, we tried our MS IIS/5 hack and it didn't work.
2539                    * The header is incomplete and there isn't anything
2540                    * we can do about it.
2541                    */
2542                   log_error(LOG_LEVEL_ERROR, "Invalid server headers. "
2543                      "Applying the MS IIS5 hack didn't help.");
2544                   log_error(LOG_LEVEL_CLF,
2545                      "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2546                   write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2547                      strlen(INVALID_SERVER_HEADERS_RESPONSE));
2548                   mark_server_socket_tainted(csp);
2549                   return;
2550                }
2551                else
2552                {
2553                   /*
2554                    * Since we have to wait for more from the server before
2555                    * we can parse the headers we just continue here.
2556                    */
2557                   log_error(LOG_LEVEL_CONNECT,
2558                      "Continuing buffering server headers from socket %d. "
2559                      "Bytes most recently read: %d.", csp->cfd, len);
2560                   continue;
2561                }
2562             }
2563             else
2564             {
2565                /*
2566                 * Account for the content bytes we
2567                 * might have gotten with the headers.
2568                 */
2569                assert(csp->iob->eod >= csp->iob->cur);
2570                byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2571             }
2572
2573             /* Did we actually get anything? */
2574             if (NULL == csp->headers->first)
2575             {
2576                if ((csp->flags & CSP_FLAG_REUSED_CLIENT_CONNECTION))
2577                {
2578                   log_error(LOG_LEVEL_ERROR,
2579                      "No server or forwarder response received on socket %d. "
2580                      "Closing client socket %d without sending data.",
2581                      csp->server_connection.sfd, csp->cfd);
2582                   log_error(LOG_LEVEL_CLF,
2583                      "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2584                }
2585                else
2586                {
2587                   log_error(LOG_LEVEL_ERROR,
2588                      "No server or forwarder response received on socket %d.",
2589                      csp->server_connection.sfd);
2590                   send_crunch_response(csp, error_response(csp, "no-server-data"));
2591                }
2592                free_http_request(http);
2593                mark_server_socket_tainted(csp);
2594                return;
2595             }
2596
2597             assert(csp->headers->first->str);
2598             assert(!http->ssl);
2599             if (strncmpic(csp->headers->first->str, "HTTP", 4) &&
2600                 strncmpic(csp->headers->first->str, "ICY", 3))
2601             {
2602                /*
2603                 * It doesn't look like a HTTP (or Shoutcast) response:
2604                 * tell the client and log the problem.
2605                 */
2606                if (strlen(csp->headers->first->str) > 30)
2607                {
2608                   csp->headers->first->str[30] = '\0';
2609                }
2610                log_error(LOG_LEVEL_ERROR,
2611                   "Invalid server or forwarder response. Starts with: %s",
2612                   csp->headers->first->str);
2613                log_error(LOG_LEVEL_CLF,
2614                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2615                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2616                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2617                free_http_request(http);
2618                mark_server_socket_tainted(csp);
2619                return;
2620             }
2621
2622             /*
2623              * We have now received the entire server header,
2624              * filter it and send the result to the client
2625              */
2626             if (JB_ERR_OK != sed(csp, FILTER_SERVER_HEADERS))
2627             {
2628                log_error(LOG_LEVEL_CLF,
2629                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2630                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2631                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2632                free_http_request(http);
2633                mark_server_socket_tainted(csp);
2634                return;
2635             }
2636             hdr = list_to_text(csp->headers);
2637             if (hdr == NULL)
2638             {
2639                /* FIXME Should handle error properly */
2640                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
2641             }
2642
2643             if ((csp->flags & CSP_FLAG_CHUNKED)
2644                && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2645                && ((csp->iob->eod - csp->iob->cur) >= 5)
2646                && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
2647             {
2648                log_error(LOG_LEVEL_CONNECT,
2649                   "Looks like we got the last chunk together with "
2650                   "the server headers. We better stop reading.");
2651                byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
2652                csp->expected_content_length = byte_count;
2653                csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
2654             }
2655
2656             csp->server_connection.response_received = time(NULL);
2657
2658             if (crunch_response_triggered(csp, crunchers_light))
2659             {
2660                /*
2661                 * One of the tags created by a server-header
2662                 * tagger triggered a crunch. We already
2663                 * delivered the crunch response to the client
2664                 * and are done here after cleaning up.
2665                 */
2666                freez(hdr);
2667                mark_server_socket_tainted(csp);
2668                return;
2669             }
2670             /* Buffer and pcrs filter this if appropriate. */
2671
2672             if (!http->ssl) /* We talk plaintext */
2673             {
2674                buffer_and_filter_content = content_requires_filtering(csp);
2675             }
2676             /*
2677              * Only write if we're not buffering for content modification
2678              */
2679             if (!buffer_and_filter_content)
2680             {
2681                /*
2682                 * Write the server's (modified) header to
2683                 * the client (along with anything else that
2684                 * may be in the buffer)
2685                 */
2686
2687                if (write_socket(csp->cfd, hdr, strlen(hdr))
2688                 || ((len = flush_socket(csp->cfd, csp->iob)) < 0))
2689                {
2690                   log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
2691
2692                   /*
2693                    * The write failed, so don't bother mentioning it
2694                    * to the client... it probably can't hear us anyway.
2695                    */
2696                   freez(hdr);
2697                   mark_server_socket_tainted(csp);
2698                   return;
2699                }
2700             }
2701
2702             /* we're finished with the server's header */
2703
2704             freez(hdr);
2705             server_body = 1;
2706
2707             /*
2708              * If this was a MS IIS/5 hack then it means the server
2709              * has already closed the connection. Nothing more to read.
2710              * Time to bail.
2711              */
2712             if (ms_iis5_hack)
2713             {
2714                log_error(LOG_LEVEL_ERROR,
2715                   "Closed server connection detected. "
2716                   "Applying the MS IIS5 hack didn't help.");
2717                log_error(LOG_LEVEL_CLF,
2718                   "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
2719                write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
2720                   strlen(INVALID_SERVER_HEADERS_RESPONSE));
2721                mark_server_socket_tainted(csp);
2722                return;
2723             }
2724          }
2725          continue;
2726       }
2727       mark_server_socket_tainted(csp);
2728       return; /* huh? we should never get here */
2729    }
2730
2731    if (csp->content_length == 0)
2732    {
2733       /*
2734        * If Privoxy didn't recalculate the Content-Length,
2735        * byte_count is still correct.
2736        */
2737       csp->content_length = byte_count;
2738    }
2739
2740 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2741    if ((csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
2742       && (csp->expected_content_length != byte_count))
2743    {
2744       log_error(LOG_LEVEL_CONNECT,
2745          "Received %llu bytes while expecting %llu.",
2746          byte_count, csp->expected_content_length);
2747       mark_server_socket_tainted(csp);
2748    }
2749 #endif
2750
2751    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
2752       csp->ip_addr_str, http->ocmd, csp->content_length);
2753
2754    csp->server_connection.timestamp = time(NULL);
2755 }
2756
2757
2758 /*********************************************************************
2759  *
2760  * Function    :  chat
2761  *
2762  * Description :  Once a connection from the client has been accepted,
2763  *                this function is called (via serve()) to handle the
2764  *                main business of the communication.  This function
2765  *                returns after dealing with a single request. It can
2766  *                be called multiple times with the same client socket
2767  *                if the client is keeping the connection alive.
2768  *
2769  *                The decision whether or not a client connection will
2770  *                be kept alive is up to the caller which also must
2771  *                close the client socket when done.
2772  *
2773  *                FIXME: chat is nearly thousand lines long.
2774  *                Ridiculous.
2775  *
2776  * Parameters  :
2777  *          1  :  csp = Current client state (buffers, headers, etc...)
2778  *
2779  * Returns     :  Nothing.
2780  *
2781  *********************************************************************/
2782 static void chat(struct client_state *csp)
2783 {
2784    const struct forward_spec *fwd;
2785    struct http_request *http;
2786    /* Skeleton for HTTP response, if we should intercept the request */
2787    struct http_response *rsp;
2788
2789    http = csp->http;
2790
2791    if (receive_client_request(csp) != JB_ERR_OK)
2792    {
2793       return;
2794    }
2795    if (parse_client_request(csp) != JB_ERR_OK)
2796    {
2797       return;
2798    }
2799
2800    /* decide how to route the HTTP request */
2801    fwd = forward_url(csp, http);
2802    if (NULL == fwd)
2803    {
2804       log_error(LOG_LEVEL_FATAL, "gateway spec is NULL!?!?  This can't happen!");
2805       /* Never get here - LOG_LEVEL_FATAL causes program exit */
2806       return;
2807    }
2808
2809    /*
2810     * build the http request to send to the server
2811     * we have to do one of the following:
2812     *
2813     * create = use the original HTTP request to create a new
2814     *          HTTP request that has either the path component
2815     *          without the http://domainspec (w/path) or the
2816     *          full orininal URL (w/url)
2817     *          Note that the path and/or the HTTP version may
2818     *          have been altered by now.
2819     *
2820     * connect = Open a socket to the host:port of the server
2821     *           and short-circuit server and client socket.
2822     *
2823     * pass =  Pass the request unchanged if forwarding a CONNECT
2824     *         request to a parent proxy. Note that we'll be sending
2825     *         the CFAIL message ourselves if connecting to the parent
2826     *         fails, but we won't send a CSUCCEED message if it works,
2827     *         since that would result in a double message (ours and the
2828     *         parent's). After sending the request to the parent, we simply
2829     *         tunnel.
2830     *
2831     * here's the matrix:
2832     *                        SSL
2833     *                    0        1
2834     *                +--------+--------+
2835     *                |        |        |
2836     *             0  | create | connect|
2837     *                | w/path |        |
2838     *  Forwarding    +--------+--------+
2839     *                |        |        |
2840     *             1  | create | pass   |
2841     *                | w/url  |        |
2842     *                +--------+--------+
2843     *
2844     */
2845
2846    if (http->ssl && connect_port_is_forbidden(csp))
2847    {
2848       const char *acceptable_connect_ports =
2849          csp->action->string[ACTION_STRING_LIMIT_CONNECT];
2850       assert(NULL != acceptable_connect_ports);
2851       log_error(LOG_LEVEL_INFO, "Request from %s marked for blocking. "
2852          "limit-connect{%s} doesn't allow CONNECT requests to %s",
2853          csp->ip_addr_str, acceptable_connect_ports, csp->http->hostport);
2854       csp->action->flags |= ACTION_BLOCK;
2855       http->ssl = 0;
2856    }
2857
2858    if (http->ssl == 0)
2859    {
2860       freez(csp->headers->first->str);
2861       build_request_line(csp, fwd, &csp->headers->first->str);
2862    }
2863
2864    /*
2865     * We have a request. Check if one of the crunchers wants it.
2866     */
2867    if (crunch_response_triggered(csp, crunchers_all))
2868    {
2869       /*
2870        * Yes. The client got the crunch response and we're done here.
2871        */
2872       return;
2873    }
2874
2875    log_applied_actions(csp->action);
2876    log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
2877
2878    if (fwd->forward_host)
2879    {
2880       log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
2881          fwd->forward_host, fwd->forward_port, http->hostport);
2882    }
2883    else
2884    {
2885       log_error(LOG_LEVEL_CONNECT, "to %s", http->hostport);
2886    }
2887
2888    /* here we connect to the server, gateway, or the forwarder */
2889
2890 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2891    if ((csp->server_connection.sfd != JB_INVALID_SOCKET)
2892       && socket_is_still_alive(csp->server_connection.sfd)
2893       && connection_destination_matches(&csp->server_connection, http, fwd))
2894    {
2895       log_error(LOG_LEVEL_CONNECT,
2896          "Reusing server socket %d connected to %s. Total requests: %u.",
2897          csp->server_connection.sfd, csp->server_connection.host,
2898          csp->server_connection.requests_sent_total);
2899    }
2900    else
2901    {
2902       if (csp->server_connection.sfd != JB_INVALID_SOCKET)
2903       {
2904 #ifdef FEATURE_CONNECTION_SHARING
2905          if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
2906          {
2907             remember_connection(&csp->server_connection);
2908          }
2909          else
2910 #endif /* def FEATURE_CONNECTION_SHARING */
2911          {
2912             log_error(LOG_LEVEL_CONNECT,
2913                "Closing server socket %d connected to %s. Total requests: %u.",
2914                csp->server_connection.sfd, csp->server_connection.host,
2915                csp->server_connection.requests_sent_total);
2916             close_socket(csp->server_connection.sfd);
2917          }
2918          mark_connection_closed(&csp->server_connection);
2919       }
2920 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2921
2922       csp->server_connection.sfd = forwarded_connect(fwd, http, csp);
2923
2924       if (csp->server_connection.sfd == JB_INVALID_SOCKET)
2925       {
2926          if (fwd->type != SOCKS_NONE)
2927          {
2928             /* Socks error. */
2929             rsp = error_response(csp, "forwarding-failed");
2930          }
2931          else if (errno == EINVAL)
2932          {
2933             rsp = error_response(csp, "no-such-domain");
2934          }
2935          else
2936          {
2937             rsp = error_response(csp, "connect-failed");
2938          }
2939
2940          /* Write the answer to the client */
2941          if (rsp != NULL)
2942          {
2943             send_crunch_response(csp, rsp);
2944          }
2945
2946          /*
2947           * Temporary workaround to prevent already-read client
2948           * bodies from being parsed as new requests. For now we
2949           * err on the safe side and throw all the following
2950           * requests under the bus, even if no client body has been
2951           * buffered. A compliant client will repeat the dropped
2952           * requests on an untainted connection.
2953           *
2954           * The proper fix is to discard the no longer needed
2955           * client body in the buffer (if there is one) and to
2956           * continue parsing the bytes that follow.
2957           */
2958          drain_and_close_socket(csp->cfd);
2959          csp->cfd = JB_INVALID_SOCKET;
2960
2961          return;
2962       }
2963 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
2964       save_connection_destination(csp->server_connection.sfd,
2965          http, fwd, &csp->server_connection);
2966       csp->server_connection.keep_alive_timeout =
2967          (unsigned)csp->config->keep_alive_timeout;
2968    }
2969 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
2970
2971    csp->server_connection.requests_sent_total++;
2972
2973    if ((fwd->type == SOCKS_5T) && (NULL == csp->headers->first))
2974    {
2975       /* Client headers have been sent optimistically */
2976       assert(csp->headers->last == NULL);
2977    }
2978    else if (fwd->forward_host || (http->ssl == 0))
2979    {
2980       if (send_http_request(csp))
2981       {
2982          rsp = error_response(csp, "connect-failed");
2983          if (rsp)
2984          {
2985             send_crunch_response(csp, rsp);
2986          }
2987          return;
2988       }
2989    }
2990    else
2991    {
2992       /*
2993        * We're running an SSL tunnel and we're not forwarding,
2994        * so just ditch the client headers, send the "connect succeeded"
2995        * message to the client, flush the rest, and get out of the way.
2996        */
2997       list_remove_all(csp->headers);
2998       if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
2999       {
3000          return;
3001       }
3002       clear_iob(csp->client_iob);
3003    }
3004
3005    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
3006
3007    /* XXX: should the time start earlier for optimistically sent data? */
3008    csp->server_connection.request_sent = time(NULL);
3009
3010    handle_established_connection(csp);
3011    freez(csp->receive_buffer);
3012 }
3013
3014
3015 #ifdef FUZZ
3016 /*********************************************************************
3017  *
3018  * Function    :  fuzz_server_response
3019  *
3020  * Description :  Treat the input as a whole server response.
3021  *
3022  * Parameters  :
3023  *          1  :  csp = Current client state (buffers, headers, etc...)
3024  *          2  :  fuzz_input_file = File to read the input from.
3025  *
3026  * Returns     :  0
3027  *
3028  *********************************************************************/
3029 extern int fuzz_server_response(struct client_state *csp, char *fuzz_input_file)
3030 {
3031    static struct forward_spec fwd; /* Zero'd due to being static */
3032    csp->cfd = 0;
3033
3034    if (strcmp(fuzz_input_file, "-") == 0)
3035    {
3036       /* XXX: Doesn'T work yet. */
3037       csp->server_connection.sfd = 0;
3038    }
3039    else
3040    {
3041       csp->server_connection.sfd = open(fuzz_input_file, O_RDONLY);
3042       if (csp->server_connection.sfd == -1)
3043       {
3044          log_error(LOG_LEVEL_FATAL, "Failed to open %s: %E",
3045             fuzz_input_file);
3046       }
3047    }
3048    csp->fwd = &fwd;
3049    csp->content_type |= CT_GIF;
3050    csp->action->flags |= ACTION_DEANIMATE;
3051    csp->action->string[ACTION_STRING_DEANIMATE] = "last";
3052
3053    csp->http->path = strdup_or_die("/");
3054    csp->http->host = strdup_or_die("fuzz.example.org");
3055    csp->http->hostport = strdup_or_die("fuzz.example.org:80");
3056    /* Prevent client socket monitoring */
3057    csp->flags |= CSP_FLAG_PIPELINED_REQUEST_WAITING;
3058    csp->flags |= CSP_FLAG_CHUNKED;
3059
3060    csp->config->feature_flags |= RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE;
3061    csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
3062
3063    csp->content_type |= CT_DECLARED|CT_GIF;
3064
3065    csp->config->socket_timeout = 0;
3066
3067    cgi_init_error_messages();
3068
3069    handle_established_connection(csp);
3070    freez(csp->receive_buffer);
3071
3072    return 0;
3073 }
3074 #endif
3075
3076
3077 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3078 /*********************************************************************
3079  *
3080  * Function    :  prepare_csp_for_next_request
3081  *
3082  * Description :  Put the csp in a mostly vergin state.
3083  *
3084  * Parameters  :
3085  *          1  :  csp = Current client state (buffers, headers, etc...)
3086  *
3087  * Returns     :  N/A
3088  *
3089  *********************************************************************/
3090 static void prepare_csp_for_next_request(struct client_state *csp)
3091 {
3092    csp->content_type = 0;
3093    csp->content_length = 0;
3094    csp->expected_content_length = 0;
3095    csp->expected_client_content_length = 0;
3096    list_remove_all(csp->headers);
3097    clear_iob(csp->iob);
3098    freez(csp->error_message);
3099    free_http_request(csp->http);
3100    destroy_list(csp->headers);
3101    destroy_list(csp->tags);
3102 #ifdef FEATURE_CLIENT_TAGS
3103    destroy_list(csp->client_tags);
3104    freez(csp->client_address);
3105 #endif
3106    free_current_action(csp->action);
3107    if (NULL != csp->fwd)
3108    {
3109       unload_forward_spec(csp->fwd);
3110       csp->fwd = NULL;
3111    }
3112    /* XXX: Store per-connection flags someplace else. */
3113    csp->flags = (CSP_FLAG_ACTIVE | CSP_FLAG_REUSED_CLIENT_CONNECTION);
3114 #ifdef FEATURE_TOGGLE
3115    if (global_toggle_state)
3116 #endif /* def FEATURE_TOGGLE */
3117    {
3118       csp->flags |= CSP_FLAG_TOGGLED_ON;
3119    }
3120
3121    if (csp->client_iob->eod > csp->client_iob->cur)
3122    {
3123       long bytes_to_shift = csp->client_iob->cur - csp->client_iob->buf;
3124       size_t data_length  = (size_t)(csp->client_iob->eod - csp->client_iob->cur);
3125
3126       assert(bytes_to_shift > 0);
3127       assert(data_length > 0);
3128
3129       log_error(LOG_LEVEL_CONNECT, "Shifting %d pipelined bytes by %d bytes",
3130          data_length, bytes_to_shift);
3131       memmove(csp->client_iob->buf, csp->client_iob->cur, data_length);
3132       csp->client_iob->cur = csp->client_iob->buf;
3133       assert(csp->client_iob->eod == csp->client_iob->buf + bytes_to_shift + data_length);
3134       csp->client_iob->eod = csp->client_iob->buf + data_length;
3135       memset(csp->client_iob->eod, '\0', (size_t)bytes_to_shift);
3136
3137       csp->flags |= CSP_FLAG_PIPELINED_REQUEST_WAITING;
3138    }
3139    else
3140    {
3141       /*
3142        * We mainly care about resetting client_iob->cur so we don't
3143        * waste buffer space at the beginning and don't mess up the
3144        * request restoration done by cgi_show_request().
3145        *
3146        * Freeing the buffer itself isn't technically necessary,
3147        * but makes debugging more convenient.
3148        */
3149       clear_iob(csp->client_iob);
3150    }
3151 }
3152 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
3153
3154
3155 /*********************************************************************
3156  *
3157  * Function    :  serve
3158  *
3159  * Description :  This is little more than chat.  We only "serve" to
3160  *                to close (or remember) any socket that chat may have
3161  *                opened.
3162  *
3163  * Parameters  :
3164  *          1  :  csp = Current client state (buffers, headers, etc...)
3165  *
3166  * Returns     :  N/A
3167  *
3168  *********************************************************************/
3169 #ifdef AMIGA
3170 void serve(struct client_state *csp)
3171 #else /* ifndef AMIGA */
3172 static void serve(struct client_state *csp)
3173 #endif /* def AMIGA */
3174 {
3175    int config_file_change_detected = 0; /* Only used for debugging */
3176 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3177 #ifdef FEATURE_CONNECTION_SHARING
3178    static int monitor_thread_running = 0;
3179 #endif /* def FEATURE_CONNECTION_SHARING */
3180    int continue_chatting = 0;
3181
3182    log_error(LOG_LEVEL_CONNECT, "Accepted connection from %s on socket %d",
3183       csp->ip_addr_str, csp->cfd);
3184
3185    do
3186    {
3187       unsigned int latency;
3188
3189       chat(csp);
3190
3191       /*
3192        * If the request has been crunched,
3193        * the calculated latency is zero.
3194        */
3195       latency = (unsigned)(csp->server_connection.response_received -
3196          csp->server_connection.request_sent) / 2;
3197
3198       if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
3199          && (csp->flags & CSP_FLAG_CRUNCHED)
3200          && (csp->expected_client_content_length != 0))
3201       {
3202          csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
3203          log_error(LOG_LEVEL_CONNECT,
3204             "Tainting client socket %d due to unread data.", csp->cfd);
3205       }
3206
3207       continue_chatting = (csp->config->feature_flags
3208          & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
3209          && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
3210          && (csp->cfd != JB_INVALID_SOCKET)
3211          && (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
3212          && ((csp->flags & CSP_FLAG_SERVER_CONTENT_LENGTH_SET)
3213             || (csp->flags & CSP_FLAG_CHUNKED));
3214
3215       if (!(csp->flags & CSP_FLAG_CRUNCHED)
3216          && (csp->server_connection.sfd != JB_INVALID_SOCKET))
3217       {
3218          if (!(csp->flags & CSP_FLAG_SERVER_KEEP_ALIVE_TIMEOUT_SET))
3219          {
3220             csp->server_connection.keep_alive_timeout = csp->config->default_server_timeout;
3221          }
3222          if (!(csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
3223             || (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
3224             || !socket_is_still_alive(csp->server_connection.sfd)
3225             || !(latency < csp->server_connection.keep_alive_timeout))
3226          {
3227             log_error(LOG_LEVEL_CONNECT,
3228                "Closing server socket %d connected to %s. "
3229                "Keep-alive %u. Tainted: %u. Socket alive %u. Timeout: %u.",
3230                csp->server_connection.sfd, csp->server_connection.host,
3231                0 != (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE),
3232                0 != (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED),
3233                socket_is_still_alive(csp->server_connection.sfd),
3234                csp->server_connection.keep_alive_timeout);
3235 #ifdef FEATURE_CONNECTION_SHARING
3236             if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
3237             {
3238                forget_connection(csp->server_connection.sfd);
3239             }
3240 #endif /* def FEATURE_CONNECTION_SHARING */
3241             close_socket(csp->server_connection.sfd);
3242             mark_connection_closed(&csp->server_connection);
3243          }
3244       }
3245
3246       if (continue_chatting && any_loaded_file_changed(csp))
3247       {
3248          continue_chatting = 0;
3249          config_file_change_detected = 1;
3250       }
3251
3252       if (continue_chatting)
3253       {
3254          if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) != 0)
3255             && socket_is_still_alive(csp->cfd))
3256          {
3257             log_error(LOG_LEVEL_CONNECT, "Client request %d has been "
3258                "pipelined on socket %d and the socket is still alive.",
3259                csp->requests_received_total+1, csp->cfd);
3260             prepare_csp_for_next_request(csp);
3261             continue;
3262          }
3263
3264          if (0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
3265          {
3266             if (csp->server_connection.sfd != JB_INVALID_SOCKET)
3267             {
3268                log_error(LOG_LEVEL_CONNECT,
3269                   "Waiting for the next client request on socket %d. "
3270                   "Keeping the server socket %d to %s open.",
3271                   csp->cfd, csp->server_connection.sfd, csp->server_connection.host);
3272             }
3273             else
3274             {
3275                log_error(LOG_LEVEL_CONNECT,
3276                   "Waiting for the next client request on socket %d. "
3277                   "No server socket to keep open.", csp->cfd);
3278             }
3279          }
3280
3281          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
3282             && data_is_available(csp->cfd, (int)csp->config->keep_alive_timeout)
3283             && socket_is_still_alive(csp->cfd))
3284          {
3285             log_error(LOG_LEVEL_CONNECT,
3286                "Client request %u arrived in time on socket %d.",
3287                csp->requests_received_total+1, csp->cfd);
3288             prepare_csp_for_next_request(csp);
3289          }
3290          else
3291          {
3292 #ifdef FEATURE_CONNECTION_SHARING
3293             if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
3294                && (csp->server_connection.sfd != JB_INVALID_SOCKET)
3295                && (socket_is_still_alive(csp->server_connection.sfd)))
3296             {
3297                time_t time_open = time(NULL) - csp->server_connection.timestamp;
3298
3299                if (csp->server_connection.keep_alive_timeout < time_open - (time_t)latency)
3300                {
3301                   break;
3302                }
3303
3304                remember_connection(&csp->server_connection);
3305                csp->server_connection.sfd = JB_INVALID_SOCKET;
3306                drain_and_close_socket(csp->cfd);
3307                csp->cfd = JB_INVALID_SOCKET;
3308                privoxy_mutex_lock(&connection_reuse_mutex);
3309                if (!monitor_thread_running)
3310                {
3311                   monitor_thread_running = 1;
3312                   privoxy_mutex_unlock(&connection_reuse_mutex);
3313                   wait_for_alive_connections();
3314                   privoxy_mutex_lock(&connection_reuse_mutex);
3315                   monitor_thread_running = 0;
3316                }
3317                privoxy_mutex_unlock(&connection_reuse_mutex);
3318             }
3319 #endif /* def FEATURE_CONNECTION_SHARING */
3320             break;
3321          }
3322       }
3323       else if (csp->server_connection.sfd != JB_INVALID_SOCKET)
3324       {
3325          log_error(LOG_LEVEL_CONNECT,
3326             "Closing server socket %d connected to %s. Keep-alive: %u. "
3327             "Tainted: %u. Socket alive: %u. Timeout: %u. "
3328             "Configuration file change detected: %u",
3329             csp->server_connection.sfd, csp->server_connection.host,
3330             0 != (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE),
3331             0 != (csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED),
3332             socket_is_still_alive(csp->server_connection.sfd),
3333             csp->server_connection.keep_alive_timeout,
3334             config_file_change_detected);
3335       }
3336    } while (continue_chatting);
3337
3338 #else
3339    chat(csp);
3340 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
3341
3342    if (csp->server_connection.sfd != JB_INVALID_SOCKET)
3343    {
3344 #ifdef FEATURE_CONNECTION_SHARING
3345       if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
3346       {
3347          forget_connection(csp->server_connection.sfd);
3348       }
3349 #endif /* def FEATURE_CONNECTION_SHARING */
3350       close_socket(csp->server_connection.sfd);
3351    }
3352
3353 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
3354    mark_connection_closed(&csp->server_connection);
3355 #endif
3356
3357    if (csp->cfd != JB_INVALID_SOCKET)
3358    {
3359       log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. "
3360          "Keep-alive: %u. Socket alive: %u. Data available: %u. "
3361          "Configuration file change detected: %u. Requests received: %u.",
3362          csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE),
3363          socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0),
3364          config_file_change_detected, csp->requests_received_total);
3365       drain_and_close_socket(csp->cfd);
3366    }
3367
3368    free_csp_resources(csp);
3369
3370    csp->flags &= ~CSP_FLAG_ACTIVE;
3371
3372 }
3373
3374
3375 #ifdef __BEOS__
3376 /*********************************************************************
3377  *
3378  * Function    :  server_thread
3379  *
3380  * Description :  We only exist to call `serve' in a threaded environment.
3381  *
3382  * Parameters  :
3383  *          1  :  data = Current client state (buffers, headers, etc...)
3384  *
3385  * Returns     :  Always 0.
3386  *
3387  *********************************************************************/
3388 static int32 server_thread(void *data)
3389 {
3390    serve((struct client_state *) data);
3391    return 0;
3392
3393 }
3394 #endif
3395
3396
3397 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3398 /*********************************************************************
3399  *
3400  * Function    :  usage
3401  *
3402  * Description :  Print usage info & exit.
3403  *
3404  * Parameters  :  Pointer to argv[0] for identifying ourselves
3405  *
3406  * Returns     :  No. ,-)
3407  *
3408  *********************************************************************/
3409 static void usage(const char *name)
3410 {
3411    printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n"
3412           "Usage: %s [--config-test] "
3413 #if defined(unix)
3414           "[--chroot] "
3415 #endif /* defined(unix) */
3416           "[--help] "
3417 #if defined(unix)
3418           "[--no-daemon] [--pidfile pidfile] [--pre-chroot-nslookup hostname] [--user user[.group]] "
3419 #endif /* defined(unix) */
3420          "[--version] [configfile]\n",
3421           name);
3422
3423 #ifdef FUZZ
3424    show_fuzz_usage(name);
3425 #endif
3426
3427    printf("Aborting\n");
3428
3429    exit(2);
3430
3431 }
3432 #endif /* #if !defined(_WIN32) || defined(_WIN_CONSOLE) */
3433
3434
3435 #ifdef MUTEX_LOCKS_AVAILABLE
3436 /*********************************************************************
3437  *
3438  * Function    :  privoxy_mutex_lock
3439  *
3440  * Description :  Locks a mutex.
3441  *
3442  * Parameters  :
3443  *          1  :  mutex = The mutex to lock.
3444  *
3445  * Returns     :  Void. May exit in case of errors.
3446  *
3447  *********************************************************************/
3448 void privoxy_mutex_lock(privoxy_mutex_t *mutex)
3449 {
3450 #ifdef FEATURE_PTHREAD
3451    int err = pthread_mutex_lock(mutex);
3452    if (err)
3453    {
3454       if (mutex != &log_mutex)
3455       {
3456          log_error(LOG_LEVEL_FATAL,
3457             "Mutex locking failed: %s.\n", strerror(err));
3458       }
3459       exit(1);
3460    }
3461 #else
3462    EnterCriticalSection(mutex);
3463 #endif /* def FEATURE_PTHREAD */
3464 }
3465
3466
3467 /*********************************************************************
3468  *
3469  * Function    :  privoxy_mutex_unlock
3470  *
3471  * Description :  Unlocks a mutex.
3472  *
3473  * Parameters  :
3474  *          1  :  mutex = The mutex to unlock.
3475  *
3476  * Returns     :  Void. May exit in case of errors.
3477  *
3478  *********************************************************************/
3479 void privoxy_mutex_unlock(privoxy_mutex_t *mutex)
3480 {
3481 #ifdef FEATURE_PTHREAD
3482    int err = pthread_mutex_unlock(mutex);
3483    if (err)
3484    {
3485       if (mutex != &log_mutex)
3486       {
3487          log_error(LOG_LEVEL_FATAL,
3488             "Mutex unlocking failed: %s.\n", strerror(err));
3489       }
3490       exit(1);
3491    }
3492 #else
3493    LeaveCriticalSection(mutex);
3494 #endif /* def FEATURE_PTHREAD */
3495 }
3496
3497
3498 /*********************************************************************
3499  *
3500  * Function    :  privoxy_mutex_init
3501  *
3502  * Description :  Prepares a mutex.
3503  *
3504  * Parameters  :
3505  *          1  :  mutex = The mutex to initialize.
3506  *
3507  * Returns     :  Void. May exit in case of errors.
3508  *
3509  *********************************************************************/
3510 static void privoxy_mutex_init(privoxy_mutex_t *mutex)
3511 {
3512 #ifdef FEATURE_PTHREAD
3513    int err = pthread_mutex_init(mutex, 0);
3514    if (err)
3515    {
3516       printf("Fatal error. Mutex initialization failed: %s.\n",
3517          strerror(err));
3518       exit(1);
3519    }
3520 #else
3521    InitializeCriticalSection(mutex);
3522 #endif /* def FEATURE_PTHREAD */
3523 }
3524 #endif /* def MUTEX_LOCKS_AVAILABLE */
3525
3526 /*********************************************************************
3527  *
3528  * Function    :  initialize_mutexes
3529  *
3530  * Description :  Prepares mutexes if mutex support is available.
3531  *
3532  * Parameters  :  None
3533  *
3534  * Returns     :  Void, exits in case of errors.
3535  *
3536  *********************************************************************/
3537 static void initialize_mutexes(void)
3538 {
3539 #ifdef MUTEX_LOCKS_AVAILABLE
3540    /*
3541     * Prepare global mutex semaphores
3542     */
3543    privoxy_mutex_init(&log_mutex);
3544    privoxy_mutex_init(&log_init_mutex);
3545    privoxy_mutex_init(&connection_reuse_mutex);
3546 #ifdef FEATURE_EXTERNAL_FILTERS
3547    privoxy_mutex_init(&external_filter_mutex);
3548 #endif
3549 #ifdef FEATURE_CLIENT_TAGS
3550    privoxy_mutex_init(&client_tags_mutex);
3551 #endif
3552
3553    /*
3554     * XXX: The assumptions below are a bit naive
3555     * and can cause locks that aren't necessary.
3556     *
3557     * For example older FreeBSD versions (< 6.x?)
3558     * have no gethostbyname_r, but gethostbyname is
3559     * thread safe.
3560     */
3561 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
3562    privoxy_mutex_init(&resolver_mutex);
3563 #endif /* !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) */
3564    /*
3565     * XXX: should we use a single mutex for
3566     * localtime() and gmtime() as well?
3567     */
3568 #ifndef HAVE_GMTIME_R
3569    privoxy_mutex_init(&gmtime_mutex);
3570 #endif /* ndef HAVE_GMTIME_R */
3571
3572 #ifndef HAVE_LOCALTIME_R
3573    privoxy_mutex_init(&localtime_mutex);
3574 #endif /* ndef HAVE_GMTIME_R */
3575
3576 #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_RANDOM)
3577    privoxy_mutex_init(&rand_mutex);
3578 #endif /* !defined(HAVE_ARC4RANDOM) && !defined(HAVE_RANDOM) */
3579
3580 #endif /* def MUTEX_LOCKS_AVAILABLE */
3581 }
3582
3583 /*********************************************************************
3584  *
3585  * Function    :  main
3586  *
3587  * Description :  Load the config file and start the listen loop.
3588  *                This function is a lot more *sane* with the `load_config'
3589  *                and `listen_loop' functions; although it stills does
3590  *                a *little* too much for my taste.
3591  *
3592  * Parameters  :
3593  *          1  :  argc = Number of parameters (including $0).
3594  *          2  :  argv = Array of (char *)'s to the parameters.
3595  *
3596  * Returns     :  1 if : can't open config file, unrecognized directive,
3597  *                stats requested in multi-thread mode, can't open the
3598  *                log file, can't open the jar file, listen port is invalid,
3599  *                any load fails, and can't bind port.
3600  *
3601  *                Else main never returns, the process must be signaled
3602  *                to terminate execution.  Or, on Windows, use the
3603  *                "File", "Exit" menu option.
3604  *
3605  *********************************************************************/
3606 #ifdef __MINGW32__
3607 int real_main(int argc, char **argv)
3608 #else
3609 int main(int argc, char **argv)
3610 #endif
3611 {
3612    int argc_pos = 0;
3613    int do_config_test = 0;
3614 #ifndef HAVE_ARC4RANDOM
3615    unsigned int random_seed;
3616 #endif
3617 #ifdef unix
3618    struct passwd *pw = NULL;
3619    struct group *grp = NULL;
3620    int do_chroot = 0;
3621    char *pre_chroot_nslookup_to_load_resolver = NULL;
3622 #endif
3623 #ifdef FUZZ
3624    char *fuzz_input_type = NULL;
3625    char *fuzz_input_file = NULL;
3626 #endif
3627
3628    Argc = argc;
3629    Argv = argv;
3630
3631    configfile =
3632 #if !defined(_WIN32)
3633    "config"
3634 #else
3635    "config.txt"
3636 #endif
3637       ;
3638
3639    /* Prepare mutexes if supported and necessary. */
3640    initialize_mutexes();
3641
3642    /* Enable logging until further notice. */
3643    init_log_module();
3644
3645    /*
3646     * Parse the command line arguments
3647     *
3648     * XXX: simply printing usage information in case of
3649     * invalid arguments isn't particularly user friendly.
3650     */
3651    while (++argc_pos < argc)
3652    {
3653 #ifdef _WIN32
3654       /* Check to see if the service must be installed or uninstalled */
3655       if (strncmp(argv[argc_pos], "--install", 9) == 0)
3656       {
3657          const char *pName = argv[argc_pos] + 9;
3658          if (*pName == ':')
3659             pName++;
3660          exit((install_service(pName)) ? 0 : 1);
3661       }
3662       else if (strncmp(argv[argc_pos], "--uninstall", 11) == 0)
3663       {
3664          const char *pName = argv[argc_pos] + 11;
3665          if (*pName == ':')
3666             pName++;
3667          exit((uninstall_service(pName)) ? 0 : 1);
3668       }
3669       else if (strcmp(argv[argc_pos], "--service") == 0)
3670       {
3671          bRunAsService = TRUE;
3672          w32_set_service_cwd();
3673          atexit(w32_service_exit_notify);
3674       }
3675       else
3676 #endif /* defined(_WIN32) */
3677
3678
3679 #if !defined(_WIN32) || defined(_WIN_CONSOLE)
3680
3681       if (strcmp(argv[argc_pos], "--help") == 0)
3682       {
3683          usage(argv[0]);
3684       }
3685
3686       else if (strcmp(argv[argc_pos], "--version") == 0)
3687       {
3688          printf("Privoxy version " VERSION " (" HOME_PAGE_URL ")\n");
3689          exit(0);
3690       }
3691
3692 #if defined(unix)
3693
3694       else if (strcmp(argv[argc_pos], "--no-daemon") == 0)
3695       {
3696          set_debug_level(LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO);
3697          daemon_mode = 0;
3698       }
3699
3700       else if (strcmp(argv[argc_pos], "--pidfile") == 0)
3701       {
3702          if (++argc_pos == argc) usage(argv[0]);
3703          pidfile = strdup_or_die(argv[argc_pos]);
3704       }
3705
3706       else if (strcmp(argv[argc_pos], "--user") == 0)
3707       {
3708          char *user_arg;
3709          char *group_name;
3710
3711          if (++argc_pos == argc) usage(argv[argc_pos]);
3712
3713          user_arg = strdup_or_die(argv[argc_pos]);
3714          group_name = strchr(user_arg, '.');
3715          if (NULL != group_name)
3716          {
3717             /* Nul-terminate the user name */
3718             *group_name = '\0';
3719
3720             /* Skip the former delimiter to actually reach the group name */
3721             group_name++;
3722
3723             grp = getgrnam(group_name);
3724             if (NULL == grp)
3725             {
3726                log_error(LOG_LEVEL_FATAL, "Group '%s' not found.", group_name);
3727             }
3728          }
3729          pw = getpwnam(user_arg);
3730          if (NULL == pw)
3731          {
3732             log_error(LOG_LEVEL_FATAL, "User '%s' not found.", user_arg);
3733          }
3734
3735          freez(user_arg);
3736       }
3737
3738       else if (strcmp(argv[argc_pos], "--pre-chroot-nslookup") == 0)
3739       {
3740          if (++argc_pos == argc) usage(argv[0]);
3741          pre_chroot_nslookup_to_load_resolver = strdup_or_die(argv[argc_pos]);
3742       }
3743
3744       else if (strcmp(argv[argc_pos], "--chroot") == 0)
3745       {
3746          do_chroot = 1;
3747       }
3748 #endif /* defined(unix) */
3749
3750       else if (strcmp(argv[argc_pos], "--config-test") == 0)
3751       {
3752          do_config_test = 1;
3753       }
3754 #ifdef FUZZ
3755       else if (strcmp(argv[argc_pos], "--fuzz") == 0)
3756       {
3757          argc_pos++;
3758          if (argc < argc_pos + 2) usage(argv[0]);
3759          fuzz_input_type = argv[argc_pos];
3760          argc_pos++;
3761          fuzz_input_file = argv[argc_pos];
3762       }
3763       else if (strcmp(argv[argc_pos], "--stfu") == 0)
3764       {
3765          set_debug_level(LOG_LEVEL_STFU);
3766       }
3767 #endif
3768       else if (argc_pos + 1 != argc)
3769       {
3770          /*
3771           * This is neither the last command line
3772           * option, nor was it recognized before,
3773           * therefore it must be invalid.
3774           */
3775          usage(argv[0]);
3776       }
3777       else
3778
3779 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
3780       {
3781          configfile = argv[argc_pos];
3782       }
3783
3784    } /* -END- while (more arguments) */
3785
3786    show_version(Argv[0]);
3787
3788 #if defined(unix)
3789    if (*configfile != '/')
3790    {
3791       char cwd[BUFFER_SIZE];
3792       char *abs_file;
3793       size_t abs_file_size;
3794
3795       /* make config-filename absolute here */
3796       if (NULL == getcwd(cwd, sizeof(cwd)))
3797       {
3798          perror("failed to get current working directory");
3799          exit(1);
3800       }
3801
3802       basedir = strdup_or_die(cwd);
3803       /* XXX: why + 5? */
3804       abs_file_size = strlen(cwd) + strlen(configfile) + 5;
3805       abs_file = malloc_or_die(abs_file_size);
3806       strlcpy(abs_file, basedir, abs_file_size);
3807       strlcat(abs_file, "/", abs_file_size);
3808       strlcat(abs_file, configfile, abs_file_size);
3809       configfile = abs_file;
3810    }
3811 #endif /* defined unix */
3812
3813
3814    files->next = NULL;
3815    clients->next = NULL;
3816
3817    /* XXX: factor out initialising after the next stable release. */
3818 #ifdef AMIGA
3819    InitAmiga();
3820 #elif defined(_WIN32)
3821    InitWin32();
3822 #endif
3823