]> 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)
committerSquid Anubis <squid-anubis@squid-cache.org>
Fri, 12 Jul 2019 11:49:40 +0000 (11:49 +0000)
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/anyp/Uri.cc
src/anyp/Uri.h
src/internal.cc

index 6ce8d9ba2588dcfc6b835f3c120d88ccda71e7ac..36d3fe2ac448d4316fcb98e4ab013a364d9880ed 100644 (file)
@@ -167,6 +167,30 @@ urlParseProtocol(const char *b)
     return AnyP::PROTO_NONE;
 }
 
+/**
+ * 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.
  *
@@ -376,9 +400,8 @@ AnyP::Uri::parse(const HttpRequestMethod& method, const char *url)
         return false;
     }
 
-    /* For IPV6 addresses also check for a colon */
-    if (Config.appendDomain && !strchr(foundHost, '.') && !strchr(foundHost, ':'))
-        strncat(foundHost, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(foundHost) - 1);
+    if (!urlAppendDomain(foundHost))
+        return false;
 
     /* remove trailing dots from hostnames */
     while ((l = strlen(foundHost)) > 0 && foundHost[--l] == '.')
index 5765f7e453b21d2045dbda5fdad9b8d151c9a43f..9d28bb001377a7fc3ec727766bf4d66ca340889f 100644 (file)
@@ -193,6 +193,7 @@ bool urlIsRelative(const char *);
 char *urlMakeAbsolute(const HttpRequest *, const char *);
 char *urlRInternal(const char *host, unsigned short port, const char *dir, const char *name);
 char *urlInternal(const char *dir, const char *name);
+bool urlAppendDomain(char *host); ///< apply append_domain config to the given hostname
 
 enum MatchDomainNameFlags {
     mdnNone = 0,
index 5e18ab5995cd90220f9a9a0b5feff79eedaad5cf..053ce629e0cac709462527335cda7abfc76cbbb0 100644 (file)
@@ -99,13 +99,9 @@ internalRemoteUri(bool encrypt, const char *host, unsigned short port, const cha
 
     /*
      * 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 */
     AnyP::Uri tmp(AnyP::PROTO_HTTP);