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