From: Fabian Keil Date: Sun, 22 May 2016 12:43:07 +0000 (+0000) Subject: Optionally use the X-Forwarded-For header for client tags X-Git-Tag: v_3_0_25~18 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=97dcdede1c96c857ea36b5f5a9873c302d021a7d;ds=sidebyside Optionally use the X-Forwarded-For header for client tags ... if it exists. Sponsored by: Robert Klemme --- diff --git a/cgisimple.c b/cgisimple.c index a47ef792..8acfc1e2 100644 --- a/cgisimple.c +++ b/cgisimple.c @@ -1,4 +1,4 @@ -const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.140 2016/05/08 10:46:18 fabiankeil Exp $"; +const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.141 2016/05/08 10:46:29 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgisimple.c,v $ @@ -358,7 +358,7 @@ jb_err cgi_show_client_tags(struct client_state *csp, { return JB_ERR_MEMORY; } - + assert(csp->client_address != NULL); toggled_tag = lookup(parameters, "tag"); if (*toggled_tag != '\0') { @@ -396,7 +396,7 @@ jb_err cgi_show_client_tags(struct client_state *csp, int tag_state; privoxy_mutex_lock(&client_tags_mutex); - tag_state = client_has_requested_tag(csp->ip_addr_str, this_tag->name); + tag_state = client_has_requested_tag(csp->client_address, this_tag->name); privoxy_mutex_unlock(&client_tags_mutex); if (!err) err = string_append(&client_tag_status, ""); if (!err) err = string_append(&client_tag_status, this_tag->name); @@ -429,7 +429,7 @@ jb_err cgi_show_client_tags(struct client_state *csp, return JB_ERR_MEMORY; } - if (map(exports, "client-ip-addr", 1, csp->ip_addr_str, 1)) + if (map(exports, "client-ip-addr", 1, csp->client_address, 1)) { free_map(exports); return JB_ERR_MEMORY; diff --git a/client-tags.c b/client-tags.c index 0bcbf353..fda1f887 100644 --- a/client-tags.c +++ b/client-tags.c @@ -42,6 +42,7 @@ #include "jcc.h" #include "miscutil.h" #include "errlog.h" +#include "parsers.h" struct client_specific_tag { @@ -491,17 +492,17 @@ jb_err enable_client_specific_tag(struct client_state *csp, return JB_ERR_PARSE; } - if (client_has_requested_tag(csp->ip_addr_str, tag_name)) + if (client_has_requested_tag(csp->client_address, tag_name)) { log_error(LOG_LEVEL_ERROR, - "Tag '%s' already enabled for client '%s'", tag->name, csp->ip_addr_str); + "Tag '%s' already enabled for client '%s'", tag->name, csp->client_address); } else { - add_tag_for_client(csp->ip_addr_str, tag_name, time_to_live); + add_tag_for_client(csp->client_address, tag_name, time_to_live); log_error(LOG_LEVEL_INFO, "Tag '%s' enabled for client '%s'. TTL: %d.", - tag->name, csp->ip_addr_str, time_to_live); + tag->name, csp->client_address, time_to_live); } privoxy_mutex_unlock(&client_tags_mutex); @@ -536,17 +537,17 @@ jb_err disable_client_specific_tag(struct client_state *csp, const char *tag_nam return JB_ERR_PARSE; } - if (client_has_requested_tag(csp->ip_addr_str, tag_name)) + if (client_has_requested_tag(csp->client_address, tag_name)) { - remove_tag_for_client(csp->ip_addr_str, tag_name); + remove_tag_for_client(csp->client_address, tag_name); log_error(LOG_LEVEL_INFO, - "Tag '%s' disabled for client '%s'", tag->name, csp->ip_addr_str); + "Tag '%s' disabled for client '%s'", tag->name, csp->client_address); } else { log_error(LOG_LEVEL_ERROR, "Tag '%s' currently not set for client '%s'", - tag->name, csp->ip_addr_str); + tag->name, csp->client_address); } privoxy_mutex_unlock(&client_tags_mutex); @@ -595,6 +596,44 @@ int client_tag_match(const struct pattern_spec *pattern, return 0; } + + +/********************************************************************* + * + * Function : set_client_address + * + * Description : Sets the client address that will be used to enable, + * disable, or apply client tags. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : headers = Client headers + * + * Returns : void. + * + *********************************************************************/ +void set_client_address(struct client_state *csp, const struct list *headers) +{ + if (csp->config->trust_x_forwarded_for) + { + const char *client_address; + + client_address = get_header_value(headers, "X-Forwarded-For:"); + if (client_address != NULL) + { + csp->client_address = strdup_or_die(client_address); + log_error(LOG_LEVEL_HEADER, + "Got client address %s from X-Forwarded-For header", + csp->client_address); + } + } + + if (csp->client_address == NULL) + { + csp->client_address = strdup_or_die(csp->ip_addr_str); + } +} + #else #error Compiling client-tags.c without FEATURE_CLIENT_TAGS #endif /* def FEATURE_CLIENT_TAGS */ diff --git a/client-tags.h b/client-tags.h index 328346ed..6f8398c4 100644 --- a/client-tags.h +++ b/client-tags.h @@ -1,6 +1,6 @@ #ifndef CLIENT_TAGS_H_INCLUDED #define CLIENT_TAGS_H_INCLUDED -#define CLIENT_TAGS_H_VERSION "$Id: client-tags.h,v 1.1 2016/03/17 10:42:27 fabiankeil Exp $" +#define CLIENT_TAGS_H_VERSION "$Id: client-tags.h,v 1.2 2016/05/03 13:21:42 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/client-tags.h,v $ @@ -40,6 +40,8 @@ extern jb_err enable_client_specific_tag(struct client_state *csp, const time_t time_to_live); extern int client_has_requested_tag(const char *client_address, const char *tag); +extern void set_client_address(struct client_state *csp, + const struct list *headers); #define CLIENT_TAG_LENGTH_MAX 50 #endif diff --git a/jcc.c b/jcc.c index 8ab7f872..ad210ab2 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.441 2016/02/26 12:29:38 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.442 2016/03/17 10:40:53 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1678,6 +1678,12 @@ static jb_err receive_client_request(struct client_state *csp) } } +#ifdef FEATURE_CLIENT_TAGS + /* XXX: If the headers were enlisted sooner, passing csp would do. */ + set_client_address(csp, headers); + get_tag_list_for_client(csp->client_tags, csp->client_address); +#endif + /* * Determine the actions for this URL */ @@ -1848,9 +1854,6 @@ static void chat(struct client_state *csp) http = csp->http; -#if FEATURE_CLIENT_TAGS - get_tag_list_for_client(csp->client_tags, csp->ip_addr_str); -#endif if (receive_client_request(csp) != JB_ERR_OK) { return; @@ -2824,6 +2827,7 @@ static void prepare_csp_for_next_request(struct client_state *csp) destroy_list(csp->tags); #ifdef FEATURE_CLIENT_TAGS destroy_list(csp->client_tags); + freez(csp->client_address); #endif free_current_action(csp->action); if (NULL != csp->fwd) diff --git a/loadcfg.c b/loadcfg.c index 879091e2..7cf58015 100644 --- a/loadcfg.c +++ b/loadcfg.c @@ -1,4 +1,4 @@ -const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.151 2016/05/03 13:21:42 fabiankeil Exp $"; +const char loadcfg_rcs[] = "$Id: loadcfg.c,v 1.152 2016/05/08 10:46:55 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loadcfg.c,v $ @@ -166,6 +166,7 @@ static struct file_list *current_configfile = NULL; #define hash_tolerate_pipelining 1360286620U /* "tolerate-pipelining" */ #define hash_toggle 447966U /* "toggle" */ #define hash_trust_info_url 430331967U /* "trust-info-url" */ +#define hash_trust_x_forwarded_for 2971537414U /* "trust-x-forwarded-for" */ #define hash_trustfile 56494766U /* "trustfile" */ #define hash_usermanual 1416668518U /* "user-manual" */ #define hash_activity_animation 1817904738U /* "activity-animation" */ @@ -599,6 +600,7 @@ struct configuration_spec * load_config(void) #ifdef FEATURE_CLIENT_TAGS config->client_tag_lifetime = 60; #endif + config->trust_x_forwarded_for = 0; /* * 128 client sockets ought to be enough for everybody who can't * be bothered to read the documentation to figure out how to @@ -1587,6 +1589,13 @@ struct configuration_spec * load_config(void) break; #endif /* def FEATURE_TRUST */ +/* ************************************************************************* + * trust-x-forwarded-for (0|1) + * *************************************************************************/ + case hash_trust_x_forwarded_for : + config->trust_x_forwarded_for = parse_toggle_state(cmd, arg); + break; + /* ************************************************************************* * trustfile filename * (In confdir by default.) diff --git a/loaders.c b/loaders.c index 2c84b327..92e0353f 100644 --- a/loaders.c +++ b/loaders.c @@ -1,4 +1,4 @@ -const char loaders_rcs[] = "$Id: loaders.c,v 1.102 2016/02/26 12:30:46 fabiankeil Exp $"; +const char loaders_rcs[] = "$Id: loaders.c,v 1.103 2016/05/08 10:45:32 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loaders.c,v $ @@ -182,6 +182,9 @@ unsigned int sweep(void) last_active->next = client_list->next; freez(csp->ip_addr_str); +#ifdef FEATURE_CLIENT_TAGS + freez(csp->client_address); +#endif freez(csp->client_iob->buf); freez(csp->iob->buf); freez(csp->error_message); diff --git a/project.h b/project.h index a53aa879..32a63d52 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.213 2016/03/17 10:40:53 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.214 2016/03/30 11:13:25 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -953,6 +953,12 @@ struct client_state #ifdef FEATURE_CLIENT_TAGS /** List of all tags that apply to this client (assigned based on address) */ struct list client_tags[1]; + /** The address of the client the request (presumably) came from. + * Either the address returned by accept(), or the address provided + * with the X-Forwarded-For header, provided Privoxy has been configured + * to use it. + */ + char *client_address; #endif /** MIME-Type key, see CT_* above */ @@ -1347,6 +1353,7 @@ struct configuration_spec /* Maximum number of seconds a temporarily enabled tag stays enabled. */ unsigned int client_tag_lifetime; #endif /* def FEATURE_CLIENT_TAGS */ + int trust_x_forwarded_for; #ifdef FEATURE_ACL