From 69254e5cd2bdf2b290d82ed2d109b35b8b3248e8 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 31 Jan 2007 16:21:38 +0000 Subject: [PATCH] Search for Max-Forwards headers case-insensitive, don't generate the "501 unsupported" message for invalid Max-Forwards values and don't increase negative ones. --- filters.c | 53 ++++++++++++++++++++++++++++++++++------------------- parsers.c | 31 +++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/filters.c b/filters.c index be4cb65f..c9383993 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.77 2007/01/12 15:36:44 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.78 2007/01/28 13:41:18 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -40,6 +40,10 @@ const char filters_rcs[] = "$Id: filters.c,v 1.77 2007/01/12 15:36:44 fabiankeil * * Revisions : * $Log: filters.c,v $ + * Revision 1.78 2007/01/28 13:41:18 fabiankeil + * - Add HEAD support to finish_http_response. + * - Add error favicon to internal HTML error messages. + * * Revision 1.77 2007/01/12 15:36:44 fabiankeil * Mark *csp as immutable for is_untrusted_url() * and is_imageurl(). Closes FR 1237736. @@ -2241,29 +2245,40 @@ struct http_response *direct_response(struct client_state *csp) { for (p = csp->headers->first; (p != NULL) ; p = p->next) { - if (!strncmp("Max-Forwards:", p->str, 13) - && (*(p->str+13) != '\0') && (atoi(p->str+13) == 0)) + if (!strncmpic("Max-Forwards:", p->str, 13)) { - /* FIXME: We could handle at least TRACE here, - but that would require a verbatim copy of - the request which we don't have anymore */ - - log_error(LOG_LEVEL_HEADER, "Found Max-Forwards:0 in OPTIONS or TRACE request -- Returning 501"); + unsigned int max_forwards; - /* Get mem for response or fail*/ - if (NULL == (rsp = alloc_http_response())) + /* + * If it's a Max-Forwards value of zero, + * we have to intercept the request. + */ + if (1 == sscanf(p->str+12, ": %u", &max_forwards) && max_forwards == 0) { - return cgi_error_memory(); - } + /* + * FIXME: We could handle at least TRACE here, + * but that would require a verbatim copy of + * the request which we don't have anymore + */ + log_error(LOG_LEVEL_HEADER, + "Detected header \'%s\' in OPTIONS or TRACE request. Returning 501.", + p->str); + + /* Get mem for response or fail*/ + if (NULL == (rsp = alloc_http_response())) + { + return cgi_error_memory(); + } - if (NULL == (rsp->status = strdup("501 Not Implemented"))) - { - free_http_response(rsp); - return cgi_error_memory(); - } + if (NULL == (rsp->status = strdup("501 Not Implemented"))) + { + free_http_response(rsp); + return cgi_error_memory(); + } - rsp->is_static = 1; - return(finish_http_response(csp, rsp)); + rsp->is_static = 1; + return(finish_http_response(csp, rsp)); + } } } } diff --git a/parsers.c b/parsers.c index eb82e481..a1596b21 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.85 2007/01/26 15:33:46 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.86 2007/01/30 13:05:26 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -45,6 +45,15 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.85 2007/01/26 15:33:46 fabiankeil * * Revisions : * $Log: parsers.c,v $ + * Revision 1.86 2007/01/30 13:05:26 fabiankeil + * - Let server_set_cookie() check the expiration date + * of cookies and don't touch the ones that are already + * expired. Fixes problems with low quality web applications + * as described in BR 932612. + * + * - Adjust comment in client_max_forwards to reality; + * remove invalid Max-Forwards headers. + * * Revision 1.85 2007/01/26 15:33:46 fabiankeil * Stop filter_header() from unintentionally removing * empty header lines that were enlisted by the continue @@ -2644,25 +2653,31 @@ jb_err client_x_forwarded(struct client_state *csp, char **header) *********************************************************************/ jb_err client_max_forwards(struct client_state *csp, char **header) { - unsigned int max_forwards; + int max_forwards; if ((0 == strcmpic(csp->http->gpc, "trace")) || (0 == strcmpic(csp->http->gpc, "options"))) { - if (1 == sscanf(*header, "Max-Forwards: %u", &max_forwards)) + assert(*(*header+12) == ':'); + if (1 == sscanf(*header+12, ": %u", &max_forwards)) { if (max_forwards > 0) { snprintf(*header, strlen(*header)+1, "Max-Forwards: %u", --max_forwards); - log_error(LOG_LEVEL_HEADER, "Max-Forwards header for %s request replaced with: %s", - csp->http->gpc, *header); + log_error(LOG_LEVEL_HEADER, "Max-Forwards value for %s request reduced to %u.", + csp->http->gpc, max_forwards); + } + else if (max_forwards < 0) + { + log_error(LOG_LEVEL_ERROR, "Crunching invalid header: %s", *header); + freez(*header); } else { /* - * direct_response() which was called earlier - * in chat() should prevent that we ever get - * here. + * Not supposed to be reached. direct_response() which + * was already called earlier in chat() should have + * intercepted the request. */ log_error(LOG_LEVEL_ERROR, "Non-intercepted %s request with Max-Forwards zero!", csp->http->gpc); -- 2.39.2