]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Prevent truncation for large origin-relative domains (#427)
authorAmos Jeffries <yadij@users.noreply.github.com>
Fri, 12 Jul 2019 03:08:00 +0000 (03:08 +0000)
committerAmos Jeffries <yadij@users.noreply.github.com>
Sun, 8 Sep 2019 23:50:23 +0000 (11:50 +1200)
The domain in a URL must obey hostname length restrictions after
append_domain is applied, not just MAX_URL for the normalized
absolute-URL.

src/URL.h
src/internal.cc
src/url.cc

index d8ad3f2a42deaf4c3544d56ba1e801634bd7ad71..c17928ae2d0a45a62aa57d758f7f9e44aab3634e 100644 (file)
--- a/src/URL.h
+++ b/src/URL.h
@@ -115,6 +115,7 @@ enum MatchDomainNameFlags {
 int matchDomainName(const char *host, const char *domain, uint flags = mdnNone);
 int urlCheckRequest(const HttpRequest *);
 int urlDefaultPort(AnyP::ProtocolType p);
+bool urlAppendDomain(char *host);
 char *urlHostname(const char *url);
 void urlExtMethodConfigure(void);
 
index 772255ecbc3b86d012c513102c700e1d16af153d..693aa1f229e8268af0950062a00eb0674b8add5a 100644 (file)
@@ -92,13 +92,9 @@ internalRemoteUri(const char *host, unsigned short port, const char *dir, const
 
     /*
      * append the domain in order to mirror the requests with appended
-     * domains
+     * domains. If that fails, just use the hostname anyway.
      */
-
-    /* For IPv6 addresses also check for a colon */
-    if (Config.appendDomain && !strchr(lc_host, '.') && !strchr(lc_host, ':'))
-        strncat(lc_host, Config.appendDomain, SQUIDHOSTNAMELEN -
-                strlen(lc_host) - 1);
+    (void)urlAppendDomain(lc_host);
 
     /* build uri in mb */
     static MemBuf mb;
index 92aea367f8c8a88565843a4eacf70a950497c9db..2e54befd2daaa2f4107e1a869dd50294ac28b019 100644 (file)
@@ -175,6 +175,30 @@ urlDefaultPort(AnyP::ProtocolType p)
     }
 }
 
+/**
+ * Appends configured append_domain to hostname, assuming
+ * the given buffer is at least SQUIDHOSTNAMELEN bytes long,
+ * and that the host FQDN is not a 'dotless' TLD.
+ *
+ * \returns false if and only if there is not enough space to append
+ */
+bool
+urlAppendDomain(char *host)
+{
+    /* For IPv4 addresses check for a dot */
+    /* For IPv6 addresses also check for a colon */
+    if (Config.appendDomain && !strchr(host, '.') && !strchr(host, ':')) {
+        const uint64_t dlen = strlen(host);
+        const uint64_t want = dlen + Config.appendDomainLen;
+        if (want > SQUIDHOSTNAMELEN - 1) {
+            debugs(23, 2, "URL domain too large (" << dlen << " bytes)");
+            return false;
+        }
+        strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - dlen - 1);
+    }
+    return true;
+}
+
 /*
  * Parse a URI/URL.
  *
@@ -375,9 +399,8 @@ urlParse(const HttpRequestMethod& method, char *url, HttpRequest *request)
         return NULL;
     }
 
-    /* For IPV6 addresses also check for a colon */
-    if (Config.appendDomain && !strchr(host, '.') && !strchr(host, ':'))
-        strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(host) - 1);
+    if (!urlAppendDomain(host))
+        return NULL;
 
     /* remove trailing dots from hostnames */
     while ((l = strlen(host)) > 0 && host[--l] == '.')