]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Alexandre SIMON <alexandre.simon@ciril.fr>
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 7 Feb 2011 12:07:18 +0000 (05:07 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 7 Feb 2011 12:07:18 +0000 (05:07 -0700)
Bug 3144: redirector program blocks while reading STDIN

The string passed to redirect helper program may exceed the available
buffer space and be truncated. Thus having no \n terminator for the helper.

Test for this failure condition and produce an error page.

errors/Makefile.am
errors/templates/ERR_GATEWAY_FAILURE [new file with mode: 0644]
src/enums.h
src/redirect.cc

index d2f73f57dba86b8cb2129566939ff166f71ea9e0..b30c16d691fa367f4b96db3417008dd4dcca04ff 100644 (file)
@@ -29,6 +29,7 @@ ERROR_TEMPLATES =  \
        templates/ERR_FTP_PUT_ERROR \
        templates/ERR_FTP_PUT_MODIFIED \
        templates/ERR_FTP_UNAVAILABLE \
+       templates/ERR_GATEWAY_FAILURE \
        templates/ERR_ICAP_FAILURE \
        templates/ERR_INVALID_REQ \
        templates/ERR_INVALID_RESP \
diff --git a/errors/templates/ERR_GATEWAY_FAILURE b/errors/templates/ERR_GATEWAY_FAILURE
new file mode 100644 (file)
index 0000000..0a0cfeb
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>ERROR: The requested URL could not be retrieved</title>
+<style type="text/css"><!-- 
+ %l
+
+body
+:lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; }
+:lang(he) { direction: rtl; float: right; }
+ --></style>
+</head><body>
+<div id="titles">
+<h1>ERROR</h1>
+<h2>The requested URL could not be retrieved</h2>
+</div>
+<hr>
+
+<div id="content">
+<p>The following error was encountered while trying to retrieve the URL: <a href="%U">%U</a></p>
+
+<blockquote id="error">
+<p><b>Gateway Proxy Failure</b></p>
+</blockquote>
+
+<p>A non-recoverable internal failure or configuration problem prevents this request from being completed.</p>
+
+<p>This may be due to limits established by the Internet Service Provider who operates this cache. Please contact them directly for more information.</p>
+
+<p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p>
+<br>
+</div>
+
+<hr>
+<div id="footer">
+<p>Generated %T by %h (%s)</p>
+<!-- %c -->
+</div>
+</body></html>
index 5b089106baaf481e67642f0e93d974ca0b9f7683..9c0f2dcde23d8103506b9d0e6fef219ffdd9994e 100644 (file)
@@ -103,6 +103,7 @@ typedef enum {
     ERR_INVALID_RESP,
     ERR_ICAP_FAILURE,
     ERR_UNSUP_HTTPVERSION,     /* HTTP version is not supported */
+    ERR_GATEWAY_FAILURE,
     ERR_MAX
 } err_type;
 
index 04bbe8a08a2140a5549899953e6be5f0276bd4fe..ed4157b9ef1bd44d98e30d89b9305055d05aca70 100644 (file)
 #include "acl/Checklist.h"
 #include "HttpRequest.h"
 #include "client_side.h"
+#include "client_side_reply.h"
 #include "helper.h"
 #include "rfc1738.h"
 
+/// url maximum lengh + extra informations passed to redirector
+#define MAX_REDIRECTOR_REQUEST_STRLEN (MAX_URL + 1024)
+
 typedef struct {
     void *data;
     char *orig_url;
@@ -114,7 +118,9 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     ConnStateData * conn = http->getConn();
     redirectStateData *r = NULL;
     const char *fqdn;
-    char buf[8192];
+    char buf[MAX_REDIRECTOR_REQUEST_STRLEN];
+    int sz;
+    http_status status;
     char claddr[MAX_IPSTRLEN];
     char myaddr[MAX_IPSTRLEN];
     assert(http);
@@ -164,14 +170,41 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data)
     if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
         fqdn = dash_str;
 
-    snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
-             r->orig_url,
-             r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
-             fqdn,
-             r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
-             r->method_s,
-             http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
-             http->request->my_addr.GetPort());
+    sz = snprintf(buf, MAX_REDIRECTOR_REQUEST_STRLEN, "%s %s/%s %s %s myip=%s myport=%d\n",
+                  r->orig_url,
+                  r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
+                  fqdn,
+                  r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
+                  r->method_s,
+                  http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
+                  http->request->my_addr.GetPort());
+
+    if ((sz<=0) || (sz>=MAX_REDIRECTOR_REQUEST_STRLEN)) {
+        if (sz<=0) {
+            status = HTTP_INTERNAL_SERVER_ERROR;
+            debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Can not build request to be passed to redirector. Request ABORTED.");
+        } else {
+            status = HTTP_REQUEST_URI_TOO_LARGE;
+            debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Request passed to redirector exceeds MAX_REDIRECTOR_REQUEST_STRLEN (" << MAX_REDIRECTOR_REQUEST_STRLEN << "). Request ABORTED.");
+        }
+
+        clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data;
+        clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
+        assert (repContext);
+        IpAddress tmpnoaddr;
+        tmpnoaddr.SetNoAddr();
+        repContext->setReplyToError(ERR_GATEWAY_FAILURE, status,
+                                    http->request->method, NULL,
+                                    http->getConn() != NULL ? http->getConn()->peer : tmpnoaddr,
+                                    http->request,
+                                    NULL,
+                                    http->getConn() != NULL && http->getConn()->auth_user_request != NULL ?
+                                    http->getConn()->auth_user_request : http->request->auth_user_request);
+
+        node = (clientStreamNode *)http->client_stream.tail->data;
+        clientStreamRead(node, http, node->readBuffer);
+        return;
+    }
 
     helperSubmit(redirectors, buf, redirectHandleReply, r);
 }