X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=cgi.c;h=53587e9509c48cccbe7c799c8b53b76056119cf8;hb=65690f437fa5f89034b8e788f10eba449a5312e5;hp=d39e4a0e40fe5b5314dc28407801105d92f53dfa;hpb=13a5c4d6d453bba4efbfba6b878b1b93c23c4a42;p=privoxy.git
diff --git a/cgi.c b/cgi.c
index d39e4a0e..53587e95 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,15 +1,14 @@
-const char cgi_rcs[] = "$Id: cgi.c,v 1.154 2012/07/23 12:42:53 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgi.c,v $
*
* Purpose : Declares functions to intercept request, generate
- * html or gif answers, and to compose HTTP resonses.
+ * html or gif answers, and to compose HTTP responses.
* This only contains the framework functions, the
* actual handler functions are declared elsewhere.
*
- * Copyright : Written by and Copyright (C) 2001-2004, 2006-2008
- * the SourceForge Privoxy team. http://www.privoxy.org/
+ * Copyright : Written by and Copyright (C) 2001-2020
+ * members of the Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
* by and Copyright (C) 1997 Anonymous Coders and
@@ -63,13 +62,16 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.154 2012/07/23 12:42:53 fabiankeil Exp $"
#if defined(FEATURE_CGI_EDIT_ACTIONS) || defined(FEATURE_TOGGLE)
#include "cgiedit.h"
#endif /* defined(FEATURE_CGI_EDIT_ACTIONS) || defined (FEATURE_TOGGLE) */
+#ifdef FEATURE_HTTPS_INSPECTION
+#include "ssl.h"
+#endif
/* loadcfg.h is for global_toggle_state only */
#include "loadcfg.h"
/* jcc.h is for mutex semaphore globals only */
#include "jcc.h"
-const char cgi_h_rcs[] = CGI_H_VERSION;
+static char *make_menu(const struct client_state *csp, const char *self);
/*
* List of CGI functions: name, handler, description
@@ -96,10 +98,17 @@ static const struct cgi_dispatcher cgi_dispatchers[] = {
"View the current configuration",
#endif
TRUE },
- { "show-version",
- cgi_show_version,
- "View the source code version numbers",
- TRUE },
+#ifdef FEATURE_CLIENT_TAGS
+ /*
+ * This is marked as harmless because despite the description
+ * used in the menu the actual toggling is done through another
+ * path ("/toggle-client-tag").
+ */
+ { "client-tags",
+ cgi_show_client_tags,
+ "View or toggle the tags that can be set based on the client's address",
+ TRUE },
+#endif
{ "show-request",
cgi_show_request,
"View the request headers",
@@ -114,6 +123,12 @@ static const struct cgi_dispatcher cgi_dispatchers[] = {
"Toggle Privoxy on or off",
FALSE },
#endif /* def FEATURE_TOGGLE */
+#ifdef FEATURE_CLIENT_TAGS
+ { "toggle-client-tag",
+ cgi_toggle_client_tag,
+ NULL,
+ FALSE },
+#endif
#ifdef FEATURE_CGI_EDIT_ACTIONS
{ "edit-actions", /* Edit the actions list */
cgi_edit_actions,
@@ -234,7 +249,7 @@ const char image_pattern_data[] =
"\000\000\000\000\111\105\116\104\256\102\140\202";
/*
- * 1x1 transparant PNG.
+ * 1x1 transparent PNG.
*/
const char image_blank_data[] =
"\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104\122"
@@ -257,7 +272,7 @@ const char image_pattern_data[] =
"\270\005\000\073";
/*
- * 1x1 transparant GIF.
+ * 1x1 transparent GIF.
*/
const char image_blank_data[] =
"GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
@@ -346,6 +361,21 @@ struct http_response *dispatch_cgi(struct client_state *csp)
return NULL;
}
+ if (strcmpic(csp->http->gpc, "GET")
+ && strcmpic(csp->http->gpc, "HEAD"))
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "CGI request with unsupported method received: %s", csp->http->gpc);
+ /*
+ * The CGI pages currently only support GET and HEAD requests.
+ *
+ * If the client used a different method, ditch any data following
+ * the current headers to reduce the likelihood of parse errors
+ * with the following request.
+ */
+ csp->client_iob->eod = csp->client_iob->cur;
+ }
+
/*
* This is a CGI call.
*/
@@ -376,8 +406,13 @@ struct http_response *dispatch_cgi(struct client_state *csp)
static char *grep_cgi_referrer(const struct client_state *csp)
{
struct list_entry *p;
+ struct list_entry *first_header =
+#ifdef FEATURE_HTTPS_INSPECTION
+ client_use_ssl(csp) ? csp->https_headers->first :
+#endif
+ csp->headers->first;
- for (p = csp->headers->first; p != NULL; p = p->next)
+ for (p = first_header; p != NULL; p = p->next)
{
if (p->str == NULL) continue;
if (strncmpic(p->str, "Referer: ", 9) == 0)
@@ -409,6 +444,10 @@ static int referrer_is_safe(const struct client_state *csp)
{
char *referrer;
static const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/";
+#ifdef FEATURE_HTTPS_INSPECTION
+ static const char alt_prefix_https[] = "https://" CGI_SITE_1_HOST "/";
+#endif
+ const char *trusted_cgi_referrer = csp->config->trusted_cgi_referrer;
referrer = grep_cgi_referrer(csp);
@@ -418,8 +457,12 @@ static int referrer_is_safe(const struct client_state *csp)
log_error(LOG_LEVEL_ERROR, "Denying access to %s. No referrer found.",
csp->http->url);
}
- else if ((0 == strncmp(referrer, CGI_PREFIX, sizeof(CGI_PREFIX)-1)
- || (0 == strncmp(referrer, alternative_prefix, strlen(alternative_prefix)))))
+ else if ((0 == strncmp(referrer, CGI_PREFIX_HTTP, sizeof(CGI_PREFIX_HTTP)-1))
+#ifdef FEATURE_HTTPS_INSPECTION
+ || (0 == strncmp(referrer, CGI_PREFIX_HTTPS, sizeof(CGI_PREFIX_HTTPS)-1))
+ || (0 == strncmp(referrer, alt_prefix_https, strlen(alt_prefix_https)))
+#endif
+ || (0 == strncmp(referrer, alternative_prefix, strlen(alternative_prefix))))
{
/* Trustworthy referrer */
log_error(LOG_LEVEL_CGI, "Granting access to %s, referrer %s is trustworthy.",
@@ -427,6 +470,18 @@ static int referrer_is_safe(const struct client_state *csp)
return TRUE;
}
+ else if ((trusted_cgi_referrer != NULL) && (0 == strncmp(referrer,
+ trusted_cgi_referrer, strlen(trusted_cgi_referrer))))
+ {
+ /*
+ * After some more testing this block should be merged with
+ * the previous one or the log level should bedowngraded.
+ */
+ log_error(LOG_LEVEL_INFO, "Granting access to %s based on trusted referrer %s",
+ csp->http->url, referrer);
+
+ return TRUE;
+ }
else
{
/* Untrustworthy referrer */
@@ -480,9 +535,13 @@ static struct http_response *dispatch_known_cgi(struct client_state * csp,
if (*query_args_start == '/')
{
*query_args_start++ = '\0';
- if ((param_list = new_map()))
+ param_list = new_map();
+ err = map(param_list, "file", 1, url_decode(query_args_start), 0);
+ if (JB_ERR_OK != err)
{
- map(param_list, "file", 1, url_decode(query_args_start), 0);
+ free(param_list);
+ free(path_copy);
+ return cgi_error_memory();
}
}
else
@@ -616,11 +675,7 @@ static struct map *parse_cgi_parameters(char *argstring)
}
vector = malloc_or_die(max_segments * sizeof(char *));
- if (NULL == (cgi_params = new_map()))
- {
- freez(vector);
- return NULL;
- }
+ cgi_params = new_map();
/*
* IE 5 does, of course, violate RFC 2316 Sect 4.1 and sends
@@ -698,22 +753,22 @@ char get_char_param(const struct map *parameters,
*
* Function : get_string_param
*
- * Description : Get a string paramater, to be used as an
- * ACTION_STRING or ACTION_MULTI paramater.
+ * Description : Get a string parameter, to be used as an
+ * ACTION_STRING or ACTION_MULTI parameter.
* Validates the input to prevent stupid/malicious
* users from corrupting their action file.
*
* Parameters :
* 1 : parameters = map of cgi parameters
* 2 : param_name = The name of the parameter to read
- * 3 : pparam = destination for paramater. Allocated as
+ * 3 : pparam = destination for parameter. Allocated as
* part of the map "parameters", so don't free it.
* Set to NULL if not specified.
*
- * Returns : JB_ERR_OK on success, or if the paramater
+ * Returns : JB_ERR_OK on success, or if the parameter
* was not specified.
* JB_ERR_MEMORY on out-of-memory.
- * JB_ERR_CGI_PARAMS if the paramater is not valid.
+ * JB_ERR_CGI_PARAMS if the parameter is not valid.
*
*********************************************************************/
jb_err get_string_param(const struct map *parameters,
@@ -793,8 +848,7 @@ jb_err get_number_param(struct client_state *csp,
unsigned *pvalue)
{
const char *param;
- char ch;
- unsigned value;
+ char *endptr;
assert(csp);
assert(parameters);
@@ -809,36 +863,12 @@ jb_err get_number_param(struct client_state *csp,
return JB_ERR_CGI_PARAMS;
}
- /* We don't use atoi because I want to check this carefully... */
-
- value = 0;
- while ((ch = *param++) != '\0')
+ *pvalue = (unsigned int)strtol(param, &endptr, 0);
+ if (*endptr != '\0')
{
- if ((ch < '0') || (ch > '9'))
- {
- return JB_ERR_CGI_PARAMS;
- }
-
- ch = (char)(ch - '0');
-
- /* Note:
- *
- *
Please " - "" + "" "file a bug report.
\n" "