-const char filters_rcs[] = "$Id: filters.c,v 1.174 2012/10/21 12:35:15 fabiankeil Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.179 2013/12/24 13:32:51 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/filters.c,v $
netmask_addr += 12;
addr_len = 4;
}
- else if (network->ss_family != address->ss_family)
- {
- return 0;
- }
/* XXX: Port check is signaled in netmask */
if (*netmask_port && *network_port != *address_port)
struct map * exports;
char buf[BUFFER_SIZE];
char *p;
- struct url_spec **tl;
- struct url_spec *t;
+ struct pattern_spec **tl;
+ struct pattern_spec *t;
jb_err err;
/*
{
struct file_list *fl;
struct block_spec *b;
- struct url_spec **trusted_url;
+ struct pattern_spec **trusted_url;
struct http_request rhttp[1];
const char * referer;
jb_err err;
#endif /* def FEATURE_TRUST */
+/*********************************************************************
+ *
+ * Function : get_filter
+ *
+ * Description : Get a filter with a given name and type.
+ * Note that taggers are filters, too.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : requested_name = Name of the content filter to get
+ * 3 : requested_type = Type of the filter to tagger to lookup
+ *
+ * Returns : A pointer to the requested filter
+ * or NULL if the filter wasn't found
+ *
+ *********************************************************************/
+struct re_filterfile_spec *get_filter(const struct client_state *csp,
+ const char *requested_name,
+ enum filter_type requested_type)
+{
+ int i;
+ struct re_filterfile_spec *b;
+ struct file_list *fl;
+
+ for (i = 0; i < MAX_AF_FILES; i++)
+ {
+ fl = csp->rlist[i];
+ if ((NULL == fl) || (NULL == fl->f))
+ {
+ /*
+ * Either there are no filter files left or this
+ * filter file just contains no valid filters.
+ *
+ * Continue to be sure we don't miss valid filter
+ * files that are chained after empty or invalid ones.
+ */
+ continue;
+ }
+
+ for (b = fl->f; b != NULL; b = b->next)
+ {
+ if (b->type != requested_type)
+ {
+ /* The callers isn't interested in this filter type. */
+ continue;
+ }
+ if (strcmp(b->name, requested_name) == 0)
+ {
+ /* The requested filter has been found. Abort search. */
+ return b;
+ }
+ }
+ }
+
+ /* No filter with the given name and type exists. */
+ return NULL;
+
+}
+
+
/*********************************************************************
*
* Function : pcrs_filter_response
static char *pcrs_filter_response(struct client_state *csp)
{
int hits = 0;
- int i;
size_t size, prev_size;
char *old = NULL;
char *new = NULL;
pcrs_job *job;
- struct file_list *fl;
struct re_filterfile_spec *b;
struct list_entry *filtername;
size = (size_t)(csp->iob->eod - csp->iob->cur);
old = csp->iob->cur;
- for (i = 0; i < MAX_AF_FILES; i++)
- {
- fl = csp->rlist[i];
- if ((NULL == fl) || (NULL == fl->f))
- {
- /*
- * Either there are no filter files
- * left, or this filter file just
- * contains no valid filters.
- *
- * Continue to be sure we don't miss
- * valid filter files that are chained
- * after empty or invalid ones.
- */
- continue;
- }
/*
* For all applying +filter actions, look if a filter by that
* name exists and if yes, execute it's pcrs_joblist on the
* buffer.
*/
- for (b = fl->f; b; b = b->next)
+ for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first;
+ filtername != NULL; filtername = filtername->next)
{
- if (b->type != FT_CONTENT_FILTER)
+ int current_hits = 0; /* Number of hits caused by this filter */
+ int job_number = 0; /* Which job we're currently executing */
+ int job_hits = 0; /* How many hits the current job caused */
+ pcrs_job *joblist;
+
+ b = get_filter(csp, filtername->str, FT_CONTENT_FILTER);
+ if (b == NULL)
{
- /* Skip header filters */
continue;
}
- for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first;
- filtername ; filtername = filtername->next)
- {
- if (strcmp(b->name, filtername->str) == 0)
- {
- int current_hits = 0; /* Number of hits caused by this filter */
- int job_number = 0; /* Which job we're currently executing */
- int job_hits = 0; /* How many hits the current job caused */
- pcrs_job *joblist = b->joblist;
+ joblist = b->joblist;
- if (b->dynamic) joblist = compile_dynamic_pcrs_job_list(csp, b);
+ if (b->dynamic) joblist = compile_dynamic_pcrs_job_list(csp, b);
- if (NULL == joblist)
- {
- log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name);
- continue;
- }
+ if (NULL == joblist)
+ {
+ log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name);
+ continue;
+ }
- prev_size = size;
- /* Apply all jobs from the joblist */
- for (job = joblist; NULL != job; job = job->next)
- {
- job_number++;
- job_hits = pcrs_execute(job, old, size, &new, &size);
+ prev_size = size;
+ /* Apply all jobs from the joblist */
+ for (job = joblist; NULL != job; job = job->next)
+ {
+ job_number++;
+ job_hits = pcrs_execute(job, old, size, &new, &size);
- if (job_hits >= 0)
- {
- /*
- * That went well. Continue filtering
- * and use the result of this job as
- * input for the next one.
- */
- current_hits += job_hits;
- if (old != csp->iob->cur)
- {
- freez(old);
- }
- old = new;
- }
- else
- {
- /*
- * This job caused an unexpected error. Inform the user
- * and skip the rest of the jobs in this filter. We could
- * continue with the next job, but usually the jobs
- * depend on each other or are similar enough to
- * fail for the same reason.
- *
- * At the moment our pcrs expects the error codes of pcre 3.4,
- * but newer pcre versions can return additional error codes.
- * As a result pcrs_strerror()'s error message might be
- * "Unknown error ...", therefore we print the numerical value
- * as well.
- *
- * XXX: Is this important enough for LOG_LEVEL_ERROR or
- * should we use LOG_LEVEL_RE_FILTER instead?
- */
- log_error(LOG_LEVEL_ERROR, "Skipped filter \'%s\' after job number %u: %s (%d)",
- b->name, job_number, pcrs_strerror(job_hits), job_hits);
- break;
- }
+ if (job_hits >= 0)
+ {
+ /*
+ * That went well. Continue filtering
+ * and use the result of this job as
+ * input for the next one.
+ */
+ current_hits += job_hits;
+ if (old != csp->iob->cur)
+ {
+ freez(old);
}
+ old = new;
+ }
+ else
+ {
+ /*
+ * This job caused an unexpected error. Inform the user
+ * and skip the rest of the jobs in this filter. We could
+ * continue with the next job, but usually the jobs
+ * depend on each other or are similar enough to
+ * fail for the same reason.
+ *
+ * At the moment our pcrs expects the error codes of pcre 3.4,
+ * but newer pcre versions can return additional error codes.
+ * As a result pcrs_strerror()'s error message might be
+ * "Unknown error ...", therefore we print the numerical value
+ * as well.
+ *
+ * XXX: Is this important enough for LOG_LEVEL_ERROR or
+ * should we use LOG_LEVEL_RE_FILTER instead?
+ */
+ log_error(LOG_LEVEL_ERROR, "Skipped filter \'%s\' after job number %u: %s (%d)",
+ b->name, job_number, pcrs_strerror(job_hits), job_hits);
+ break;
+ }
+ }
- if (b->dynamic) pcrs_free_joblist(joblist);
+ if (b->dynamic) pcrs_free_joblist(joblist);
- log_error(LOG_LEVEL_RE_FILTER,
- "filtering %s%s (size %d) with \'%s\' produced %d hits (new size %d).",
- csp->http->hostport, csp->http->path, prev_size, b->name, current_hits, size);
+ log_error(LOG_LEVEL_RE_FILTER,
+ "filtering %s%s (size %d) with \'%s\' produced %d hits (new size %d).",
+ csp->http->hostport, csp->http->path, prev_size, b->name, current_hits, size);
- hits += current_hits;
- }
- }
- }
+ hits += current_hits;
}
/*
fwd->type = SOCKS_5;
socks_proxy = vec[1];
}
+ else if (!strcasecmp(vec[0], "forward-socks5t"))
+ {
+ fwd->type = SOCKS_5T;
+ socks_proxy = vec[1];
+ }
if (NULL != socks_proxy)
{
const struct forward_spec *forward_url(struct client_state *csp,
const struct http_request *http)
{
- static const struct forward_spec fwd_default[1] = { FORWARD_SPEC_INITIALIZER };
+ static const struct forward_spec fwd_default[1]; /* Zero'ed due to being static. */
struct forward_spec *fwd = csp->config->forward;
if (csp->action->flags & ACTION_FORWARD_OVERRIDE)