From 439046b4f88535a962b4d7333bfbb16fd563fc7e Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Tue, 20 Mar 2007 15:16:34 +0000 Subject: [PATCH] Use dedicated header filter actions instead of abusing "filter". Replace "filter-client-headers" and "filter-client-headers" with "server-header-filter" and "client-header-filter". --- actionlist.h | 21 +++++++++- cgiedit.c | 107 +++++++++++++++++++++++++++++++++++++++++++-------- filters.c | 11 +++++- loaders.c | 33 ++++++++++++++-- project.h | 26 +++++++++---- 5 files changed, 168 insertions(+), 30 deletions(-) diff --git a/actionlist.h b/actionlist.h index 1274aee1..3d36d66b 100644 --- a/actionlist.h +++ b/actionlist.h @@ -39,6 +39,17 @@ * * Revisions : * $Log: actionlist.h,v $ + * Revision 1.23 2006/10/09 10:26:18 fabiankeil + * Changed the path in set-image-blocker's redirection default to + * "send-banner?type=pattern" instead of "show-banner?type=pattern" + * which isn't caught by Privoxy. Fixes BR 1573468. + * + * Changed hide-user-agent's default value to "Privoxy VERSION". + * + * Changed hide-referrer's default fake value to "http://www.privoxy.org/". + * A static referrer is obviously fake anyway, so we might as well + * advertise ourselves. + * * Revision 1.22 2006/09/01 17:14:18 hal9 * Re-ordered the actions list so that they display in the actions editor in * alphabetical order. Some of the new actions were "out of order". @@ -137,6 +148,7 @@ DEFINE_ACTION_MULTI ("add-header", ACTION_MULTI_ADD_HEADER) DEFINE_ACTION_BOOL ("block", ACTION_BLOCK) +DEFINE_ACTION_MULTI ("client-header-filter", ACTION_MULTI_CLIENT_HEADER_FILTER) DEFINE_ACTION_STRING ("content-type-overwrite", ACTION_CONTENT_TYPE_OVERWRITE, ACTION_STRING_CONTENT_TYPE) DEFINE_CGI_PARAM_NO_RADIO("content-type-overwrite", ACTION_CONTENT_TYPE_OVERWRITE, ACTION_STRING_CONTENT_TYPE, "text/html") DEFINE_ACTION_STRING ("crunch-client-header", ACTION_CRUNCH_CLIENT_HEADER, ACTION_STRING_CLIENT_HEADER) @@ -154,8 +166,6 @@ DEFINE_ACTION_STRING ("fast-redirects", ACTION_FAST_REDIRECTS, DEFINE_CGI_PARAM_RADIO ("fast-redirects", ACTION_FAST_REDIRECTS, ACTION_STRING_FAST_REDIRECTS, "simple-check", 0) DEFINE_CGI_PARAM_RADIO ("fast-redirects", ACTION_FAST_REDIRECTS, ACTION_STRING_FAST_REDIRECTS, "check-decoded-url", 1) DEFINE_ACTION_MULTI ("filter", ACTION_MULTI_FILTER) -DEFINE_ACTION_BOOL ("filter-client-headers", ACTION_FILTER_CLIENT_HEADERS) -DEFINE_ACTION_BOOL ("filter-server-headers", ACTION_FILTER_SERVER_HEADERS) DEFINE_ACTION_BOOL ("force-text-mode", ACTION_FORCE_TEXT_MODE) DEFINE_ACTION_BOOL ("handle-as-empty-document", ACTION_HANDLE_AS_EMPTY_DOCUMENT) DEFINE_ACTION_BOOL ("handle-as-image", ACTION_IMAGE) @@ -192,6 +202,7 @@ DEFINE_ACTION_STRING ("redirect", ACTION_REDIRECT, DEFINE_CGI_PARAM_NO_RADIO("redirect", ACTION_REDIRECT, ACTION_STRING_REDIRECT, "http://localhost/") DEFINE_ACTION_BOOL ("send-vanilla-wafer", ACTION_VANILLA_WAFER) DEFINE_ACTION_MULTI ("send-wafer", ACTION_MULTI_WAFER) +DEFINE_ACTION_MULTI ("server-header-filter", ACTION_MULTI_SERVER_HEADER_FILTER) DEFINE_ACTION_BOOL ("session-cookies-only", ACTION_NO_COOKIE_KEEP) DEFINE_ACTION_STRING ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER) DEFINE_CGI_PARAM_RADIO ("set-image-blocker", ACTION_IMAGE_BLOCKER, ACTION_STRING_IMAGE_BLOCKER, "pattern", 1) @@ -209,6 +220,12 @@ DEFINE_ACTION_BOOL ("kill-popup", ACTION_NO_POPUPS) DEFINE_ACTION_STRING ("hide-referer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER) DEFINE_ACTION_BOOL ("prevent-keeping-cookies", ACTION_NO_COOKIE_KEEP) +/* + * Pre-3.0.7 (pseudo) compatibility + */ +DEFINE_ACTION_MULTI ("filter-client-headers", ACTION_MULTI_CLIENT_HEADER_FILTER) +DEFINE_ACTION_MULTI ("filter-server-headers", ACTION_MULTI_SERVER_HEADER_FILTER) + /* * Pre-3.0 compatibility */ diff --git a/cgiedit.c b/cgiedit.c index e4f1d68f..60edc893 100644 --- a/cgiedit.c +++ b/cgiedit.c @@ -1,4 +1,4 @@ -const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.47 2006/12/28 18:04:25 fabiankeil Exp $"; +const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.48 2007/02/13 14:35:25 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $ @@ -42,6 +42,10 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.47 2006/12/28 18:04:25 fabiankeil * * Revisions : * $Log: cgiedit.c,v $ + * Revision 1.48 2007/02/13 14:35:25 fabiankeil + * Replace hash escaping code to prevent + * crashes, memory and file corruption. + * * Revision 1.47 2006/12/28 18:04:25 fabiankeil * Fixed gcc43 conversion warnings. * @@ -3106,10 +3110,20 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, } if (0 == have_filters) + { err = map(exports, "filter-params", 1, "", 1); + } else { - /* We have some entries in the filter list */ + /* + * List available filters and their settings. + * + * XXX: Different types of filters should use different + * @substitution strings@. They are currently listed + * in the order they appear in the filter files and + * are all inserted as @filter-params@ which can lead + * to an "interesting" mix. + */ char * result; int filter_identifier = 0; char * filter_template; @@ -3142,8 +3156,37 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, char * this_line; struct map *line_exports; char number[20]; + int multi_action_index = 0; + char *filter_type; + char *abbr_filter_type; - filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first; + switch (filter_group->type) + { + case FT_CONTENT_FILTER: + /* XXX: Should we call it content-filter instead? */ + filter_type = "filter"; + abbr_filter_type = "F"; + multi_action_index = ACTION_MULTI_FILTER; + break; + case FT_SERVER_HEADER_FILTER: + filter_type = "server-header-filter"; + abbr_filter_type = "S"; + multi_action_index = ACTION_MULTI_SERVER_HEADER_FILTER; + break; + case FT_CLIENT_HEADER_FILTER: + filter_type = "client-header-filter"; + abbr_filter_type = "C"; + multi_action_index = ACTION_MULTI_CLIENT_HEADER_FILTER; + break; + default: + log_error(LOG_LEVEL_FATAL, + "cgi_edit_actions_for_url: Unknown filter type: %u for filter %s.", + filter_group->type, filter_group->name); + /* Not reached. */ + } + assert(multi_action_index); + + filter_name = cur_line->data.action->multi_add[multi_action_index]->first; while ((filter_name != NULL) && (0 != strcmp(filter_group->name, filter_name->str))) { @@ -3156,7 +3199,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, } else { - filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first; + filter_name = cur_line->data.action->multi_remove[multi_action_index]->first; while ((filter_name != NULL) && (0 != strcmp(filter_group->name, filter_name->str))) { @@ -3184,6 +3227,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (!err) err = map(line_exports, "name", 1, filter_group->name, 1); if (!err) err = map(line_exports, "description", 1, filter_group->description, 1); if (!err) err = map_radio(line_exports, "this-filter", "ynx", current_mode); + if (!err) err = map(line_exports, "filter-type", 1, filter_type, 1); + if (!err) err = map(line_exports, "abbr-filter-type", 1, abbr_filter_type, 1); this_line = NULL; if (!err) @@ -3349,14 +3394,25 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, { char key_value[30]; char key_name[30]; + char key_type[30]; const char *name; - char value; + char value; /* + * Filter state. Valid states are: 'Y' (active), + * 'N' (inactive) and 'X' (no change). + * XXX: bad name. + */ + char type; /* + * Abbreviated filter type. Valid types are: 'F' (content filter), + * 'S' (server-header filter) and 'C' (client-header filter). + */ + int multi_action_index = 0; /* Generate the keys */ snprintf(key_value, sizeof(key_value), "filter_r%x", filter_identifier); - key_value[sizeof(key_value) - 1] = '\0'; + key_value[sizeof(key_value) - 1] = '\0'; /* XXX: Why? */ snprintf(key_name, sizeof(key_name), "filter_n%x", filter_identifier); - key_name[sizeof(key_name) - 1] = '\0'; + key_name[sizeof(key_name) - 1] = '\0'; /* XXX: Why? */ + snprintf(key_type, sizeof(key_type), "filter_t%x", filter_identifier); err = get_string_param(parameters, key_name, &name); if (err) break; @@ -3367,26 +3423,45 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, break; } + type = get_char_param(parameters, key_type); + switch (type) + { + case 'F': + multi_action_index = ACTION_MULTI_FILTER; + break; + case 'S': + multi_action_index = ACTION_MULTI_SERVER_HEADER_FILTER; + break; + case 'C': + multi_action_index = ACTION_MULTI_CLIENT_HEADER_FILTER; + break; + default: + log_error(LOG_LEVEL_ERROR, + "Unknown filter type: %c for filter %s. Filter ignored.", type, name); + continue; + } + assert(multi_action_index); + value = get_char_param(parameters, key_value); if (value == 'Y') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - if (!err) err = enlist(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + if (!err) err = enlist(cur_line->data.action->multi_add[multi_action_index], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); } else if (value == 'N') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - if (!cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER]) + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + if (!cur_line->data.action->multi_remove_all[multi_action_index]) { - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); - if (!err) err = enlist(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); + if (!err) err = enlist(cur_line->data.action->multi_remove[multi_action_index], name); } } else if (value == 'X') { - list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); - list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_add[multi_action_index], name); + list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name); } } diff --git a/filters.c b/filters.c index 06e69129..4fde6721 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.82 2007/03/13 11:28:43 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.83 2007/03/17 15:20:05 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -40,6 +40,9 @@ const char filters_rcs[] = "$Id: filters.c,v 1.82 2007/03/13 11:28:43 fabiankeil * * Revisions : * $Log: filters.c,v $ + * Revision 1.83 2007/03/17 15:20:05 fabiankeil + * New config option: enforce-blocks. + * * Revision 1.82 2007/03/13 11:28:43 fabiankeil * - Fix port handling in acl_addr() and use a temporary acl spec * copy so error messages don't contain a truncated version. @@ -1876,6 +1879,12 @@ char *pcrs_filter_response(struct client_state *csp) */ for (b = fl->f; b; b = b->next) { + if (b->type != FT_CONTENT_FILTER) + { + /* Skip header filters */ + continue; + } + for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first; filtername ; filtername = filtername->next) { diff --git a/loaders.c b/loaders.c index 97e9fc37..17973bf1 100644 --- a/loaders.c +++ b/loaders.c @@ -1,4 +1,4 @@ -const char loaders_rcs[] = "$Id: loaders.c,v 1.58 2006/12/31 14:25:20 fabiankeil Exp $"; +const char loaders_rcs[] = "$Id: loaders.c,v 1.59 2007/01/25 13:38:20 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loaders.c,v $ @@ -35,6 +35,9 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.58 2006/12/31 14:25:20 fabiankeil * * Revisions : * $Log: loaders.c,v $ + * Revision 1.59 2007/01/25 13:38:20 fabiankeil + * Freez csp->error_message in sweep(). + * * Revision 1.58 2006/12/31 14:25:20 fabiankeil * Fix gcc43 compiler warnings. * @@ -1420,19 +1423,41 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) */ while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL) { + int new_filter = 0; + + if (strncmp(buf, "FILTER:", 7) == 0) + { + new_filter = FT_CONTENT_FILTER; + } + else if (strncmp(buf, "SERVER-HEADER-FILTER:", 21) == 0) + { + new_filter = FT_SERVER_HEADER_FILTER; + } + else if (strncmp(buf, "CLIENT-HEADER-FILTER:", 21) == 0) + { + new_filter = FT_CLIENT_HEADER_FILTER; + } + /* * If this is the head of a new filter block, make it a * re_filterfile spec of its own and chain it to the list: */ - if (strncmp(buf, "FILTER:", 7) == 0) + if (new_filter != 0) { new_bl = (struct re_filterfile_spec *)zalloc(sizeof(*bl)); if (new_bl == NULL) { goto load_re_filterfile_error; } - - new_bl->name = chomp(buf + 7); + if (new_filter == FT_CONTENT_FILTER) + { + new_bl->name = chomp(buf + 7); + } + else + { + new_bl->name = chomp(buf + 21); + } + new_bl->type = new_filter; /* * If a filter description is available, diff --git a/project.h b/project.h index 5469ebe9..d3cde777 100644 --- a/project.h +++ b/project.h @@ -1,7 +1,7 @@ #ifndef PROJECT_H_INCLUDED #define PROJECT_H_INCLUDED /** Version string. */ -#define PROJECT_H_VERSION "$Id: project.h,v 1.91 2007/03/05 13:28:03 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.92 2007/03/17 15:20:05 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -37,6 +37,9 @@ * * Revisions : * $Log: project.h,v $ + * Revision 1.92 2007/03/17 15:20:05 fabiankeil + * New config option: enforce-blocks. + * * Revision 1.91 2007/03/05 13:28:03 fabiankeil * Add some CSP_FLAGs for the header parsers. * @@ -1047,18 +1050,22 @@ struct iob #define ACTION_STRING_COUNT 15 -/*To make the ugly hack in sed easier to understand*/ +/* To make the ugly hack in sed easier to understand */ #define CHECK_EVERY_HEADER_REMAINING 0 /** Index into current_action_spec::multi[] for headers to add. */ -#define ACTION_MULTI_ADD_HEADER 0 +#define ACTION_MULTI_ADD_HEADER 0 /** Index into current_action_spec::multi[] for headers to add. */ -#define ACTION_MULTI_WAFER 1 -/** Index into current_action_spec::multi[] for filters to apply. */ -#define ACTION_MULTI_FILTER 2 +#define ACTION_MULTI_WAFER 1 +/** Index into current_action_spec::multi[] for content filters to apply. */ +#define ACTION_MULTI_FILTER 2 +/** Index into current_action_spec::multi[] for server-header filters to apply. */ +#define ACTION_MULTI_SERVER_HEADER_FILTER 3 +/** Index into current_action_spec::multi[] for client-header filters to apply. */ +#define ACTION_MULTI_CLIENT_HEADER_FILTER 4 /** Number of multi-string actions. */ -#define ACTION_MULTI_COUNT 3 +#define ACTION_MULTI_COUNT 5 /** @@ -1444,6 +1451,10 @@ struct forward_spec */ #define FORWARD_SPEC_INITIALIZER { { URL_SPEC_INITIALIZER }, 0, NULL, 0, NULL, 0, NULL } +/* Supported filter types */ +#define FT_CONTENT_FILTER 1 +#define FT_CLIENT_HEADER_FILTER 2 +#define FT_SERVER_HEADER_FILTER 3 /** * This struct represents one filter (one block) from @@ -1457,6 +1468,7 @@ struct re_filterfile_spec char *description; /**< Description from FILTER: statement in re_filterfile. */ struct list patterns[1]; /**< The patterns from the re_filterfile. */ pcrs_job *joblist; /**< The resulting compiled pcrs_jobs. */ + int type; /**< Filter type (content, client-header, server-header). */ struct re_filterfile_spec *next; /**< The pointer for chaining. */ }; -- 2.49.0