X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=jcc.c;h=7c09830b8cf92311c3c3ffbdcbec3248e247a576;hb=ef90a49bca7cc597192e8e3d77de6de9cdf88f57;hp=77b13797274bdd388dd056521bdf45a17bf50e38;hpb=433e5bc964858dbd9a5257549146de2b8bd3279f;p=privoxy.git diff --git a/jcc.c b/jcc.c index 77b13797..7c09830b 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.42 2001/09/21 23:02:02 david__schmidt Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.47 2001/10/10 16:44:36 oes Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,37 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.42 2001/09/21 23:02:02 david__schmidt Exp * * Revisions : * $Log: jcc.c,v $ + * Revision 1.47 2001/10/10 16:44:36 oes + * Added CONNECT destination port limitation check + * + * Revision 1.46 2001/10/08 15:17:41 oes + * Re-enabled SSL forwarding + * + * Revision 1.45 2001/10/07 15:42:11 oes + * Replaced 6 boolean members of csp with one bitmap (csp->flags) + * + * Moved downgrading of the HTTP version from parse_http_request to + * chat(), since we can't decide if it is necessary before we have + * determined the actions for the URL. The HTTP command is now + * *always* re-built so the repairs need no longer be special-cased. + * + * filter_popups now gets a csp pointer so it can raise the new + * CSP_FLAG_MODIFIED flag. + * + * Bugfix + * + * Added configurable size limit for the IOB. If the IOB grows so + * large that the next read would exceed the limit, the header + * is generated, and the header & unfiltered buffer are flushed + * to the client. Chat then continues in non-buffering, + * non-filtering body mode. + * + * Revision 1.44 2001/10/02 18:13:57 oes + * Ooops + * + * Revision 1.43 2001/10/02 15:32:13 oes + * Moved generation of hdr + * * Revision 1.42 2001/09/21 23:02:02 david__schmidt * Cleaning up 2 compiler warnings on OS/2. * @@ -426,17 +457,17 @@ static void chat(struct client_state *csp) { /* * This next lines are a little ugly, but they simplifies the if statements - * below. Basically if TOGGLE, then we want the if to test "csp->toggled_on", - * else we don't. And if FEATURE_FORCE_LOAD, then we want the if to test - * "csp->toggled_on", else we don't + * below. Basically if TOGGLE, then we want the if to test if the + * CSP_FLAG_TOGGLED_ON flag ist set, else we don't. And if FEATURE_FORCE_LOAD, + * then we want the if to test for CSP_FLAG_FORCED , else we don't */ #ifdef FEATURE_TOGGLE -# define IS_TOGGLED_ON_AND (csp->toggled_on) && +# define IS_TOGGLED_ON_AND (csp->flags & CSP_FLAG_TOGGLED_ON) && #else /* ifndef FEATURE_TOGGLE */ # define IS_TOGGLED_ON_AND #endif /* ndef FEATURE_TOGGLE */ #ifdef FEATURE_FORCE_LOAD -# define IS_NOT_FORCED_AND (!csp->force) && +# define IS_NOT_FORCED_AND !(csp->flags & CSP_FLAG_FORCED) && #else /* ifndef FEATURE_FORCE_LOAD */ # define IS_NOT_FORCED_AND #endif /* def FEATURE_FORCE_LOAD */ @@ -501,12 +532,9 @@ static void chat(struct client_state *csp) { strclean(req, FORCE_PREFIX); log_error(LOG_LEVEL_FORCE, "Enforcing request \"%s\".\n", req); - csp->force = 1; + csp->flags |= CSP_FLAG_FORCED; } - else - { - csp->force = 0; - } + #endif /* def FEATURE_FORCE_LOAD */ parse_http_request(req, http, csp); @@ -536,62 +564,113 @@ static void chat(struct client_state *csp) * we have to do one of the following: * * create = use the original HTTP request to create a new - * HTTP request that has only the path component - * without the http://domainspec - * pass = pass the original HTTP request unchanged + * HTTP request that has either the path component + * without the http://domainspec (w/path) or the + * full orininal URL (w/url) + * Note that the path and/or the HTTP version may + * have been altered by now. + * + * connect = Open a socket to the host:port of the server + * and short-circuit server and client socket. * - * drop = drop the HTTP request + * pass = Pass the request unchanged if forwarding a CONNECT + * request to a parent proxy. Note that we'll be sending + * the CFAIL message ourselves if connecting to the parent + * fails, but we won't send a CSUCCEED message if it works, + * since that would result in a double message (ours and the + * parent's). After sending the request to the parent, we simply + * tunnel. * - * here's the matrix: + * here's the matrix: * SSL * 0 1 * +--------+--------+ * | | | - * 0 | create | drop | - * | | | + * 0 | create | connect| + * | w/path | | * Forwarding +--------+--------+ * | | | - * 1 | pass | pass | - * | | | + * 1 | create | pass | + * | w/url | | * +--------+--------+ * */ - if (fwd->forward_host) + /* + * Determine the actions for this URL + */ +#ifdef FEATURE_TOGGLE + if (!(csp->flags & CSP_FLAG_TOGGLED_ON)) { - /* if forwarding, just pass the request as is */ - enlist(csp->headers, http->cmd); + /* Most compatible set of actions (i.e. none) */ + init_current_action(csp->action); } else +#endif /* ndef FEATURE_TOGGLE */ { - if (http->ssl == 0) - { - /* otherwise elide the host information from the url */ - p = NULL; - p = strsav(p, http->gpc); - p = strsav(p, " "); - p = strsav(p, http->path); - p = strsav(p, " "); - p = strsav(p, http->ver); - enlist(csp->headers, p); - freez(p); - } + url_actions(http, csp); } - /* decide what we're to do with cookies */ -#ifdef FEATURE_TOGGLE - if (!csp->toggled_on) + /* + * Check if a CONNECT request is allowable: + * In the absence of a +limit-connect action, allow only port 443. + * If there is an action, allow whatever matches the specificaton. + */ + if(http->ssl) { - /* Most compatible set of actions (i.e. none) */ - init_current_action(csp->action); + if( ( !(csp->action->flags & ACTION_LIMIT_CONNECT) && csp->http->port != 443) + || (csp->action->flags & ACTION_LIMIT_CONNECT + && !match_portlist(csp->action->string[ACTION_STRING_LIMIT_CONNECT], csp->http->port)) ) + { + strcpy(buf, CFORBIDDEN); + write_socket(csp->cfd, buf, strlen(buf)); + + log_error(LOG_LEVEL_CONNECT, "Denying suspicious CONNECT request from %s", csp->ip_addr_str); + log_error(LOG_LEVEL_CLF, "%s - - [%T] \" \" 403 0", csp->ip_addr_str); + + return; + } } - else -#endif /* ndef FEATURE_TOGGLE */ + + + /* + * Downgrade http version from 1.1 to 1.0 if +downgrade + * action applies + */ + if (!strcmpic(http->ver, "HTTP/1.1") && csp->action->flags & ACTION_DOWNGRADE) { - url_actions(http, csp); + freez(http->ver); + http->ver = strdup("HTTP/1.0"); } + /* + * (Re)build the HTTP request for non-SSL requests. + * If forwarding, use the whole URL, else, use only the path. + */ + if (http->ssl == 0) + { + freez(http->cmd); + + http->cmd = strsav(http->cmd, http->gpc); + http->cmd = strsav(http->cmd, " "); + + if (fwd->forward_host) + { + http->cmd = strsav(http->cmd, http->url); + } + else + { + http->cmd = strsav(http->cmd, http->path); + } + + http->cmd = strsav(http->cmd, " "); + http->cmd = strsav(http->cmd, http->ver); + + } + enlist(csp->headers, http->cmd); + + #ifdef FEATURE_COOKIE_JAR /* * If we're logging cookies in a cookie jar, and the user has not @@ -606,6 +685,7 @@ static void chat(struct client_state *csp) } #endif /* def FEATURE_COOKIE_JAR */ + #ifdef FEATURE_KILL_POPUPS block_popups = ((csp->action->flags & ACTION_NO_POPUPS) != 0); #endif /* def FEATURE_KILL_POPUPS */ @@ -676,7 +756,7 @@ static void chat(struct client_state *csp) #ifdef FEATURE_STATISTICS /* Count as a rejected request */ - csp->rejected = 1; + csp->flags |= CSP_FLAG_REJECTED; #endif /* def FEATURE_STATISTICS */ /* Log (FIXME: All intercept reasons apprear as "crunch" with Status 200) */ @@ -741,6 +821,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_CONNECT, "OK"); hdr = sed(client_patterns, add_client_headers, csp); + list_remove_all(csp->headers); if (fwd->forward_host || (http->ssl == 0)) { @@ -883,7 +964,7 @@ static void chat(struct client_state *csp) /* Filter the popups on this read. */ if (block_popups_now) { - filter_popups(buf); + filter_popups(buf, csp); } #endif /* def FEATURE_KILL_POPUPS */ @@ -933,12 +1014,14 @@ static void chat(struct client_state *csp) if ((write_socket(csp->cfd, hdr, n) != n) || (write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length) != (int)csp->content_length)) { - log_error(LOG_LEVEL_CONNECT, "write modified content to client failed: %E"); + log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E"); return; } freez(hdr); - freez(p); + if (NULL != p) { + freez(p); + } } break; /* "game over, man" */ @@ -969,6 +1052,36 @@ static void chat(struct client_state *csp) if (content_filter) { add_to_iob(csp, buf, n); + + /* + * If the buffer limit will be reached on the next read, + * switch to non-filtering mode, i.e. make & write the + * header, flush the socket and get out of the way. + */ + if (csp->iob->eod - csp->iob->buf + BUFFER_SIZE > csp->config->buffer_limit) + { + log_error(LOG_LEVEL_ERROR, "Buffer size limit reached! Flushing and stepping back."); + + hdr = sed(server_patterns, add_server_headers, csp); + n = strlen(hdr); + byte_count += n; + + if (((write_socket(csp->cfd, hdr, n) != n) + || (n = flush_socket(csp->cfd, csp) < 0))) + { + log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E"); + + freez(hdr); + return; + } + + freez(hdr); + byte_count += n; + + content_filter = NULL; + server_body = 1; + + } } else { @@ -1057,7 +1170,7 @@ static void chat(struct client_state *csp) * Filter the part of the body that came in the same read * as the last headers: */ - filter_popups(csp->iob->cur); + filter_popups(csp->iob->cur, csp); } #endif /* def FEATURE_KILL_POPUPS */ @@ -1152,7 +1265,7 @@ static void serve(struct client_state *csp) close_socket(csp->sfd); } - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; } @@ -1330,7 +1443,7 @@ static void listen_loop(void) continue; } - csp->active = 1; + csp->flags |= CSP_FLAG_ACTIVE; csp->sfd = -1; csp->config = config = load_config(); @@ -1392,8 +1505,10 @@ static void listen_loop(void) } #ifdef FEATURE_TOGGLE - /* by haroon - most of credit to srt19170 */ - csp->toggled_on = g_bToggleIJB; + if (g_bToggleIJB) + { + csp->flags |= CSP_FLAG_TOGGLED_ON; + } #endif /* def FEATURE_TOGGLE */ if (run_loader(csp)) @@ -1505,7 +1620,7 @@ static void listen_loop(void) wait( NULL ); #endif /* !defined(_WIN32) && defined(__CYGWIN__) */ close_socket(csp->cfd); - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; } #endif @@ -1522,7 +1637,7 @@ static void listen_loop(void) write_socket(csp->cfd, buf, strlen(buf)); close_socket(csp->cfd); - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; sleep(5); continue; }