X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=5a05d08660bcff7ec8f18a8479ce350475a8e39a;hp=82ab45384544767eaf07e632a74bb890d0bb9f3d;hb=7c7592fae8bbc71e2b255289e5a1eebd752e4dfc;hpb=5ee3e711d51e9fc40564f25fed2dccde2c76656c diff --git a/jcc.c b/jcc.c index 82ab4538..5a05d086 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.168 2008/03/02 12:25:25 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.173 2008/05/06 15:09:00 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -6,7 +6,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.168 2008/03/02 12:25:25 fabiankeil Exp $" * Purpose : Main file. Contains main() method, main loop, and * the main connection-handling function. * - * Copyright : Written by and Copyright (C) 2001-2007 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2008 the SourceForge * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -33,6 +33,25 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.168 2008/03/02 12:25:25 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.173 2008/05/06 15:09:00 fabiankeil + * Least-effort fix for bug #1821930 (reported by Lee): + * If the response doesn't look like HTTP, + * tell the client and log the problem. + * + * Revision 1.172 2008/04/16 16:38:21 fabiankeil + * Don't pass the whole csp structure to flush_socket() + * when it only needs a file descriptor and a buffer. + * + * Revision 1.171 2008/03/27 18:27:25 fabiankeil + * Remove kill-popups action. + * + * Revision 1.170 2008/03/06 16:33:46 fabiankeil + * If limit-connect isn't used, don't limit CONNECT requests to port 443. + * + * Revision 1.169 2008/03/04 18:30:39 fabiankeil + * Remove the treat-forbidden-connects-like-blocks action. We now + * use the "blocked" page for forbidden CONNECT requests by default. + * * Revision 1.168 2008/03/02 12:25:25 fabiankeil * Also use shiny new connect_port_is_forbidden() in jcc.c. * @@ -1040,7 +1059,6 @@ http://www.fabiankeil.de/sourcecode/privoxy/ #include "filters.h" #include "loaders.h" #include "parsers.h" -#include "killpopup.h" #include "miscutil.h" #include "errlog.h" #include "jbsockets.h" @@ -1175,6 +1193,14 @@ static const char NO_SERVER_DATA_RESPONSE[] = "Empty server or forwarder response.\r\n" "The connection has been closed but Privoxy didn't receive any data.\r\n"; +/* XXX: should be a template */ +static const char INVALID_SERVER_HEADERS_RESPONSE[] = + "HTTP/1.0 502 Server or forwarder response invalid\r\n" + "Proxy-Agent: Privoxy " VERSION "\r\n" + "Content-Type: text/plain\r\n" + "Connection: close\r\n\r\n" + "Bad response. The server or forwarder response doesn't look like HTTP.\r\n"; + #if 0 /* XXX: should be a template */ static const char NULL_BYTE_RESPONSE[] = @@ -1299,8 +1325,6 @@ static void sig_handler(int the_signal) *********************************************************************/ static int client_protocol_is_unsupported(const struct client_state *csp, char *req) { - char buf[BUFFER_SIZE]; - /* * If it's a FTP or gopher request, we don't support it. * @@ -1316,21 +1340,26 @@ static int client_protocol_is_unsupported(const struct client_state *csp, char * */ if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13)) { + const char *response = NULL; + const char *protocol = NULL; + if (!strncmpic(req, "GET ftp://", 10)) { - strlcpy(buf, FTP_RESPONSE, sizeof(buf)); - log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s", - csp->ip_addr_str, req); + response = FTP_RESPONSE; + protocol = "FTP"; } else { - strlcpy(buf, GOPHER_RESPONSE, sizeof(buf)); - log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as gopher proxy: %s", - csp->ip_addr_str, req); + response = GOPHER_RESPONSE; + protocol = "GOPHER"; } - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req); + log_error(LOG_LEVEL_ERROR, + "%s tried to use Privoxy as %s proxy: %s", + csp->ip_addr_str, protocol, req); + log_error(LOG_LEVEL_CLF, + "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req); freez(req); - write_socket(csp->cfd, buf, strlen(buf)); + write_socket(csp->cfd, response, strlen(response)); return TRUE; } @@ -1912,9 +1941,6 @@ static void chat(struct client_state *csp) struct http_request *http; int len; /* for buffer sizes (and negative error codes) */ jb_err err; -#ifdef FEATURE_KILL_POPUPS - int block_popups_now = 0; /* bool, 1==currently blocking popups */ -#endif /* def FEATURE_KILL_POPUPS */ /* Function that does the content filtering for the current request */ filter_function_ptr content_filter = NULL; @@ -2192,9 +2218,8 @@ static void chat(struct client_state *csp) if (http->ssl && connect_port_is_forbidden(csp)) { const char *acceptable_connect_ports = - csp->action->string[ACTION_STRING_LIMIT_CONNECT] ? - csp->action->string[ACTION_STRING_LIMIT_CONNECT] : - "443 (implied default)"; + csp->action->string[ACTION_STRING_LIMIT_CONNECT]; + assert(NULL != acceptable_connect_ports); log_error(LOG_LEVEL_INFO, "Request from %s marked for blocking. " "limit-connect{%s} doesn't allow CONNECT requests to port %d.", csp->ip_addr_str, acceptable_connect_ports, csp->http->port); @@ -2297,7 +2322,7 @@ static void chat(struct client_state *csp) */ if (write_socket(csp->sfd, hdr, strlen(hdr)) - || (flush_socket(csp->sfd, csp) < 0)) + || (flush_socket(csp->sfd, csp->iob) < 0)) { log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E", http->hostport); @@ -2440,14 +2465,6 @@ static void chat(struct client_state *csp) */ buf[len] = '\0'; -#ifdef FEATURE_KILL_POPUPS - /* Filter the popups on this read. */ - if (block_popups_now) - { - filter_popups(buf, csp); - } -#endif /* def FEATURE_KILL_POPUPS */ - /* Normally, this would indicate that we've read * as much as the server has sent us and we can * close the client connection. However, Microsoft @@ -2579,7 +2596,7 @@ static void chat(struct client_state *csp) hdrlen = strlen(hdr); if (write_socket(csp->cfd, hdr, hdrlen) - || ((flushed = flush_socket(csp->cfd, csp)) < 0) + || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0) || (write_socket(csp->cfd, buf, (size_t)len))) { log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); @@ -2665,6 +2682,29 @@ static void chat(struct client_state *csp) return; } + assert(csp->headers->first->str); + assert(!http->ssl); + if (strncmpic(csp->headers->first->str, "HTTP", 4)) + { + /* + * It doesn't look like a HTTP response: + * tell the client and log the problem. + */ + if (strlen(csp->headers->first->str) > 30) + { + csp->headers->first->str[30] = '\0'; + } + log_error(LOG_LEVEL_ERROR, + "Invalid server or forwarder response. Starts with: %s", + csp->headers->first->str); + log_error(LOG_LEVEL_CLF, + "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); + write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE)); + free_http_request(http); + return; + } + /* we have now received the entire header. * filter it and send the result to the client */ @@ -2694,20 +2734,6 @@ static void chat(struct client_state *csp) if (!http->ssl) /* We talk plaintext */ { - -#ifdef FEATURE_KILL_POPUPS - /* Start blocking popups if appropriate. */ - if ((csp->content_type & CT_TEXT) && /* It's a text / * MIME-Type */ - (csp->action->flags & ACTION_NO_POPUPS) != 0) /* Policy allows */ - { - block_popups_now = 1; - /* - * Filter the part of the body that came in the same read - * as the last headers: - */ - filter_popups(csp->iob->cur, csp); - } -#endif /* def FEATURE_KILL_POPUPS */ content_filter = get_filter_function(csp); } /* @@ -2721,7 +2747,7 @@ static void chat(struct client_state *csp) */ if (write_socket(csp->cfd, hdr, strlen(hdr)) - || ((len = flush_socket(csp->cfd, csp)) < 0)) + || ((len = flush_socket(csp->cfd, csp->iob)) < 0)) { log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");