X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=filters.c;h=744af6a204abdd067c6a1e0f7bedeb1dcba871fa;hp=cff05c4a9bf24d3dc8aacc0531c4b31721aba4e9;hb=72081f829de368392d04076728f8c991178c0080;hpb=91f8d1cfa59b145296b7b5dc4ee07bdb32517b8b diff --git a/filters.c b/filters.c index cff05c4a..744af6a2 100644 --- a/filters.c +++ b/filters.c @@ -1,7 +1,7 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.53 2002/03/26 22:29:54 swa Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.58.2.9 2006/01/29 23:10:56 david__schmidt Exp $"; /********************************************************************* * - * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ + * File : $Source: /cvsroot/ijbswa/current/Attic/filters.c,v $ * * Purpose : Declares functions to parse/crunch headers and pages. * Functions declared include: @@ -9,9 +9,10 @@ const char filters_rcs[] = "$Id: filters.c,v 1.53 2002/03/26 22:29:54 swa Exp $" * `block_url', `url_actions', `domain_split', * `filter_popups', `forward_url', 'redirect_url', * `ij_untrusted_url', `intercept_url', `pcrs_filter_respose', - * 'ijb_send_banner', and `trust_url' + * `ijb_send_banner', `trust_url', `gif_deanimate_response', + * `jpeg_inspect_response' * - * Copyright : Written by and Copyright (C) 2001 the SourceForge + * Copyright : Written by and Copyright (C) 2001, 2004 the SourceForge * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -38,6 +39,61 @@ const char filters_rcs[] = "$Id: filters.c,v 1.53 2002/03/26 22:29:54 swa Exp $" * * Revisions : * $Log: filters.c,v $ + * Revision 1.58.2.9 2006/01/29 23:10:56 david__schmidt + * Multiple filter file support + * + * Revision 1.58.2.8 2005/05/07 21:50:55 david__schmidt + * A few memory leaks plugged (mostly on error paths) + * + * Revision 1.58.2.7 2004/10/03 12:53:32 david__schmidt + * Add the ability to check jpeg images for invalid + * lengths of comment blocks. Defensive strategy + * against the exploit: + * Microsoft Security Bulletin MS04-028 + * Buffer Overrun in JPEG Processing (GDI+) Could + * Allow Code Execution (833987) + * Enabled with +inspect-jpegs in actions files. + * + * Revision 1.58.2.6 2003/12/06 22:18:27 gliptak + * Correcting compile problem with FEATURE_IMAGE_BLOCKING + * + * Revision 1.58.2.5 2003/11/11 13:10:31 oes + * Fixed bug #839859: "See why" link URL now gets url-encoded. + * + * Revision 1.58.2.4 2003/02/28 12:52:45 oes + * Fixed a typo + * + * Revision 1.58.2.3 2002/09/25 14:51:51 oes + * Added basic support for OPTIONS and TRACE HTTP methods: + * New function direct_response which handles OPTIONS and + * TRACE requests whose Max-Forwards header field is zero. + * + * Revision 1.58.2.2 2002/08/01 17:18:28 oes + * Fixed BR 537651 / SR 579724 (MSIE image detect improper for IE/Mac) + * + * Revision 1.58.2.1 2002/07/26 15:18:53 oes + * - Bugfix: Executing a filters without jobs no longer results in + * turing off *all* filters. + * - Security fix: Malicious web servers can't cause a seg fault + * through bogus chunk sizes anymore + * + * Revision 1.58 2002/04/24 02:11:17 oes + * Jon's multiple AF patch: url_actions now evaluates rules + * from all AFs. + * + * Revision 1.57 2002/04/08 20:38:34 swa + * fixed JB spelling + * + * Revision 1.56 2002/04/05 15:51:24 oes + * - bugfix: error-pages now get correct request protocol + * - fix for invalid HTML in trust info + * + * Revision 1.55 2002/04/02 16:13:51 oes + * Fix: No "Go there anyway" for SSL + * + * Revision 1.54 2002/04/02 14:55:56 oes + * Bugfix: is_untrusted_url() now depends on FEATURE_TRUST, not FEATURE_COOKIE_JAR + * * Revision 1.53 2002/03/26 22:29:54 swa * we have a new homepage! * @@ -360,7 +416,7 @@ const char filters_rcs[] = "$Id: filters.c,v 1.53 2002/03/26 22:29:54 swa Exp $" * a lot! ;-) * * Revision 1.3 2001/05/20 16:44:47 jongfoster - * Removing last hardcoded JunkBusters.com URLs. + * Removing last hardcoded Junkbusters.com URLs. * * Revision 1.2 2001/05/20 01:21:20 jongfoster * Version 2.9.4 checkin. @@ -664,9 +720,6 @@ int match_portlist(const char *portlist, int port) *********************************************************************/ struct http_response *block_url(struct client_state *csp) { -#ifdef FEATURE_IMAGE_BLOCKING - char *p; -#endif /* def FEATURE_IMAGE_BLOCKING */ struct http_response *rsp; /* @@ -693,6 +746,7 @@ struct http_response *block_url(struct client_state *csp) if (((csp->action->flags & ACTION_IMAGE_BLOCKER) != 0) && is_imageurl(csp)) { + char *p; /* determine HOW images should be blocked */ p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER]; @@ -783,6 +837,7 @@ struct http_response *block_url(struct client_state *csp) { jb_err err; struct map * exports; + char *p; /* * Workaround for stupid Netscape bug which prevents @@ -818,12 +873,16 @@ struct http_response *block_url(struct client_state *csp) #ifdef FEATURE_FORCE_LOAD err = map(exports, "force-prefix", 1, FORCE_PREFIX, 1); -#else /* ifndef FEATURE_FORCE_LOAD */ - err = map_block_killer(exports, "force-support"); + if (csp->http->ssl != 0) #endif /* ndef FEATURE_FORCE_LOAD */ + { + err = map_block_killer(exports, "force-support"); + } + if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); if (!err) err = map(exports, "hostport", 1, html_encode(csp->http->hostport), 0); if (!err) err = map(exports, "path", 1, html_encode(csp->http->path), 0); + if (!err) err = map(exports, "path-ue", 1, url_encode(csp->http->path), 0); if (err) { @@ -893,9 +952,10 @@ struct http_response *trust_url(struct client_state *csp) } /* - * Export the host, port, and referrer information + * Export the protocol, host, port, and referrer information */ err = map(exports, "hostport", 1, csp->http->hostport, 1); + if (!err) err = map(exports, "protocol", 1, csp->http->ssl ? "https://" : "http://", 1); if (!err) err = map(exports, "path", 1, csp->http->path, 1); if (NULL != (p = get_header_value(csp->headers, "Referer:"))) @@ -924,6 +984,7 @@ struct http_response *trust_url(struct client_state *csp) string_append(&p, buf); } err = map(exports, "trusted-referrers", 1, p, 0); + freez(p); if (err) { @@ -942,10 +1003,11 @@ struct http_response *trust_url(struct client_state *csp) p = strdup(""); for (l = csp->config->trust_info->first; l ; l = l->next) { - sprintf(buf, "
  • %s
    \n",l->str, l->str); + sprintf(buf, "
  • %s
    \n",l->str, l->str); string_append(&p, buf); } err = map(exports, "trust-info", 1, p, 0); + freez(p); } else { @@ -1057,8 +1119,9 @@ struct http_response *redirect_url(struct client_state *csp) * * Description : Given a URL, decide whether it is an image or not, * using either the info from a previous +image action - * or, #ifdef FEATURE_IMAGE_DETECT_MSIE, the info from - * the browser's accept header. + * or, #ifdef FEATURE_IMAGE_DETECT_MSIE, and the browser + * is MSIE and not on a Mac, tell from the browser's accept + * header. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -1073,7 +1136,7 @@ int is_imageurl(struct client_state *csp) char *tmp; tmp = get_header_value(csp->headers, "User-Agent:"); - if (tmp && strstr(tmp, "MSIE")) + if (tmp && strstr(tmp, "MSIE") && !strstr(tmp, "Mac_")) { tmp = get_header_value(csp->headers, "Accept:"); if (tmp && strstr(tmp, "image/gif")) @@ -1222,7 +1285,7 @@ int is_untrusted_url(struct client_state *csp) * * Function : pcrs_filter_response * - * Description : Ecexute all text substitutions from all applying + * Description : Execute all text substitutions from all applying * +filter actions on the text buffer that's been accumulated * in csp->iob->buf. If this changes the contents, set * csp->content_length to the modified size and raise the @@ -1247,6 +1310,8 @@ char *pcrs_filter_response(struct client_state *csp) struct re_filterfile_spec *b; struct list_entry *filtername; + int i, found_filters = 0; + /* * Sanity first */ @@ -1256,10 +1321,26 @@ char *pcrs_filter_response(struct client_state *csp) } size = csp->iob->eod - csp->iob->cur; - if ( ( NULL == (fl = csp->rlist) ) || ( NULL == fl->f) ) + /* + * Need to check the set of re_filterfiles... + */ + for (i = 0; i < MAX_AF_FILES; i++) + { + fl = csp->rlist[i]; + if (NULL != fl) + { + if (NULL != fl->f) + { + found_filters = 1; + break; + } + } + } + + if (0 == found_filters) { log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering."); - return(NULL); + return(NULL); } /* @@ -1277,6 +1358,11 @@ char *pcrs_filter_response(struct client_state *csp) csp->flags |= CSP_FLAG_MODIFIED; } + for (i = 0; i < MAX_AF_FILES; i++) + { + fl = csp->rlist[i]; + if ((NULL == fl) || (NULL == fl->f)) + break; /* * For all applying +filter actions, look if a filter by that * name exists and if yes, execute it's pcrs_joblist on the @@ -1294,7 +1380,7 @@ char *pcrs_filter_response(struct client_state *csp) if ( NULL == b->joblist ) { log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name); - return(NULL); + continue; } log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) with filter %s...", @@ -1313,6 +1399,7 @@ char *pcrs_filter_response(struct client_state *csp) } } } + } /* * If there were no hits, destroy our copy and let @@ -1407,6 +1494,80 @@ char *gif_deanimate_response(struct client_state *csp) } +/********************************************************************* + * + * Function : jpeg_inspect_response + * + * Description : + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : a pointer to the (newly allocated) modified buffer + * or NULL in case something went wrong. + * + *********************************************************************/ +char *jpeg_inspect_response(struct client_state *csp) +{ + struct binbuffer *in = NULL, *out = NULL; + char *p = NULL; + size_t size = csp->iob->eod - csp->iob->cur; + + /* + * If the body has a "chunked" transfer-encoding, + * get rid of it first, adjusting size and iob->eod + */ + if (csp->flags & CSP_FLAG_CHUNKED) + { + log_error(LOG_LEVEL_DEANIMATE, "Need to de-chunk first"); + if (0 == (size = remove_chunked_transfer_coding(csp->iob->cur, size))) + { + return(NULL); + } + csp->iob->eod = csp->iob->cur + size; + csp->flags |= CSP_FLAG_MODIFIED; + } + + if (NULL == (in = (struct binbuffer *)zalloc(sizeof *in ))) + { + log_error(LOG_LEVEL_DEANIMATE, "failed! (jpeg no mem 1)"); + return NULL; + } + + if (NULL == (out = (struct binbuffer *)zalloc(sizeof *out))) + { + log_error(LOG_LEVEL_DEANIMATE, "failed! (jpeg no mem 2)"); + return NULL; + } + + in->buffer = csp->iob->cur; + in->size = size; + + /* + * Calling jpeg_inspect has the side-effect of creating and + * modifying the image buffer of "out" directly. + */ + if (jpeg_inspect(in, out)) + { + log_error(LOG_LEVEL_DEANIMATE, "failed! (jpeg parsing)"); + free(in); + buf_free(out); + return(NULL); + + } + else + { + csp->content_length = out->offset; + csp->flags |= CSP_FLAG_MODIFIED; + p = out->buffer; + free(in); + free(out); + return(p); + } + +} + + /********************************************************************* * * Function : remove_chunked_transfer_coding @@ -1445,7 +1606,12 @@ int remove_chunked_transfer_coding(char *buffer, const size_t size) log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding"); return(0); } - newsize += chunksize; + + if ((newsize += chunksize) >= size) + { + log_error(LOG_LEVEL_ERROR, "Chunksize exceeds buffer in \"chunked\" transfer coding"); + return(0); + } from_p += 2; memmove(to_p, from_p, (size_t) chunksize); @@ -1484,16 +1650,21 @@ void url_actions(struct http_request *http, { struct file_list *fl; struct url_actions *b; + int i; init_current_action(csp->action); - if (((fl = csp->actions_list) == NULL) || ((b = fl->f) == NULL)) + for (i = 0; i < MAX_AF_FILES; i++) { - return; - } + if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL)) + { + return; + } - apply_url_actions(csp->action, http, b); + apply_url_actions(csp->action, http, b); + } + return; } @@ -1568,6 +1739,63 @@ const struct forward_spec * forward_url(struct http_request *http, } +/********************************************************************* + * + * Function : direct_response + * + * Description : Check if Max-Forwards == 0 for an OPTIONS or TRACE + * request and if so, return a HTTP 501 to the client. + * + * FIXME: I have a stupid name and I should handle the + * requests properly. Still, what we do here is rfc- + * compliant, whereas ignoring or forwarding are not. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : http_response if , NULL if nonmatch or handler fail + * + *********************************************************************/ +struct http_response *direct_response(struct client_state *csp) +{ + struct http_response *rsp; + struct list_entry *p; + + if ((0 == strcmpic(csp->http->gpc, "trace")) + || (0 == strcmpic(csp->http->gpc, "options"))) + { + for (p = csp->headers->first; (p != NULL) ; p = p->next) + { + if (!strncmp("Max-Forwards:", p->str, 13) + && (*(p->str+13) != '\0') && (atoi(p->str+13) == 0)) + { + /* FIXME: We could handle at least TRACE here, + but that would require a verbatim copy of + the request which we don't have anymore */ + + log_error(LOG_LEVEL_HEADER, "Found Max-Forwards:0 in OPTIONS or TRACE request -- Returning 501"); + + /* Get mem for response or fail*/ + if (NULL == (rsp = alloc_http_response())) + { + return cgi_error_memory(); + } + + if (NULL == (rsp->status = strdup("501 Not Implemented"))) + { + free_http_response(rsp); + return cgi_error_memory(); + } + + rsp->is_static = 1; + return(finish_http_response(rsp)); + } + } + } + return NULL; +} + + /* Local Variables: tab-width: 3