X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=cgi.c;h=cc8ef2cc89898b4f8dbe145f6ca27656a0ee7585;hb=13d869044f86f8a315b9bba21e9dad4eab07b17a;hp=866755d4f70a6c539205a11d76cdb160ede87723;hpb=e6abc85b12f8d1a0bd04e8db1bfe2e6aeac922ff;p=privoxy.git diff --git a/cgi.c b/cgi.c index 866755d4..cc8ef2cc 100644 --- a/cgi.c +++ b/cgi.c @@ -1,4 +1,4 @@ -const char cgi_rcs[] = "$Id: cgi.c,v 1.94 2007/02/08 19:44:49 fabiankeil Exp $"; +const char cgi_rcs[] = "$Id: cgi.c,v 1.107 2008/05/26 16:23:19 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgi.c,v $ @@ -11,7 +11,7 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.94 2007/02/08 19:44:49 fabiankeil Exp $"; * Functions declared include: * * - * Copyright : Written by and Copyright (C) 2001-2004, 2006-2007 + * Copyright : Written by and Copyright (C) 2001-2004, 2006-2008 * the SourceForge Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -38,6 +38,51 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.94 2007/02/08 19:44:49 fabiankeil Exp $"; * * Revisions : * $Log: cgi.c,v $ + * Revision 1.107 2008/05/26 16:23:19 fabiankeil + * - Fix spelling in template-not-found message. + * - Declare referrer_is_safe()'s alternative_prefix[] static. + * + * Revision 1.106 2008/05/21 15:24:38 fabiankeil + * Mark csp as immutable for a bunch of functions. + * + * Revision 1.105 2008/04/17 14:40:47 fabiankeil + * Provide get_http_time() with the buffer size so it doesn't + * have to blindly assume that the buffer is big enough. + * + * Revision 1.104 2008/03/26 18:07:06 fabiankeil + * Add hostname directive. Closes PR#1918189. + * + * Revision 1.103 2008/03/21 11:13:57 fabiankeil + * Only gather host information if it's actually needed. + * Also move the code out of accept_connection() so it's less likely + * to delay other incoming connections if the host is misconfigured. + * + * Revision 1.102 2008/02/23 16:33:43 fabiankeil + * Let forward_url() use the standard parameter ordering + * and mark its second parameter immutable. + * + * Revision 1.101 2008/02/03 15:45:06 fabiankeil + * Add SOCKS5 support for "Forwarding failure" CGI page. + * + * Revision 1.100 2007/10/17 18:40:53 fabiankeil + * - Send CGI pages as HTTP/1.1 unless the client asked for HTTP/1.0. + * - White space fix. + * + * Revision 1.99 2007/08/05 13:42:22 fabiankeil + * #1763173 from Stefan Huehner: declare some more functions static. + * + * Revision 1.98 2007/05/14 10:33:51 fabiankeil + * - Use strlcpy() and strlcat() instead of strcpy() and strcat(). + * + * Revision 1.97 2007/04/09 18:11:35 fabiankeil + * Don't mistake VC++'s _snprintf() for a snprintf() replacement. + * + * Revision 1.96 2007/03/08 17:41:05 fabiankeil + * Use sizeof() more often. + * + * Revision 1.95 2007/02/10 17:01:37 fabiankeil + * Don't overlook map result for the forwarding-type. + * * Revision 1.94 2007/02/08 19:44:49 fabiankeil * Use a transparent background for the PNG replacement pattern. * @@ -577,10 +622,6 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.94 2007/02/08 19:44:49 fabiankeil Exp $"; #include #include -#ifdef _WIN32 -#define snprintf _snprintf -#endif /* def _WIN32 */ - #include "project.h" #include "cgi.h" #include "list.h" @@ -590,6 +631,7 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.94 2007/02/08 19:44:49 fabiankeil Exp $"; #include "filters.h" #include "miscutil.h" #include "cgisimple.h" +#include "jbsockets.h" #ifdef FEATURE_CGI_EDIT_ACTIONS #include "cgiedit.h" #endif /* def FEATURE_CGI_EDIT_ACTIONS */ @@ -730,6 +772,9 @@ static const struct cgi_dispatcher cgi_dispatchers[] = { { "t", cgi_transparent_image, NULL, TRUE /* Send a transparent image (short name) */ }, + { "url-info-osd.xml", + cgi_send_url_info_osd, + NULL, TRUE /* Send templates/url-info-osd.xml */ }, { "user-manual", cgi_send_user_manual, NULL, TRUE /* Send user-manual */ }, @@ -893,7 +938,7 @@ struct http_response *dispatch_cgi(struct client_state *csp) * Returns : pointer to value (no copy!), or NULL if none found. * *********************************************************************/ -char *grep_cgi_referrer(const struct client_state *csp) +static char *grep_cgi_referrer(const struct client_state *csp) { struct list_entry *p; @@ -925,10 +970,10 @@ char *grep_cgi_referrer(const struct client_state *csp) * FALSE if the referrer is unsafe or not set. * *********************************************************************/ -int referrer_is_safe (const struct client_state *csp) +static int referrer_is_safe(const struct client_state *csp) { char *referrer; - const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/"; + static const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/"; referrer = grep_cgi_referrer(csp); @@ -1417,7 +1462,8 @@ struct http_response *error_response(struct client_state *csp, } else if (!strcmp(templatename, "forwarding-failed")) { - const struct forward_spec * fwd = forward_url(csp->http, csp); + const struct forward_spec *fwd = forward_url(csp, csp->http); + char *socks_type = NULL; if (fwd == NULL) { log_error(LOG_LEVEL_FATAL, "gateway spec is NULL. This shouldn't happen!"); @@ -1443,8 +1489,27 @@ struct http_response *error_response(struct client_state *csp, csp->error_message = strdup("Failure reason missing. Check the log file for details."); } if (!err) err = map(exports, "gateway", 1, fwd->gateway_host, 1); - if (!err) err = map(exports, "forwarding-type", 1, (fwd->type == SOCKS_4) ? - "socks4-" : "socks4a-", 1); + + /* + * XXX: this is almost the same code as in cgi_show_url_info() + * and thus should be factored out and shared. + */ + switch (fwd->type) + { + case SOCKS_4: + socks_type = "socks4-"; + break; + case SOCKS_4A: + socks_type = "socks4a-"; + break; + case SOCKS_5: + socks_type = "socks5-"; + break; + default: + log_error(LOG_LEVEL_FATAL, "Unknown socks type: %d.", fwd->type); + } + + if (!err) err = map(exports, "forwarding-type", 1, socks_type, 1); if (!err) err = map(exports, "error-message", 1, html_encode(csp->error_message), 0); if (!err) rsp->status = strdup("503 Forwarding failure"); @@ -1500,7 +1565,7 @@ struct http_response *error_response(struct client_state *csp, * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_disabled(struct client_state *csp, +jb_err cgi_error_disabled(const struct client_state *csp, struct http_response *rsp) { struct map *exports; @@ -1603,7 +1668,7 @@ struct http_response *cgi_error_memory(void) * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_no_template(struct client_state *csp, +jb_err cgi_error_no_template(const struct client_state *csp, struct http_response *rsp, const char *template_name) { @@ -1620,7 +1685,7 @@ jb_err cgi_error_no_template(struct client_state *csp, "

Privoxy encountered an error while processing your request:

\r\n" "

Could not load template file "; static const char body_suffix[] = - " or one of it's included components.

\r\n" + " or one of its included components.

\r\n" "

Please contact your proxy administrator.

\r\n" "

If you are the proxy administrator, please put the required file(s)" "in the (confdir)/templates directory. The " @@ -1633,6 +1698,7 @@ jb_err cgi_error_no_template(struct client_state *csp, ").

\r\n" "\r\n" "\r\n"; + const size_t body_size = strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1; assert(csp); assert(rsp); @@ -1646,14 +1712,14 @@ jb_err cgi_error_no_template(struct client_state *csp, rsp->head_length = 0; rsp->is_static = 0; - rsp->body = malloc(strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1); + rsp->body = malloc(body_size); if (rsp->body == NULL) { return JB_ERR_MEMORY; } - strcpy(rsp->body, body_prefix); - strcat(rsp->body, template_name); - strcat(rsp->body, body_suffix); + strlcpy(rsp->body, body_prefix, body_size); + strlcat(rsp->body, template_name, body_size); + strlcat(rsp->body, body_suffix, body_size); rsp->status = strdup(status); if (rsp->status == NULL) @@ -1689,7 +1755,7 @@ jb_err cgi_error_no_template(struct client_state *csp, * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_unknown(struct client_state *csp, +jb_err cgi_error_unknown(const struct client_state *csp, struct http_response *rsp, jb_err error_to_report) { @@ -1713,6 +1779,11 @@ jb_err cgi_error_unknown(struct client_state *csp, "\r\n" "\r\n"; char errnumbuf[30]; + /* + * Due to sizeof(errnumbuf), body_size will be slightly + * bigger than necessary but it doesn't really matter. + */ + const size_t body_size = strlen(body_prefix) + sizeof(errnumbuf) + strlen(body_suffix) + 1; assert(csp); assert(rsp); @@ -1727,14 +1798,14 @@ jb_err cgi_error_unknown(struct client_state *csp, snprintf(errnumbuf, sizeof(errnumbuf), "%d", error_to_report); - rsp->body = malloc(strlen(body_prefix) + strlen(errnumbuf) + strlen(body_suffix) + 1); + rsp->body = malloc(body_size); if (rsp->body == NULL) { return JB_ERR_MEMORY; } - strcpy(rsp->body, body_prefix); - strcat(rsp->body, errnumbuf); - strcat(rsp->body, body_suffix); + strlcpy(rsp->body, body_prefix, body_size); + strlcat(rsp->body, errnumbuf, body_size); + strlcat(rsp->body, body_suffix, body_size); rsp->status = strdup(status); if (rsp->status == NULL) @@ -1763,7 +1834,7 @@ jb_err cgi_error_unknown(struct client_state *csp, * JB_ERR_MEMORY on out-of-memory error. * *********************************************************************/ -jb_err cgi_error_bad_param(struct client_state *csp, +jb_err cgi_error_bad_param(const struct client_state *csp, struct http_response *rsp) { struct map *exports; @@ -1878,13 +1949,15 @@ char *add_help_link(const char *item, * Parameters : * 1 : time_offset = Time returned will be current time * plus this number of seconds. - * 2 : buf = Destination for result. Must be long enough - * to hold 29 characters plus a trailing zero. + * 2 : buf = Destination for result. + * 3 : buffer_size = Size of the buffer above. Must be big + * enough to hold 29 characters plus a + * trailing zero. * * Returns : N/A * *********************************************************************/ -void get_http_time(int time_offset, char *buf) +void get_http_time(int time_offset, char *buf, size_t buffer_size) { static const char day_names[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; @@ -1905,6 +1978,7 @@ void get_http_time(int time_offset, char *buf) #endif assert(buf); + assert(buffer_size > 29); time(¤t_time); /* get current time */ @@ -1924,7 +1998,7 @@ void get_http_time(int time_offset, char *buf) } /* Format: "Sun, 06 Nov 1994 08:49:37 GMT" */ - snprintf(buf, 30, + snprintf(buf, buffer_size, "%s, %02d %s %4d %02d:%02d:%02d GMT", day_names[t->tm_wday], t->tm_mday, @@ -1968,9 +2042,12 @@ struct http_response *finish_http_response(const struct client_state *csp, struc } /* - * Fill in the HTTP Status + * Fill in the HTTP Status, using HTTP/1.1 + * unless the client asked for HTTP/1.0. */ - snprintf(buf, sizeof(buf), "HTTP/1.0 %s", rsp->status ? rsp->status : "200 OK"); + snprintf(buf, sizeof(buf), "%s %s", + strcmpic(csp->http->ver, "HTTP/1.0") ? "HTTP/1.1" : "HTTP/1.0", + rsp->status ? rsp->status : "200 OK"); err = enlist_first(rsp->headers, buf); /* @@ -2006,12 +2083,12 @@ struct http_response *finish_http_response(const struct client_state *csp, struc if (strncmpic(rsp->status, "302", 3)) { - /* - * If it's not a redirect without any content, - * set the Content-Type to text/html if it's - * not already specified. - */ - if (!err) err = enlist_unique(rsp->headers, "Content-Type: text/html", 13); + /* + * If it's not a redirect without any content, + * set the Content-Type to text/html if it's + * not already specified. + */ + if (!err) err = enlist_unique(rsp->headers, "Content-Type: text/html", 13); } /* @@ -2033,7 +2110,7 @@ struct http_response *finish_http_response(const struct client_state *csp, struc if (!err) { - get_http_time(0, buf); + get_http_time(0, buf, sizeof(buf)); err = enlist_unique_header(rsp->headers, "Date", buf); } @@ -2042,13 +2119,13 @@ struct http_response *finish_http_response(const struct client_state *csp, struc if (!err) { - get_http_time(10 * 60, buf); /* 10 * 60sec = 10 minutes */ + get_http_time(10 * 60, buf, sizeof(buf)); /* 10 * 60sec = 10 minutes */ err = enlist_unique_header(rsp->headers, "Expires", buf); } } else if (!strncmpic(rsp->status, "302", 3)) { - get_http_time(0, buf); + get_http_time(0, buf, sizeof(buf)); if (!err) err = enlist_unique_header(rsp->headers, "Date", buf); } else @@ -2074,7 +2151,7 @@ struct http_response *finish_http_response(const struct client_state *csp, struc */ if (!err) err = enlist_unique_header(rsp->headers, "Cache-Control", "no-cache"); - get_http_time(0, buf); + get_http_time(0, buf, sizeof(buf)); if (!err) err = enlist_unique_header(rsp->headers, "Date", buf); if (!strncmpic(rsp->status, "403", 3) || !strncmpic(rsp->status, "404", 3) @@ -2182,7 +2259,7 @@ void free_http_response(struct http_response *rsp) * JB_ERR_FILE if the template file cannot be read * *********************************************************************/ -jb_err template_load(struct client_state *csp, char **template_ptr, +jb_err template_load(const struct client_state *csp, char **template_ptr, const char *templatename, int recursive) { jb_err err; @@ -2461,7 +2538,7 @@ jb_err template_fill(char **template_ptr, const struct map *exports) * JB_ERR_MEMORY on out-of-memory error * *********************************************************************/ -jb_err template_fill_for_cgi(struct client_state *csp, +jb_err template_fill_for_cgi(const struct client_state *csp, const char *templatename, struct map *exports, struct http_response *rsp) @@ -2511,6 +2588,8 @@ struct map *default_exports(const struct client_state *csp, const char *caller) jb_err err; struct map * exports; int local_help_exists = 0; + char *ip_address = NULL; + char *hostname = NULL; assert(csp); @@ -2520,9 +2599,21 @@ struct map *default_exports(const struct client_state *csp, const char *caller) return NULL; } + if (csp->config->hostname) + { + get_host_information(csp->cfd, &ip_address, NULL); + hostname = strdup(csp->config->hostname); + } + else + { + get_host_information(csp->cfd, &ip_address, &hostname); + } + err = map(exports, "version", 1, html_encode(VERSION), 0); - if (!err) err = map(exports, "my-ip-address", 1, html_encode(csp->my_ip_addr_str ? csp->my_ip_addr_str : "unknown"), 0); - if (!err) err = map(exports, "my-hostname", 1, html_encode(csp->my_hostname ? csp->my_hostname : "unknown"), 0); + if (!err) err = map(exports, "my-ip-address", 1, html_encode(ip_address ? ip_address : "unknown"), 0); + freez(ip_address); + if (!err) err = map(exports, "my-hostname", 1, html_encode(hostname ? hostname : "unknown"), 0); + freez(hostname); if (!err) err = map(exports, "homepage", 1, html_encode(HOME_PAGE_URL), 0); if (!err) err = map(exports, "default-cgi", 1, html_encode(CGI_PREFIX), 0); if (!err) err = map(exports, "menu", 1, make_menu(caller, csp->config->feature_flags), 0); @@ -2545,7 +2636,7 @@ struct map *default_exports(const struct client_state *csp, const char *caller) if (!err) err = map_block_killer(exports, "can-toggle"); #endif - snprintf(buf, 20, "%d", csp->config->hport); + snprintf(buf, sizeof(buf), "%d", csp->config->hport); if (!err) err = map(exports, "my-port", 1, buf, 1); if(!strcmp(CODE_STATUS, "stable")) @@ -2614,7 +2705,7 @@ jb_err map_block_killer(struct map *exports, const char *name) assert(name); assert(strlen(name) < 490); - snprintf(buf, 1000, "if-%s-start.*if-%s-end", name, name); + snprintf(buf, sizeof(buf), "if-%s-start.*if-%s-end", name, name); return map(exports, buf, 1, "", 1); } @@ -2644,7 +2735,7 @@ jb_err map_block_keep(struct map *exports, const char *name) assert(name); assert(strlen(name) < 490); - snprintf(buf, 500, "if-%s-start", name); + snprintf(buf, sizeof(buf), "if-%s-start", name); err = map(exports, buf, 1, "", 1); if (err) @@ -2652,7 +2743,7 @@ jb_err map_block_keep(struct map *exports, const char *name) return err; } - snprintf(buf, 500, "if-%s-end", name); + snprintf(buf, sizeof(buf), "if-%s-end", name); return map(exports, buf, 1, "", 1); } @@ -2691,7 +2782,7 @@ jb_err map_conditional(struct map *exports, const char *name, int choose_first) assert(name); assert(strlen(name) < 480); - snprintf(buf, 1000, (choose_first + snprintf(buf, sizeof(buf), (choose_first ? "else-not-%s@.*@endif-%s" : "if-%s-then@.*@else-not-%s"), name, name); @@ -2702,7 +2793,7 @@ jb_err map_conditional(struct map *exports, const char *name, int choose_first) return err; } - snprintf(buf, 1000, (choose_first ? "if-%s-then" : "endif-%s"), name); + snprintf(buf, sizeof(buf), (choose_first ? "if-%s-then" : "endif-%s"), name); return map(exports, buf, 1, "", 1); }