diff --git a/SOURCES/squid-3.5.20-CVE-2023-46724.patch b/SOURCES/squid-3.5.20-CVE-2023-46724.patch new file mode 100644 index 0000000..97df2c7 --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2023-46724.patch @@ -0,0 +1,210 @@ +From 792ef23e6e1c05780fe17f733859eef6eb8c8be3 Mon Sep 17 00:00:00 2001 +From: Andreas Weigel <andreas.weigel@securepoint.de> +Date: Wed, 18 Oct 2023 04:14:31 +0000 +Subject: [PATCH] Fix validation of certificates with CN=* (#1523) + +The bug was discovered and detailed by Joshua Rogers at +https://megamansec.github.io/Squid-Security-Audit/ +where it was filed as "Buffer UnderRead in SSL CN Parsing". + +Additionally includes upstream commit abbd782505c760279a8bd86a45c6095428f10752. +--- + src/URL.h | 39 ++++++++++++++++++++++++--------------- + src/acl/ServerName.cc | 2 +- + src/ssl/support.cc | 9 ++++++--- + src/url.cc | 37 ++++++++++++++++++++++++++++++++----- + 4 files changed, 63 insertions(+), 24 deletions(-) + +diff --git a/src/URL.h b/src/URL.h +index 7076958..9a6c091 100644 +--- a/src/URL.h ++++ b/src/URL.h +@@ -73,23 +73,29 @@ 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); + ++enum MatchDomainNameFlags { ++ mdnNone = 0, ++ mdnHonorWildcards = 1 << 0, ++ mdnRejectSubsubDomains = 1 << 1 ++}; ++ + /** +- * matchDomainName() compares a hostname (usually extracted from traffic) +- * with a domainname (usually from an ACL) according to the following rules: ++ * matchDomainName() matches a hostname (usually extracted from traffic) ++ * with a domainname when mdnNone or mdnRejectSubsubDomains flags are used ++ * according to the following rules: + * +- * HOST | DOMAIN | MATCH? +- * -------------|-------------|------ +- * foo.com | foo.com | YES +- * .foo.com | foo.com | YES +- * x.foo.com | foo.com | NO +- * foo.com | .foo.com | YES +- * .foo.com | .foo.com | YES +- * x.foo.com | .foo.com | YES ++ * HOST | DOMAIN | mdnNone | mdnRejectSubsubDomains ++ * -------------|-------------|-----------|----------------------- ++ * foo.com | foo.com | YES | YES ++ * .foo.com | foo.com | YES | YES ++ * x.foo.com | foo.com | NO | NO ++ * foo.com | .foo.com | YES | YES ++ * .foo.com | .foo.com | YES | YES ++ * x.foo.com | .foo.com | YES | YES ++ * .x.foo.com | .foo.com | YES | NO ++ * y.x.foo.com | .foo.com | YES | NO + * +- * We strip leading dots on hosts (but not domains!) so that +- * ".foo.com" is always the same as "foo.com". +- * +- * if honorWildcards is true then the matchDomainName() also accepts ++ * if mdnHonorWildcards flag is set then the matchDomainName() also accepts + * optional wildcards on hostname: + * + * HOST | DOMAIN | MATCH? +@@ -99,11 +105,14 @@ char *urlInternal(const char *dir, const char *name); + * *.foo.com | .foo.com | YES + * *.foo.com | foo.com | NO + * ++ * The combination of mdnHonorWildcards and mdnRejectSubsubDomains flags is ++ * supported. ++ * + * \retval 0 means the host matches the domain + * \retval 1 means the host is greater than the domain + * \retval -1 means the host is less than the domain + */ +-int matchDomainName(const char *host, const char *domain, bool honorWildcards = false); ++int matchDomainName(const char *host, const char *domain, uint flags = mdnNone); + int urlCheckRequest(const HttpRequest *); + int urlDefaultPort(AnyP::ProtocolType p); + char *urlHostname(const char *url); +diff --git a/src/acl/ServerName.cc b/src/acl/ServerName.cc +index 9cc08b2..f49209b 100644 +--- a/src/acl/ServerName.cc ++++ b/src/acl/ServerName.cc +@@ -30,7 +30,7 @@ aclHostDomainCompare( char *const &a, char * const &b) + const char *h = static_cast<const char *>(a); + const char *d = static_cast<const char *>(b); + debugs(28, 7, "Match:" << h << " <> " << d); +- return matchDomainName(h, d, true); ++ return matchDomainName(h, d, mdnHonorWildcards); + } + + bool +diff --git a/src/ssl/support.cc b/src/ssl/support.cc +index 6f01a94..5e33447 100644 +--- a/src/ssl/support.cc ++++ b/src/ssl/support.cc +@@ -199,9 +199,12 @@ static int check_domain( void *check_data, ASN1_STRING *cn_data) + char cn[1024]; + const char *server = (const char *)check_data; + +- if (cn_data->length > (int)sizeof(cn) - 1) { ++ if (cn_data->length == 0) ++ return 1; // zero length cn, ignore ++ ++ if (cn_data->length > (int)sizeof(cn) - 1) + return 1; //if does not fit our buffer just ignore +- } ++ + char *s = reinterpret_cast<char*>(cn_data->data); + char *d = cn; + for (int i = 0; i < cn_data->length; ++i, ++d, ++s) { +@@ -211,7 +214,7 @@ static int check_domain( void *check_data, ASN1_STRING *cn_data) + } + cn[cn_data->length] = '\0'; + debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn); +- return matchDomainName(server, cn[0] == '*' ? cn + 1 : cn); ++ return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains); + } + + bool Ssl::checkX509ServerValidity(X509 *cert, const char *server) +diff --git a/src/url.cc b/src/url.cc +index 1e14d05..0bddd0e 100644 +--- a/src/url.cc ++++ b/src/url.cc +@@ -54,6 +54,7 @@ urlInitialize(void) + assert(0 == matchDomainName("foo.com", ".foo.com")); + assert(0 == matchDomainName(".foo.com", ".foo.com")); + assert(0 == matchDomainName("x.foo.com", ".foo.com")); ++ assert(0 == matchDomainName("y.x.foo.com", ".foo.com")); + assert(0 != matchDomainName("x.foo.com", "foo.com")); + assert(0 != matchDomainName("foo.com", "x.foo.com")); + assert(0 != matchDomainName("bar.com", "foo.com")); +@@ -66,6 +67,17 @@ urlInitialize(void) + assert(0 < matchDomainName("bfoo.com", "afoo.com")); + assert(0 > matchDomainName("afoo.com", "bfoo.com")); + assert(0 < matchDomainName("x-foo.com", ".foo.com")); ++ ++ assert(0 == matchDomainName(".foo.com", ".foo.com", mdnRejectSubsubDomains)); ++ assert(0 == matchDomainName("x.foo.com", ".foo.com", mdnRejectSubsubDomains)); ++ assert(0 != matchDomainName("y.x.foo.com", ".foo.com", mdnRejectSubsubDomains)); ++ assert(0 != matchDomainName(".x.foo.com", ".foo.com", mdnRejectSubsubDomains)); ++ ++ assert(0 == matchDomainName("*.foo.com", "x.foo.com", mdnHonorWildcards)); ++ assert(0 == matchDomainName("*.foo.com", ".x.foo.com", mdnHonorWildcards)); ++ assert(0 == matchDomainName("*.foo.com", ".foo.com", mdnHonorWildcards)); ++ assert(0 != matchDomainName("*.foo.com", "foo.com", mdnHonorWildcards)); ++ + /* more cases? */ + } + +@@ -680,16 +692,20 @@ urlMakeAbsolute(const HttpRequest * req, const char *relUrl) + } + + int +-matchDomainName(const char *h, const char *d, bool honorWildcards) ++matchDomainName(const char *h, const char *d, uint flags) + { + int dl; + int hl; + ++ const bool hostIncludesSubdomains = (*h == '.'); + while ('.' == *h) + ++h; + + hl = strlen(h); + ++ if (hl == 0) ++ return -1; ++ + dl = strlen(d); + + /* +@@ -727,9 +743,20 @@ matchDomainName(const char *h, const char *d, bool honorWildcards) + * is a leading '.'. + */ + +- if ('.' == d[0]) +- return 0; +- else ++ if ('.' == d[0]) { ++ if (flags & mdnRejectSubsubDomains) { ++ // Check for sub-sub domain and reject ++ while(--hl >= 0 && h[hl] != '.'); ++ if (hl < 0) { ++ // No sub-sub domain found, but reject if there is a ++ // leading dot in given host string (which is removed ++ // before the check is started). ++ return hostIncludesSubdomains ? 1 : 0; ++ } else ++ return 1; // sub-sub domain, reject ++ } else ++ return 0; ++ } else + return 1; + } + } +@@ -741,7 +768,7 @@ matchDomainName(const char *h, const char *d, bool honorWildcards) + // If the h has a form of "*.foo.com" and d has a form of "x.foo.com" + // then the h[hl] points to '*', h[hl+1] to '.' and d[dl] to 'x' + // The following checks are safe, the "h[hl + 1]" in the worst case is '\0'. +- if (honorWildcards && h[hl] == '*' && h[hl + 1] == '.') ++ if ((flags & mdnHonorWildcards) && h[hl] == '*' && h[hl + 1] == '.') + return 0; + + /* +-- +2.43.0 + diff --git a/SOURCES/squid-3.5.20-CVE-2023-46728.patch b/SOURCES/squid-3.5.20-CVE-2023-46728.patch new file mode 100644 index 0000000..5e0409b --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2023-46728.patch @@ -0,0 +1,2308 @@ +From c31b89a042e54000516ce01779a0bd6f5bb53c1f Mon Sep 17 00:00:00 2001 +From: Stepan Broz <sbroz@redhat.com> +Date: Tue, 6 Feb 2024 14:12:32 +0100 +Subject: [PATCH] Remove gopher support + +--- + doc/debug-sections.txt | 1 - + errors/af/ERR_UNSUP_REQ | 2 +- + errors/ar/ERR_UNSUP_REQ | 2 +- + errors/az/ERR_UNSUP_REQ | 2 +- + errors/bg/ERR_UNSUP_REQ | 2 +- + errors/ca/ERR_UNSUP_REQ | 2 +- + errors/cs/ERR_UNSUP_REQ | 2 +- + errors/da/ERR_UNSUP_REQ | 2 +- + errors/de/ERR_UNSUP_REQ | 2 +- + errors/el/ERR_UNSUP_REQ | 2 +- + errors/en/ERR_UNSUP_REQ | 2 +- + errors/errorpage.css | 2 +- + errors/es/ERR_UNSUP_REQ | 2 +- + errors/et/ERR_UNSUP_REQ | 2 +- + errors/fa/ERR_UNSUP_REQ | 2 +- + errors/fi/ERR_UNSUP_REQ | 2 +- + errors/fr/ERR_UNSUP_REQ | 2 +- + errors/he/ERR_UNSUP_REQ | 2 +- + errors/hu/ERR_UNSUP_REQ | 2 +- + errors/hy/ERR_UNSUP_REQ | 2 +- + errors/id/ERR_UNSUP_REQ | 2 +- + errors/it/ERR_UNSUP_REQ | 2 +- + errors/ja/ERR_UNSUP_REQ | 2 +- + errors/ka/ERR_UNSUP_REQ | 2 +- + errors/ko/ERR_UNSUP_REQ | 2 +- + errors/lt/ERR_UNSUP_REQ | 2 +- + errors/lv/ERR_UNSUP_REQ | 2 +- + errors/ms/ERR_UNSUP_REQ | 2 +- + errors/nl/ERR_UNSUP_REQ | 2 +- + errors/oc/ERR_UNSUP_REQ | 2 +- + errors/pl/ERR_UNSUP_REQ | 2 +- + errors/pt-br/ERR_UNSUP_REQ | 2 +- + errors/pt/ERR_UNSUP_REQ | 2 +- + errors/ro/ERR_UNSUP_REQ | 2 +- + errors/ru/ERR_UNSUP_REQ | 2 +- + errors/sk/ERR_UNSUP_REQ | 2 +- + errors/sl/ERR_UNSUP_REQ | 2 +- + errors/sr-cyrl/ERR_UNSUP_REQ | 2 +- + errors/sr-latn/ERR_UNSUP_REQ | 2 +- + errors/sv/ERR_UNSUP_REQ | 2 +- + errors/templates/ERR_UNSUP_REQ | 2 +- + errors/th/ERR_UNSUP_REQ | 2 +- + errors/tr/ERR_UNSUP_REQ | 2 +- + errors/uk/ERR_UNSUP_REQ | 2 +- + errors/uz/ERR_UNSUP_REQ | 2 +- + errors/vi/ERR_UNSUP_REQ | 2 +- + errors/zh-hans/ERR_UNSUP_REQ | 2 +- + errors/zh-hant/ERR_UNSUP_REQ | 2 +- + src/FwdState.cc | 5 - + src/HttpRequest.cc | 6 - + src/IoStats.h | 2 +- + src/Makefile.am | 14 - + src/Makefile.in | 51 +- + src/adaptation/ecap/Host.cc | 1 - + src/adaptation/ecap/MessageRep.cc | 2 - + src/anyp/ProtocolType.cc | 1 - + src/anyp/ProtocolType.h | 1 - + src/cf.data.pre | 6 +- + src/client_side_request.cc | 4 - + src/err_type.h | 2 +- + src/gopher.cc | 982 ----------------------- + src/gopher.h | 29 - + src/mgr/IoAction.cc | 3 - + src/mgr/IoAction.h | 2 - + src/squid.8.in | 2 +- + src/stat.cc | 19 - + src/url.cc | 8 - + test-suite/squidconf/regressions-3.4.0.1 | 1 - + 68 files changed, 71 insertions(+), 1165 deletions(-) + delete mode 100644 src/gopher.cc + delete mode 100644 src/gopher.h + +diff --git a/doc/debug-sections.txt b/doc/debug-sections.txt +index 8f3be05..bea80e1 100644 +--- a/doc/debug-sections.txt ++++ b/doc/debug-sections.txt +@@ -27,7 +27,6 @@ section 06 Disk I/O Routines + section 07 Multicast + section 08 Swap File Bitmap + section 09 File Transfer Protocol (FTP) +-section 10 Gopher + section 11 Hypertext Transfer Protocol (HTTP) + section 12 Internet Cache Protocol (ICP) + section 13 High Level Memory Pool Management +diff --git a/errors/af/ERR_UNSUP_REQ b/errors/af/ERR_UNSUP_REQ +index e17daed..6851f71 100644 +--- a/errors/af/ERR_UNSUP_REQ ++++ b/errors/af/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Niegesteunde versoekmetode en -protokol</b></p> + </blockquote> + +-<p>Squid ondersteun nie alle navraagmetodes vir alle toegangsprotokolle nie. Mens kan by voorbeeld nie 'n Gopher-navraag POST nie.</p> ++<p>Squid ondersteun nie alle navraagmetodes vir alle toegangsprotokolle nie.</p> + + <p>Die kasbediener se administrateur is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ar/ERR_UNSUP_REQ b/errors/ar/ERR_UNSUP_REQ +index 2a85404..96ba37a 100644 +--- a/errors/ar/ERR_UNSUP_REQ ++++ b/errors/ar/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/az/ERR_UNSUP_REQ b/errors/az/ERR_UNSUP_REQ +index add8654..937babf 100644 +--- a/errors/az/ERR_UNSUP_REQ ++++ b/errors/az/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Dəstəklənməyən sorğu metodu və protokol</b></p> + </blockquote> + +-<p>Squid bütün sorğu metodları və bütün protokollardəstəkləmir. Məsələn, Gopher protokolu üzrə siz POST sorğu metodunu yerinə yetirə bilməzsiniz.</p> ++<p>Squid bütün sorğu metodları və bütün protokollardəstəkləmir.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/bg/ERR_UNSUP_REQ b/errors/bg/ERR_UNSUP_REQ +index c5d7220..97d386a 100644 +--- a/errors/bg/ERR_UNSUP_REQ ++++ b/errors/bg/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Сървърът не поддържа метода и/или протокола, посочен в заявката</b></p> + </blockquote> + +-<p>Кеш сървърът не поддържа всички методи на заявка за всички протоколи. Например, не можете да заявите метод POST за протокол Gopher.</p> ++<p>Кеш сървърът не поддържа всички методи на заявка за всички протоколи.</p> + + <p>Вашият кеш администратор е <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ca/ERR_UNSUP_REQ b/errors/ca/ERR_UNSUP_REQ +index 8115246..2a1cb55 100644 +--- a/errors/ca/ERR_UNSUP_REQ ++++ b/errors/ca/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Mètode i protocol no admesos</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>L'administrador d'aquesta cache és <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/cs/ERR_UNSUP_REQ b/errors/cs/ERR_UNSUP_REQ +index 4f87e8e..ff1664d 100644 +--- a/errors/cs/ERR_UNSUP_REQ ++++ b/errors/cs/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid nepodporuje všechny typy metod u všech protokolů. Např. není možno použit metodu POST u služby GOPHER.</p> ++<p>Squid nepodporuje všechny typy metod u všech protokolů.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/da/ERR_UNSUP_REQ b/errors/da/ERR_UNSUP_REQ +index 1773ae6..2a49b94 100644 +--- a/errors/da/ERR_UNSUP_REQ ++++ b/errors/da/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Uunderstøttet Forespørgsels Metode og Protokol</b></p> + </blockquote> + +-<p>Proxy'en Squid understøtter ikke alle forespørgselsmetoder for alle adgangs protokoller. For eksempel kan du ikke POST en Gopher forespørgsel.</p> ++<p>Proxy'en Squid understøtter ikke alle forespørgselsmetoder for alle adgangs protokoller.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/de/ERR_UNSUP_REQ b/errors/de/ERR_UNSUP_REQ +index e07cc92..d3e5462 100644 +--- a/errors/de/ERR_UNSUP_REQ ++++ b/errors/de/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Anfragemethode und Protokoll nicht unterstützt</b></p> + </blockquote> + +-<p>Squid unterstützt nicht alle Anfragemethoden für alle Protokolle. Sie können zum Beispiel keine POST Anfrage über das Gopher Protokoll senden.</p> ++<p>Squid unterstützt nicht alle Anfragemethoden für alle Protokolle.</p> + + <p>Ihr Cache Administrator ist <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/el/ERR_UNSUP_REQ b/errors/el/ERR_UNSUP_REQ +index e784f0d..0eba042 100644 +--- a/errors/el/ERR_UNSUP_REQ ++++ b/errors/el/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Μη υποστηριζόμενη μέθοδος αίτησης και πρωτόκολλο</b></p> + </blockquote> + +-<p>Το Squid δεν υποστηρίζει όλες τις μεθόδους αιτήσεων για όλα τα πρωτόκολλα πρόσβασης. Για παράδειγμα, το POST για Gopher δεν υποστηρίζεται.</p> ++<p>Το Squid δεν υποστηρίζει όλες τις μεθόδους αιτήσεων για όλα τα πρωτόκολλα πρόσβασης.</p> + + <p>Ο διαχειριστής του μεσολαβητή σας είναι ο <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/en/ERR_UNSUP_REQ b/errors/en/ERR_UNSUP_REQ +index 059b073..70a3b4e 100644 +--- a/errors/en/ERR_UNSUP_REQ ++++ b/errors/en/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/errorpage.css b/errors/errorpage.css +index 3b392fe..9762c6c 100644 +--- a/errors/errorpage.css ++++ b/errors/errorpage.css +@@ -74,7 +74,7 @@ pre { + font-family:sans-serif; + } + +-/* special event: FTP / Gopher directory listing */ ++/* special event: FTP directory listing */ + #dirmsg { + font-family: courier; + color: black; +diff --git a/errors/es/ERR_UNSUP_REQ b/errors/es/ERR_UNSUP_REQ +index 0671f65..b03dba6 100644 +--- a/errors/es/ERR_UNSUP_REQ ++++ b/errors/es/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Método de la petición y protocolo no soportados.</b></p> + </blockquote> + +-<p>Squid no admite todos los métodos para todos los protocolos de acceso. Por ejemplo, no se puede hacer un POST a un servidor Gopher.</p> ++<p>Squid no admite todos los métodos para todos los protocolos de acceso.</p> + + <p>Su administrador del caché es <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/et/ERR_UNSUP_REQ b/errors/et/ERR_UNSUP_REQ +index e44db4a..bb53957 100644 +--- a/errors/et/ERR_UNSUP_REQ ++++ b/errors/et/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Tundmatu päringu meetod ja protokoll</b></p> + </blockquote> + +-<p>Squid ei toeta kõiki päringu meetodeid kõikide protokollidega. Näiteks, te ei saa teha POST operatsiooni Gopher päringus.</p> ++<p>Squid ei toeta kõiki päringu meetodeid kõikide protokollidega.</p> + + <p>Teie teenusepakkuja aadress on <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/fa/ERR_UNSUP_REQ b/errors/fa/ERR_UNSUP_REQ +index f88dbfd..81b38f8 100644 +--- a/errors/fa/ERR_UNSUP_REQ ++++ b/errors/fa/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>روش پشتیبانینشده درخواست و قرارداد</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/fi/ERR_UNSUP_REQ b/errors/fi/ERR_UNSUP_REQ +index 6cfc3e8..1cd4164 100644 +--- a/errors/fi/ERR_UNSUP_REQ ++++ b/errors/fi/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Hakupyynnon tyyppi ja yhteyskäytäntö ei tuettu</b></p> + </blockquote> + +-<p>Squid ei tue kaikkia hakupyynnon tyyppejä kaikilla protokollilla. Et voi esimerkiksi käyttää POST-pyyntöä gopherilla.</p> ++<p>Squid ei tue kaikkia hakupyynnon tyyppejä kaikilla protokollilla.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/fr/ERR_UNSUP_REQ b/errors/fr/ERR_UNSUP_REQ +index b714037..fbadc39 100644 +--- a/errors/fr/ERR_UNSUP_REQ ++++ b/errors/fr/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>La méthode de requête et le protocole ne sont pas pris en charge.</b></p> + </blockquote> + +-<p>Squid ne prend pas en charge tous les types de requêtes par rapport à tous les protocoles d'accès. Vous ne pouvez pas par exemple utiliser une requête POST avec le protocole Gopher.</p> ++<p>Squid ne prend pas en charge tous les types de requêtes par rapport à tous les protocoles d'accès.</p> + + <p>Votre administrateur proxy est <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/he/ERR_UNSUP_REQ b/errors/he/ERR_UNSUP_REQ +index 2d0eafa..a96e3b8 100644 +--- a/errors/he/ERR_UNSUP_REQ ++++ b/errors/he/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>שיטת בקשה ופרוטוקול לא נתמכים</b></p> + </blockquote> + +-<p>שרת ה Squid אינו תומך בכל שיטות הבקשה לכל הפרוטוקולים. לדוגמא אינך יכול לשלוח בקשת POST ב-Gopher.</p> ++<p>שרת ה Squid אינו תומך בכל שיטות הבקשה לכל הפרוטוקולים.</p> + + <p>מנהל השרת הוא <a href="mailto:%w%W">%w</a>. </p> + <br> +diff --git a/errors/hu/ERR_UNSUP_REQ b/errors/hu/ERR_UNSUP_REQ +index d7f9223..c8d2871 100644 +--- a/errors/hu/ERR_UNSUP_REQ ++++ b/errors/hu/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Nem támogatott kéréstípus vagy protokoll</b></p> + </blockquote> + +-<p>A proxyszerver nem támogat minden létező kéréstípus és protokoll kombinációt, így pl. nem lehet POST kéréstípust használni egy Gopher kérésben.</p> ++<p>A proxyszerver nem támogat minden létező kéréstípus és protokoll kombinációt.</p> + + <p>A proxyszerver üzemeltetőjének e-mail címe: <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/hy/ERR_UNSUP_REQ b/errors/hy/ERR_UNSUP_REQ +index ee2a38f..77d48e3 100644 +--- a/errors/hy/ERR_UNSUP_REQ ++++ b/errors/hy/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Հարցում իրականացնելու մեթոդը և արձանագրությունը չեն աջակցվում</b></p> + </blockquote> + +-<p>Squid-ը բոլոր արձանագրությունների համար բոլոր հարցման մեթոդները չի աջակցում. Օրինակ, Gopher արձանագրության համար չեք կարող POST հարցում կատարել.</p> ++<p>Squid-ը բոլոր արձանագրությունների համար բոլոր հարցման մեթոդները չի աջակցում.</p> + + <p>Ձեր քեշի կառավարիչը <a href="mailto:%w%W">%w</a> է.</p> + <br> +diff --git a/errors/id/ERR_UNSUP_REQ b/errors/id/ERR_UNSUP_REQ +index 059b073..70a3b4e 100644 +--- a/errors/id/ERR_UNSUP_REQ ++++ b/errors/id/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/it/ERR_UNSUP_REQ b/errors/it/ERR_UNSUP_REQ +index 7a7594e..898201c 100644 +--- a/errors/it/ERR_UNSUP_REQ ++++ b/errors/it/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Metodo e protocollo della richiesta non sono supportati.</b></p> + </blockquote> + +-<p>Squid non consente di utilizzare qualsiasi tipo di richiesta per qualsiasi protocollo (a esempio non consente una richiesta POST su protocollo Gopher).</p> ++<p>Squid non consente di utilizzare qualsiasi tipo di richiesta per qualsiasi protocollo.</p> + + <p>L'amministratore del proxy è <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ja/ERR_UNSUP_REQ b/errors/ja/ERR_UNSUP_REQ +index 22ed098..92993e7 100644 +--- a/errors/ja/ERR_UNSUP_REQ ++++ b/errors/ja/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>サポートしていないリクエストメソッドとプロトコルです。</b></p> + </blockquote> + +-<p>Squidはすべてのアクセス・プロトコルに対して、すべてのリクエストメソッドをサポートしているわけではありません。例えば、POSTをGopherのリクエストで行うことはできません。</p> ++<p>Squidはすべてのアクセス・プロトコルに対して、すべてのリクエストメソッドをサポートしているわけではありません。</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ka/ERR_UNSUP_REQ b/errors/ka/ERR_UNSUP_REQ +index 059b073..70a3b4e 100644 +--- a/errors/ka/ERR_UNSUP_REQ ++++ b/errors/ka/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ko/ERR_UNSUP_REQ b/errors/ko/ERR_UNSUP_REQ +index 723f304..e892352 100644 +--- a/errors/ko/ERR_UNSUP_REQ ++++ b/errors/ko/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>지원되지 않는 Request Method와 프로토콜입니다.</b></p> + </blockquote> + +-<p>Squid는 모든 접속 프로토콜에 대한 request method를 지원하지 않습니다. 한가지 예로, Gopher에서 POST request를 사용할 수 없습니다.</p> ++<p>Squid는 모든 접속 프로토콜에 대한 request method를 지원하지 않습니다.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/lt/ERR_UNSUP_REQ b/errors/lt/ERR_UNSUP_REQ +index c5759e6..bb006c0 100644 +--- a/errors/lt/ERR_UNSUP_REQ ++++ b/errors/lt/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Nepalaikomas užklausos metodas ir protokolas</b></p> + </blockquote> + +-<p>Squid palaiko ne visus užklausos metodus daliai protokolų. Pavyzdžiui, jūs negalite vykdyti POST Gopher tipo užklausoje.</p> ++<p>Squid palaiko ne visus užklausos metodus daliai protokolų.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/lv/ERR_UNSUP_REQ b/errors/lv/ERR_UNSUP_REQ +index 1bd5dc6..3f60b6c 100644 +--- a/errors/lv/ERR_UNSUP_REQ ++++ b/errors/lv/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Neatbalstīta pieprasījuma metode un protokols</b></p> + </blockquote> + +-<p>Squid neatbalsta visas pieprasījuma metodes visiem protokoliem. Piemēram, Jūs nevarat veikt POST pieprasījumu izmantojot Gopher protokolu.</p> ++<p>Squid neatbalsta visas pieprasījuma metodes visiem protokoliem.</p> + + <p>Jūsu kešatmiņas administrators ir <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ms/ERR_UNSUP_REQ b/errors/ms/ERR_UNSUP_REQ +index ee6d67a..57c073e 100644 +--- a/errors/ms/ERR_UNSUP_REQ ++++ b/errors/ms/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Pengurus Proxy anda ialah <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/nl/ERR_UNSUP_REQ b/errors/nl/ERR_UNSUP_REQ +index f0a0107..e086cd0 100644 +--- a/errors/nl/ERR_UNSUP_REQ ++++ b/errors/nl/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Niet ondersteunde verzoekmethode of protocol</b></p> + </blockquote> + +-<p>Squid ondersteunt niet alle verzoekmethoden voor alle toegangsprotocollen. U kunt bijvoorbeeld geen Gopher verzoek POSTen.</p> ++<p>Squid ondersteunt niet alle verzoekmethoden voor alle toegangsprotocollen.</p> + + <p>De beheerder van deze cache is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/oc/ERR_UNSUP_REQ b/errors/oc/ERR_UNSUP_REQ +index af183ce..ff39a8f 100644 +--- a/errors/oc/ERR_UNSUP_REQ ++++ b/errors/oc/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Vòstre administrator d'amagatal es <a href="mailto:%w">%w</a>.</p> + <br> +diff --git a/errors/pl/ERR_UNSUP_REQ b/errors/pl/ERR_UNSUP_REQ +index 77e9350..9e84117 100644 +--- a/errors/pl/ERR_UNSUP_REQ ++++ b/errors/pl/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>użyta w żądaniu kombinacja metoda/protokół jest niewłaściwa</b></p> + </blockquote> + +-<p>Squid nie wspiera wszystkich metod we wszystkich protokołach. Na przykład nie możesz użyć metody POST w żądaniu skierowanym do usługi Gopher.</p> ++<p>Squid nie wspiera wszystkich metod we wszystkich protokołach.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/pt-br/ERR_UNSUP_REQ b/errors/pt-br/ERR_UNSUP_REQ +index e2948f9..ce9b632 100644 +--- a/errors/pt-br/ERR_UNSUP_REQ ++++ b/errors/pt-br/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Método e Protocolo de Requisição Não-Suportado</b></p> + </blockquote> + +-<p>Squid não suporta todos os métodos de requisição para todos os protocolos de acesso. Por exemplo, você não pode emitir uma requisição POST ao protocolo Gopher.</p> ++<p>Squid não suporta todos os métodos de requisição para todos os protocolos de acesso.</p> + + <p>Seu administrador do cache é <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/pt/ERR_UNSUP_REQ b/errors/pt/ERR_UNSUP_REQ +index 5201d24..3a744c1 100644 +--- a/errors/pt/ERR_UNSUP_REQ ++++ b/errors/pt/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Método ou protocolo não suportado.</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ro/ERR_UNSUP_REQ b/errors/ro/ERR_UNSUP_REQ +index 8ca0502..51324e9 100644 +--- a/errors/ro/ERR_UNSUP_REQ ++++ b/errors/ro/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Metodă de cerere şi protocol nesuportată</b></p> + </blockquote> + +-<p>Squid nu suportă toate metodele de cerere pentru toate protocoalele de acces. De exemplu, nu puteţi face o cerere de tip POST pentru Gopher.</p> ++<p>Squid nu suportă toate metodele de cerere pentru toate protocoalele de acces.</p> + + <p>Administratorul cache-ului este <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/ru/ERR_UNSUP_REQ b/errors/ru/ERR_UNSUP_REQ +index 5bd256a..a42d2e2 100644 +--- a/errors/ru/ERR_UNSUP_REQ ++++ b/errors/ru/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Неподдерживаемый метод запроса или протокол</b></p> + </blockquote> + +-<p>Squid не поддерживает все методы запросов для всех протоколов. К примеру, для протокола Gopher Вы не можете выполнить запрос POST.</p> ++<p>Squid не поддерживает все методы запросов для всех протоколов.</p> + + <p>Администратор Вашего кэша: <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/sk/ERR_UNSUP_REQ b/errors/sk/ERR_UNSUP_REQ +index 91718dc..9abbca8 100644 +--- a/errors/sk/ERR_UNSUP_REQ ++++ b/errors/sk/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Nepodporovaná metóda a protokol požiadavky</b></p> + </blockquote> + +-<p>Squid nepodporuje všetky typy metód pri všetkých protokoloch. Napríklad: nie je možné použiť metódu POST pri službe Gopher.</p> ++<p>Squid nepodporuje všetky typy metód pri všetkých protokoloch.</p> + + <p>Vaším správcom cache je <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/sl/ERR_UNSUP_REQ b/errors/sl/ERR_UNSUP_REQ +index e26d86f..bfc6a10 100644 +--- a/errors/sl/ERR_UNSUP_REQ ++++ b/errors/sl/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Nepodprta metoda zahteve in protokol</b></p> + </blockquote> + +-<p>Squid ne podpira vseh metod zahtev za vse protokole dostopa. Tako npr. metode POST ne morete uporabiti za zahtevo Gopher.</p> ++<p>Squid ne podpira vseh metod zahtev za vse protokole dostopa.</p> + + <p>Skrbnik vašega predpomnilnika je <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/sr-cyrl/ERR_UNSUP_REQ b/errors/sr-cyrl/ERR_UNSUP_REQ +index 059b073..70a3b4e 100644 +--- a/errors/sr-cyrl/ERR_UNSUP_REQ ++++ b/errors/sr-cyrl/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/sr-latn/ERR_UNSUP_REQ b/errors/sr-latn/ERR_UNSUP_REQ +index 78b0484..bfa783c 100644 +--- a/errors/sr-latn/ERR_UNSUP_REQ ++++ b/errors/sr-latn/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Nepodržan metod ili protokol zahteva (Request)</b></p> + </blockquote> + +-<p>Squid Proksi server ne podržava sve metode zahteva za sve moguæe pristupne protokole. Na primer ne možete da uradite POST na Gopher zahtev.</p> ++<p>Squid Proksi server ne podržava sve metode zahteva za sve moguæe pristupne protokole.</p> + + <p>Vaš keš/proksi administrator je: <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/sv/ERR_UNSUP_REQ b/errors/sv/ERR_UNSUP_REQ +index b8be6fb..48ecc87 100644 +--- a/errors/sv/ERR_UNSUP_REQ ++++ b/errors/sv/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Ej stöd för begärd Metod och Protokoll</b></p> + </blockquote> + +-<p>Squid stödjer inte alla frågemetoder för alla protokoll. Till exempel, Ni kan inte POST'a en Gopher förfrågan.</p> ++<p>Squid stödjer inte alla frågemetoder för alla protokoll.</p> + + <p>Din cacheserver administratör är <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/templates/ERR_UNSUP_REQ b/errors/templates/ERR_UNSUP_REQ +index 68b60c9..aaf6fe9 100644 +--- a/errors/templates/ERR_UNSUP_REQ ++++ b/errors/templates/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/th/ERR_UNSUP_REQ b/errors/th/ERR_UNSUP_REQ +index 3d71c0a..d0adcdb 100644 +--- a/errors/th/ERR_UNSUP_REQ ++++ b/errors/th/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>ไม่รองรับโปรโตคอลและวิธีการหรือคำสั่งที่เรียกมา (request method)</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>ผู้ดูแลระบบแคชของคุณคือ <a href="mailto:%w%W">%w</a></p> + <br> +diff --git a/errors/tr/ERR_UNSUP_REQ b/errors/tr/ERR_UNSUP_REQ +index 22e0b48..c985248 100644 +--- a/errors/tr/ERR_UNSUP_REQ ++++ b/errors/tr/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Desteklenmeyen istek yöntemi ve protokol.</b></p> + </blockquote> + +-<p>Squid, bazı erişim protokollerin, bazı istek yöntemlerini desteklemiyor. Örneğin Gopher isteğinizde POST yapamazsınız.</p> ++<p>Squid, bazı erişim protokollerin, bazı istek yöntemlerini desteklemiyor.</p> + + <p>Önbellk yöneticiniz <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/uk/ERR_UNSUP_REQ b/errors/uk/ERR_UNSUP_REQ +index 7deb9b9..f1bc7b4 100644 +--- a/errors/uk/ERR_UNSUP_REQ ++++ b/errors/uk/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Метод запиту чи протокол не підтримуються</b></p> + </blockquote> + +-<p>Squid не підтримує всі методи запитів для всіх наявних протоколів. Як приклад, Ви не можете виконати запит POST для протоколу Gopher.</p> ++<p>Squid не підтримує всі методи запитів для всіх наявних протоколів.</p> + + <p>Адміністратор даного кешу <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/uz/ERR_UNSUP_REQ b/errors/uz/ERR_UNSUP_REQ +index db3799e..c2c66dd 100644 +--- a/errors/uz/ERR_UNSUP_REQ ++++ b/errors/uz/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid does not support all request methods for all access protocols. For example, you can not POST a Gopher request.</p> ++<p>Squid does not support all request methods for all access protocols.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/vi/ERR_UNSUP_REQ b/errors/vi/ERR_UNSUP_REQ +index 4fbe5b2..6c6631a 100644 +--- a/errors/vi/ERR_UNSUP_REQ ++++ b/errors/vi/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>Unsupported Request Method and Protocol</b></p> + </blockquote> + +-<p>Squid không hỗ trợ tất cả các phương pháp yêu cầu cho mỗi giao thức truy cập. Chẳng hạn, bạn không có khả năng POST một yêu cầu Gopher.</p> ++<p>Squid không hỗ trợ tất cả các phương pháp yêu cầu cho mỗi giao thức truy cập.</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/zh-hans/ERR_UNSUP_REQ b/errors/zh-hans/ERR_UNSUP_REQ +index 263cffd..2fa387f 100644 +--- a/errors/zh-hans/ERR_UNSUP_REQ ++++ b/errors/zh-hans/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>不支持的请求方式和协议</b></p> + </blockquote> + +-<p>Squid (缓存服务器)不能对所有的存取协议支持所有的请求方式。比如说,你不能对 GOPHER 进行一个 POST 请求。</p> ++<p>Squid (缓存服务器)不能对所有的存取协议支持所有的请求方式。</p> + + <p>缓存服务器的管理员 <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/errors/zh-hant/ERR_UNSUP_REQ b/errors/zh-hant/ERR_UNSUP_REQ +index 8b56127..272219b 100644 +--- a/errors/zh-hant/ERR_UNSUP_REQ ++++ b/errors/zh-hant/ERR_UNSUP_REQ +@@ -24,7 +24,7 @@ body + <p><b>尚未支援的要求方式或通訊協定</b></p> + </blockquote> + +-<p>因為 Squid (網路快取程式)並未支援所有的連結要求方式在各式通訊協定上。比如說,你不能要求一個 GOPHER 的 POST 連結要求。</p> ++<p>因為 Squid (網路快取程式)並未支援所有的連結要求方式在各式通訊協定上。</p> + + <p>Your cache administrator is <a href="mailto:%w%W">%w</a>.</p> + <br> +diff --git a/src/FwdState.cc b/src/FwdState.cc +index c1d8a0f..42dfe20 100644 +--- a/src/FwdState.cc ++++ b/src/FwdState.cc +@@ -28,7 +28,6 @@ + #include "fde.h" + #include "FwdState.h" + #include "globals.h" +-#include "gopher.h" + #include "hier_code.h" + #include "http.h" + #include "HttpReply.h" +@@ -978,10 +977,6 @@ FwdState::dispatch() + httpStart(this); + break; + +- case AnyP::PROTO_GOPHER: +- gopherStart(this); +- break; +- + case AnyP::PROTO_FTP: + if (request->flags.ftpNative) + Ftp::StartRelay(this); +diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc +index f686251..abddd2b 100644 +--- a/src/HttpRequest.cc ++++ b/src/HttpRequest.cc +@@ -16,7 +16,6 @@ + #include "DnsLookupDetails.h" + #include "err_detail_type.h" + #include "globals.h" +-#include "gopher.h" + #include "http.h" + #include "HttpHdrCc.h" + #include "HttpHeaderRange.h" +@@ -580,11 +579,6 @@ HttpRequest::maybeCacheable() + // no-store, private and related which block cacheability + break; + +- case AnyP::PROTO_GOPHER: +- if (!gopherCachable(this)) +- return false; +- break; +- + case AnyP::PROTO_CACHE_OBJECT: + return false; + +diff --git a/src/IoStats.h b/src/IoStats.h +index 0383c09..3fbd0a2 100644 +--- a/src/IoStats.h ++++ b/src/IoStats.h +@@ -22,7 +22,7 @@ public: + int writes; + int write_hist[histSize]; + } +- Http, Ftp, Gopher; ++ Http, Ftp; + }; + + #endif /* SQUID_IOSTATS_H_ */ +diff --git a/src/Makefile.am b/src/Makefile.am +index c21032e..f34ace3 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -367,8 +367,6 @@ squid_SOURCES = \ + FwdState.h \ + Generic.h \ + globals.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + helper.h \ + hier_code.h \ +@@ -1482,8 +1480,6 @@ tests_testCacheManager_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + hier_code.h \ + helper.cc \ + $(HTCPSOURCE) \ +@@ -1898,8 +1894,6 @@ tests_testEvent_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -2145,8 +2139,6 @@ tests_testEventLoop_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -2388,8 +2380,6 @@ tests_test_http_range_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -2716,8 +2706,6 @@ tests_testHttpRequest_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -3568,8 +3556,6 @@ tests_testURL_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +diff --git a/src/Makefile.in b/src/Makefile.in +index 0e1c453..21bceff 100644 +--- a/src/Makefile.in ++++ b/src/Makefile.in +@@ -341,7 +341,7 @@ am__squid_SOURCES_DIST = AclRegs.cc AuthReg.cc AccessLogEntry.cc \ + ExternalACLEntry.h FadingCounter.h FadingCounter.cc fatal.h \ + fatal.cc fd.h fd.cc fde.cc fde.h FileMap.h filemap.cc \ + fqdncache.h fqdncache.cc FwdState.cc FwdState.h Generic.h \ +- globals.h gopher.h gopher.cc helper.cc helper.h hier_code.h \ ++ globals.h helper.cc helper.h hier_code.h \ + HierarchyLogEntry.h htcp.cc htcp.h HttpStateFlags.h http.cc \ + http.h HttpHeaderFieldStat.h HttpHdrCc.h HttpHdrCc.cc \ + HttpHdrCc.cci HttpHdrRange.cc HttpHdrSc.cc HttpHdrSc.h \ +@@ -437,7 +437,7 @@ am_squid_OBJECTS = $(am__objects_4) AccessLogEntry.$(OBJEXT) \ + event.$(OBJEXT) EventLoop.$(OBJEXT) external_acl.$(OBJEXT) \ + ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \ + fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) filemap.$(OBJEXT) \ +- fqdncache.$(OBJEXT) FwdState.$(OBJEXT) gopher.$(OBJEXT) \ ++ fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ + helper.$(OBJEXT) $(am__objects_9) http.$(OBJEXT) \ + HttpHdrCc.$(OBJEXT) HttpHdrRange.$(OBJEXT) HttpHdrSc.$(OBJEXT) \ + HttpHdrScTarget.$(OBJEXT) HttpHdrContRange.$(OBJEXT) \ +@@ -612,8 +612,8 @@ am__tests_testCacheManager_SOURCES_DIST = AccessLogEntry.cc debug.cc \ + DnsLookupDetails.cc errorpage.cc tests/stub_ETag.cc event.cc \ + external_acl.cc ExternalACLEntry.cc fatal.h \ + tests/stub_fatal.cc fd.h fd.cc fde.cc FileMap.h filemap.cc \ +- fqdncache.h fqdncache.cc FwdState.cc FwdState.h gopher.h \ +- gopher.cc hier_code.h helper.cc htcp.cc htcp.h \ ++ fqdncache.h fqdncache.cc FwdState.cc FwdState.h \ ++ hier_code.h helper.cc htcp.cc htcp.h \ + HttpStateFlags.h http.cc HttpBody.h HttpBody.cc HttpHeader.h \ + HttpHeader.cc HttpHeaderFieldInfo.h HttpHeaderTools.h \ + HttpHeaderTools.cc HttpHeaderFieldStat.h HttpHdrCc.h \ +@@ -672,7 +672,7 @@ am_tests_testCacheManager_OBJECTS = AccessLogEntry.$(OBJEXT) \ + external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ + filemap.$(OBJEXT) fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ +- gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_9) \ ++ helper.$(OBJEXT) $(am__objects_9) \ + http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \ + HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ + HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ +@@ -881,7 +881,7 @@ am__tests_testEvent_SOURCES_DIST = AccessLogEntry.cc BodyPipe.cc \ + EventLoop.h EventLoop.cc external_acl.cc ExternalACLEntry.cc \ + FadingCounter.cc fatal.h tests/stub_fatal.cc fd.h fd.cc fde.cc \ + FileMap.h filemap.cc fqdncache.h fqdncache.cc FwdState.cc \ +- FwdState.h gopher.h gopher.cc helper.cc hier_code.h htcp.cc \ ++ FwdState.h helper.cc hier_code.h htcp.cc \ + htcp.h http.cc HttpBody.h HttpBody.cc HttpHeader.h \ + HttpHeader.cc HttpHeaderFieldInfo.h HttpHeaderTools.h \ + HttpHeaderTools.cc HttpHeaderFieldStat.h HttpHdrCc.h \ +@@ -939,7 +939,7 @@ am_tests_testEvent_OBJECTS = AccessLogEntry.$(OBJEXT) \ + ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ + filemap.$(OBJEXT) fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ +- gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_9) \ ++ helper.$(OBJEXT) $(am__objects_9) \ + http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \ + HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ + HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ +@@ -1012,8 +1012,8 @@ am__tests_testEventLoop_SOURCES_DIST = AccessLogEntry.cc BodyPipe.cc \ + EventLoop.h EventLoop.cc event.cc external_acl.cc \ + ExternalACLEntry.cc FadingCounter.cc fatal.h \ + tests/stub_fatal.cc fd.h fd.cc fde.cc FileMap.h filemap.cc \ +- fqdncache.h fqdncache.cc FwdState.cc FwdState.h gopher.h \ +- gopher.cc helper.cc hier_code.h htcp.cc htcp.h http.cc \ ++ fqdncache.h fqdncache.cc FwdState.cc FwdState.h \ ++ helper.cc hier_code.h htcp.cc htcp.h http.cc \ + HttpBody.h HttpBody.cc HttpHeader.h HttpHeader.cc \ + HttpHeaderFieldInfo.h HttpHeaderTools.h HttpHeaderTools.cc \ + HttpHeaderFieldStat.h HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci \ +@@ -1070,7 +1070,7 @@ am_tests_testEventLoop_OBJECTS = AccessLogEntry.$(OBJEXT) \ + ExternalACLEntry.$(OBJEXT) FadingCounter.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ + filemap.$(OBJEXT) fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ +- gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_9) \ ++ helper.$(OBJEXT) $(am__objects_9) \ + http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \ + HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ + HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ +@@ -1197,7 +1197,7 @@ am__tests_testHttpRequest_SOURCES_DIST = AccessLogEntry.cc \ + DnsLookupDetails.cc errorpage.cc tests/stub_ETag.cc \ + external_acl.cc ExternalACLEntry.cc fatal.h \ + tests/stub_fatal.cc fd.h fd.cc fde.cc fqdncache.h fqdncache.cc \ +- FwdState.cc FwdState.h gopher.h gopher.cc helper.cc \ ++ FwdState.cc FwdState.h helper.cc \ + hier_code.h htcp.cc htcp.h http.cc HttpBody.h HttpBody.cc \ + HttpHeader.h HttpHeader.cc HttpHeaderFieldInfo.h \ + HttpHeaderTools.h HttpHeaderTools.cc HttpHeaderFieldStat.h \ +@@ -1257,7 +1257,7 @@ am_tests_testHttpRequest_OBJECTS = AccessLogEntry.$(OBJEXT) \ + $(am__objects_8) errorpage.$(OBJEXT) tests/stub_ETag.$(OBJEXT) \ + external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ +- fqdncache.$(OBJEXT) FwdState.$(OBJEXT) gopher.$(OBJEXT) \ ++ fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ + helper.$(OBJEXT) $(am__objects_9) http.$(OBJEXT) \ + HttpBody.$(OBJEXT) HttpHeader.$(OBJEXT) \ + HttpHeaderTools.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ +@@ -1648,8 +1648,8 @@ am__tests_testURL_SOURCES_DIST = AccessLogEntry.cc BodyPipe.cc \ + DnsLookupDetails.cc errorpage.cc ETag.cc event.cc \ + external_acl.cc ExternalACLEntry.cc fatal.h \ + tests/stub_fatal.cc fd.h fd.cc fde.cc FileMap.h filemap.cc \ +- fqdncache.h fqdncache.cc FwdState.cc FwdState.h gopher.h \ +- gopher.cc helper.cc hier_code.h htcp.cc htcp.h http.cc \ ++ fqdncache.h fqdncache.cc FwdState.cc FwdState.h \ ++ helper.cc hier_code.h htcp.cc htcp.h http.cc \ + HttpBody.h HttpBody.cc HttpHeaderFieldStat.h HttpHdrCc.h \ + HttpHdrCc.cc HttpHdrCc.cci HttpHdrContRange.cc HttpHdrRange.cc \ + HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.h HttpHeader.cc \ +@@ -1708,7 +1708,7 @@ am_tests_testURL_OBJECTS = AccessLogEntry.$(OBJEXT) BodyPipe.$(OBJEXT) \ + external_acl.$(OBJEXT) ExternalACLEntry.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ + filemap.$(OBJEXT) fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ +- gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_9) \ ++ helper.$(OBJEXT) $(am__objects_9) \ + http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ + HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ + HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \ +@@ -1891,8 +1891,8 @@ am__tests_test_http_range_SOURCES_DIST = AccessLogEntry.cc BodyPipe.cc \ + DnsLookupDetails.cc errorpage.cc tests/stub_ETag.cc event.cc \ + FadingCounter.cc fatal.h tests/stub_libauth.cc \ + tests/stub_fatal.cc fd.h fd.cc fde.cc FileMap.h filemap.cc \ +- fqdncache.h fqdncache.cc FwdState.cc FwdState.h gopher.h \ +- gopher.cc helper.cc hier_code.h htcp.cc htcp.h http.cc \ ++ fqdncache.h fqdncache.cc FwdState.cc FwdState.h \ ++ helper.cc hier_code.h htcp.cc htcp.h http.cc \ + HttpBody.h HttpBody.cc HttpHeaderFieldStat.h HttpHdrCc.h \ + HttpHdrCc.cc HttpHdrCc.cci HttpHdrContRange.cc HttpHdrRange.cc \ + HttpHdrSc.cc HttpHdrScTarget.cc HttpHeader.h HttpHeader.cc \ +@@ -1948,7 +1948,7 @@ am_tests_test_http_range_OBJECTS = AccessLogEntry.$(OBJEXT) \ + FadingCounter.$(OBJEXT) tests/stub_libauth.$(OBJEXT) \ + tests/stub_fatal.$(OBJEXT) fd.$(OBJEXT) fde.$(OBJEXT) \ + filemap.$(OBJEXT) fqdncache.$(OBJEXT) FwdState.$(OBJEXT) \ +- gopher.$(OBJEXT) helper.$(OBJEXT) $(am__objects_9) \ ++ helper.$(OBJEXT) $(am__objects_9) \ + http.$(OBJEXT) HttpBody.$(OBJEXT) HttpHdrCc.$(OBJEXT) \ + HttpHdrContRange.$(OBJEXT) HttpHdrRange.$(OBJEXT) \ + HttpHdrSc.$(OBJEXT) HttpHdrScTarget.$(OBJEXT) \ +@@ -2865,7 +2865,7 @@ squid_SOURCES = $(ACL_REGISTRATION_SOURCES) AccessLogEntry.cc \ + ExternalACLEntry.cc ExternalACLEntry.h FadingCounter.h \ + FadingCounter.cc fatal.h fatal.cc fd.h fd.cc fde.cc fde.h \ + FileMap.h filemap.cc fqdncache.h fqdncache.cc FwdState.cc \ +- FwdState.h Generic.h globals.h gopher.h gopher.cc helper.cc \ ++ FwdState.h Generic.h globals.h helper.cc \ + helper.h hier_code.h HierarchyLogEntry.h $(HTCPSOURCE) \ + HttpStateFlags.h http.cc http.h HttpHeaderFieldStat.h \ + HttpHdrCc.h HttpHdrCc.cc HttpHdrCc.cci HttpHdrRange.cc \ +@@ -3673,8 +3673,6 @@ tests_testCacheManager_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + hier_code.h \ + helper.cc \ + $(HTCPSOURCE) \ +@@ -4093,8 +4091,6 @@ tests_testEvent_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -4342,8 +4338,6 @@ tests_testEventLoop_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -4588,8 +4582,6 @@ tests_test_http_range_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -4922,8 +4914,6 @@ tests_testHttpRequest_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -5782,8 +5772,6 @@ tests_testURL_SOURCES = \ + fqdncache.cc \ + FwdState.cc \ + FwdState.h \ +- gopher.h \ +- gopher.cc \ + helper.cc \ + hier_code.h \ + $(HTCPSOURCE) \ +@@ -6970,7 +6958,6 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filemap.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fqdncache.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gopher.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hier_code.Po@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htcp.Po@am__quote@ +diff --git a/src/adaptation/ecap/Host.cc b/src/adaptation/ecap/Host.cc +index 30b9661..0a9f745 100644 +--- a/src/adaptation/ecap/Host.cc ++++ b/src/adaptation/ecap/Host.cc +@@ -48,7 +48,6 @@ Adaptation::Ecap::Host::Host() + libecap::protocolHttp.assignHostId(AnyP::PROTO_HTTP); + libecap::protocolHttps.assignHostId(AnyP::PROTO_HTTPS); + libecap::protocolFtp.assignHostId(AnyP::PROTO_FTP); +- libecap::protocolGopher.assignHostId(AnyP::PROTO_GOPHER); + libecap::protocolWais.assignHostId(AnyP::PROTO_WAIS); + libecap::protocolUrn.assignHostId(AnyP::PROTO_URN); + libecap::protocolWhois.assignHostId(AnyP::PROTO_WHOIS); +diff --git a/src/adaptation/ecap/MessageRep.cc b/src/adaptation/ecap/MessageRep.cc +index cff44d4..b9c783e 100644 +--- a/src/adaptation/ecap/MessageRep.cc ++++ b/src/adaptation/ecap/MessageRep.cc +@@ -149,8 +149,6 @@ Adaptation::Ecap::FirstLineRep::protocol() const + return libecap::protocolHttps; + case AnyP::PROTO_FTP: + return libecap::protocolFtp; +- case AnyP::PROTO_GOPHER: +- return libecap::protocolGopher; + case AnyP::PROTO_WAIS: + return libecap::protocolWais; + case AnyP::PROTO_WHOIS: +diff --git a/src/anyp/ProtocolType.cc b/src/anyp/ProtocolType.cc +index 5b4fca3..304c0fd 100644 +--- a/src/anyp/ProtocolType.cc ++++ b/src/anyp/ProtocolType.cc +@@ -13,7 +13,6 @@ const char * ProtocolType_str[] = { + "HTTPS", + "COAP", + "COAPS", +- "GOPHER", + "WAIS", + "CACHE_OBJECT", + "ICP", +diff --git a/src/anyp/ProtocolType.h b/src/anyp/ProtocolType.h +index 1235521..aa68dda 100644 +--- a/src/anyp/ProtocolType.h ++++ b/src/anyp/ProtocolType.h +@@ -26,7 +26,6 @@ typedef enum { + PROTO_HTTPS, + PROTO_COAP, + PROTO_COAPS, +- PROTO_GOPHER, + PROTO_WAIS, + PROTO_CACHE_OBJECT, + PROTO_ICP, +diff --git a/src/cf.data.pre b/src/cf.data.pre +index f47dcd9..5bdef86 100644 +--- a/src/cf.data.pre ++++ b/src/cf.data.pre +@@ -1220,7 +1220,6 @@ acl SSL_ports port 443 + acl Safe_ports port 80 # http + acl Safe_ports port 21 # ftp + acl Safe_ports port 443 # https +-acl Safe_ports port 70 # gopher + acl Safe_ports port 210 # wais + acl Safe_ports port 1025-65535 # unregistered ports + acl Safe_ports port 280 # http-mgmt +@@ -4211,7 +4210,7 @@ DOC_START + [http::]<bs Number of HTTP-equivalent message body bytes + received from the next hop, excluding chunked + transfer encoding and control messages. +- Generated FTP/Gopher listings are treated as ++ Generated FTP listings are treated as + received bodies. + + +@@ -5479,7 +5478,6 @@ NOCOMMENT_START + # Add any of your own refresh_pattern entries above these. + # + refresh_pattern ^ftp: 1440 20% 10080 +-refresh_pattern ^gopher: 1440 0% 1440 + refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 + refresh_pattern . 0 20% 4320 + NOCOMMENT_END +@@ -8053,7 +8051,7 @@ DOC_START + client IP can use. Any more than this and Squid will begin to drop + new connections from the client until it closes some links. + +- Note that this is a global limit. It affects all HTTP, HTCP, Gopher and FTP ++ Note that this is a global limit. It affects all HTTP, HTCP, and FTP + connections from the client. For finer control use the ACL access controls. + + Requires client_db to be enabled (the default). +diff --git a/src/client_side_request.cc b/src/client_side_request.cc +index 2de3cb5..57d8975 100644 +--- a/src/client_side_request.cc ++++ b/src/client_side_request.cc +@@ -33,7 +33,6 @@ + #include "fd.h" + #include "fde.h" + #include "format/Token.h" +-#include "gopher.h" + #include "helper.h" + #include "helper/Reply.h" + #include "http.h" +@@ -960,9 +959,6 @@ clientHierarchical(ClientHttpRequest * http) + if (request->url.getScheme() == AnyP::PROTO_HTTP) + return method.respMaybeCacheable(); + +- if (request->url.getScheme() == AnyP::PROTO_GOPHER) +- return gopherCachable(request); +- + if (request->url.getScheme() == AnyP::PROTO_CACHE_OBJECT) + return 0; + +diff --git a/src/err_type.h b/src/err_type.h +index c6f0dae..5c634ee 100644 +--- a/src/err_type.h ++++ b/src/err_type.h +@@ -65,7 +65,7 @@ typedef enum { + ERR_GATEWAY_FAILURE, + + /* Special Cases */ +- ERR_DIR_LISTING, /* Display of remote directory (FTP, Gopher) */ ++ ERR_DIR_LISTING, /* Display of remote directory (FTP) */ + ERR_SQUID_SIGNATURE, /* not really an error */ + ERR_SHUTTING_DOWN, + +diff --git a/src/gopher.cc b/src/gopher.cc +deleted file mode 100644 +index 07acdba..0000000 +--- a/src/gopher.cc ++++ /dev/null +@@ -1,982 +0,0 @@ +-/* +- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors +- * +- * Squid software is distributed under GPLv2+ license and includes +- * contributions from numerous individuals and organizations. +- * Please see the COPYING and CONTRIBUTORS files for details. +- */ +- +-/* DEBUG: section 10 Gopher */ +- +-#include "squid.h" +-#include "comm.h" +-#include "comm/Read.h" +-#include "comm/Write.h" +-#include "errorpage.h" +-#include "fd.h" +-#include "FwdState.h" +-#include "globals.h" +-#include "html_quote.h" +-#include "HttpReply.h" +-#include "HttpRequest.h" +-#include "Mem.h" +-#include "MemBuf.h" +-#include "mime.h" +-#include "rfc1738.h" +-#include "SquidConfig.h" +-#include "SquidTime.h" +-#include "StatCounters.h" +-#include "Store.h" +-#include "tools.h" +- +-#if USE_DELAY_POOLS +-#include "DelayPools.h" +-#include "MemObject.h" +-#endif +- +-/** +- \defgroup ServerProtocolGopherInternal Server-Side Gopher Internals +- \ingroup ServerProtocolGopherAPI +- * Gopher is somewhat complex and gross because it must convert from +- * the Gopher protocol to HTTP. +- */ +- +-/* gopher type code from rfc. Anawat. */ +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_FILE '0' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_DIRECTORY '1' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_CSO '2' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_ERROR '3' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_MACBINHEX '4' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_DOSBIN '5' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_UUENCODED '6' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_INDEX '7' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_TELNET '8' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_BIN '9' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_REDUNT '+' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_3270 'T' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_GIF 'g' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_IMAGE 'I' +- +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_HTML 'h' /* HTML */ +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_INFO 'i' +-/** +- \ingroup ServerProtocolGopherInternal +- W3 address +- */ +-#define GOPHER_WWW 'w' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_SOUND 's' +- +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_PLUS_IMAGE ':' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_PLUS_MOVIE ';' +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_PLUS_SOUND '<' +- +-/// \ingroup ServerProtocolGopherInternal +-#define GOPHER_PORT 70 +- +-/// \ingroup ServerProtocolGopherInternal +-#define TAB '\t' +-/// \ingroup ServerProtocolGopherInternal +-/// \todo CODE: should this be a protocol-specific thing? +-#define TEMP_BUF_SIZE 4096 +-/// \ingroup ServerProtocolGopherInternal +-#define MAX_CSO_RESULT 1024 +- +-/// \ingroup ServerProtocolGopherInternal +-typedef struct gopher_ds { +- StoreEntry *entry; +- enum { +- NORMAL, +- HTML_DIR, +- HTML_INDEX_RESULT, +- HTML_CSO_RESULT, +- HTML_INDEX_PAGE, +- HTML_CSO_PAGE +- } conversion; +- int HTML_header_added; +- int HTML_pre; +- char type_id; +- char request[MAX_URL]; +- int cso_recno; +- int len; +- char *buf; /* pts to a 4k page */ +- Comm::ConnectionPointer serverConn; +- HttpRequest *req; +- FwdState::Pointer fwd; +- char replybuf[BUFSIZ]; +-} GopherStateData; +- +-static CLCB gopherStateFree; +-static void gopherMimeCreate(GopherStateData *); +-static void gopher_request_parse(const HttpRequest * req, +- char *type_id, +- char *request); +-static void gopherEndHTML(GopherStateData *); +-static void gopherToHTML(GopherStateData *, char *inbuf, int len); +-static CTCB gopherTimeout; +-static IOCB gopherReadReply; +-static IOCB gopherSendComplete; +-static PF gopherSendRequest; +- +-/// \ingroup ServerProtocolGopherInternal +-static char def_gopher_bin[] = "www/unknown"; +- +-/// \ingroup ServerProtocolGopherInternal +-static char def_gopher_text[] = "text/plain"; +- +-/// \ingroup ServerProtocolGopherInternal +-static void +-gopherStateFree(const CommCloseCbParams ¶ms) +-{ +- GopherStateData *gopherState = (GopherStateData *)params.data; +- +- if (gopherState == NULL) +- return; +- +- if (gopherState->entry) { +- gopherState->entry->unlock("gopherState"); +- } +- +- HTTPMSGUNLOCK(gopherState->req); +- +- gopherState->fwd = NULL; // refcounted +- +- memFree(gopherState->buf, MEM_4K_BUF); +- gopherState->buf = NULL; +- cbdataFree(gopherState); +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * Create MIME Header for Gopher Data +- */ +-static void +-gopherMimeCreate(GopherStateData * gopherState) +-{ +- StoreEntry *entry = gopherState->entry; +- const char *mime_type = NULL; +- const char *mime_enc = NULL; +- +- switch (gopherState->type_id) { +- +- case GOPHER_DIRECTORY: +- +- case GOPHER_INDEX: +- +- case GOPHER_HTML: +- +- case GOPHER_WWW: +- +- case GOPHER_CSO: +- mime_type = "text/html"; +- break; +- +- case GOPHER_GIF: +- +- case GOPHER_IMAGE: +- +- case GOPHER_PLUS_IMAGE: +- mime_type = "image/gif"; +- break; +- +- case GOPHER_SOUND: +- +- case GOPHER_PLUS_SOUND: +- mime_type = "audio/basic"; +- break; +- +- case GOPHER_PLUS_MOVIE: +- mime_type = "video/mpeg"; +- break; +- +- case GOPHER_MACBINHEX: +- +- case GOPHER_DOSBIN: +- +- case GOPHER_UUENCODED: +- +- case GOPHER_BIN: +- /* Rightnow We have no idea what it is. */ +- mime_enc = mimeGetContentEncoding(gopherState->request); +- mime_type = mimeGetContentType(gopherState->request); +- if (!mime_type) +- mime_type = def_gopher_bin; +- break; +- +- case GOPHER_FILE: +- +- default: +- mime_enc = mimeGetContentEncoding(gopherState->request); +- mime_type = mimeGetContentType(gopherState->request); +- if (!mime_type) +- mime_type = def_gopher_text; +- break; +- } +- +- assert(entry->isEmpty()); +- +- HttpReply *reply = new HttpReply; +- entry->buffer(); +- reply->setHeaders(Http::scOkay, "Gatewaying", mime_type, -1, -1, -2); +- if (mime_enc) +- reply->header.putStr(HDR_CONTENT_ENCODING, mime_enc); +- +- entry->replaceHttpReply(reply); +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * Parse a gopher request into components. By Anawat. +- */ +-static void +-gopher_request_parse(const HttpRequest * req, char *type_id, char *request) +-{ +- const char *path = req->urlpath.termedBuf(); +- +- if (request) +- request[0] = '\0'; +- +- if (path && (*path == '/')) +- ++path; +- +- if (!path || !*path) { +- *type_id = GOPHER_DIRECTORY; +- return; +- } +- +- *type_id = path[0]; +- +- if (request) { +- xstrncpy(request, path + 1, MAX_URL); +- /* convert %xx to char */ +- rfc1738_unescape(request); +- } +-} +- +-/** +- \ingroup ServerProtocolGopherAPI +- * Parse the request to determine whether it is cachable. +- * +- \param req Request data. +- \retval 0 Not cachable. +- \retval 1 Cachable. +- */ +-int +-gopherCachable(const HttpRequest * req) +-{ +- int cachable = 1; +- char type_id; +- /* parse to see type */ +- gopher_request_parse(req, +- &type_id, +- NULL); +- +- switch (type_id) { +- +- case GOPHER_INDEX: +- +- case GOPHER_CSO: +- +- case GOPHER_TELNET: +- +- case GOPHER_3270: +- cachable = 0; +- break; +- +- default: +- cachable = 1; +- } +- +- return cachable; +-} +- +-/// \ingroup ServerProtocolGopherInternal +-static void +-gopherHTMLHeader(StoreEntry * e, const char *title, const char *substring) +-{ +- storeAppendPrintf(e, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"); +- storeAppendPrintf(e, "<HTML><HEAD><TITLE>"); +- storeAppendPrintf(e, title, substring); +- storeAppendPrintf(e, "</TITLE>"); +- storeAppendPrintf(e, "<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}--></STYLE>\n"); +- storeAppendPrintf(e, "</HEAD>\n<BODY><H1>"); +- storeAppendPrintf(e, title, substring); +- storeAppendPrintf(e, "</H1>\n"); +-} +- +-/// \ingroup ServerProtocolGopherInternal +-static void +-gopherHTMLFooter(StoreEntry * e) +-{ +- storeAppendPrintf(e, "<HR noshade size=\"1px\">\n"); +- storeAppendPrintf(e, "<ADDRESS>\n"); +- storeAppendPrintf(e, "Generated %s by %s (%s)\n", +- mkrfc1123(squid_curtime), +- getMyHostname(), +- visible_appname_string); +- storeAppendPrintf(e, "</ADDRESS></BODY></HTML>\n"); +-} +- +-/// \ingroup ServerProtocolGopherInternal +-static void +-gopherEndHTML(GopherStateData * gopherState) +-{ +- StoreEntry *e = gopherState->entry; +- +- if (!gopherState->HTML_header_added) { +- gopherHTMLHeader(e, "Server Return Nothing", NULL); +- storeAppendPrintf(e, "<P>The Gopher query resulted in a blank response</P>"); +- } else if (gopherState->HTML_pre) { +- storeAppendPrintf(e, "</PRE>\n"); +- } +- +- gopherHTMLFooter(e); +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * Convert Gopher to HTML. +- \par +- * Borrow part of code from libwww2 came with Mosaic distribution. +- */ +-static void +-gopherToHTML(GopherStateData * gopherState, char *inbuf, int len) +-{ +- char *pos = inbuf; +- char *lpos = NULL; +- char *tline = NULL; +- LOCAL_ARRAY(char, line, TEMP_BUF_SIZE); +- char *name = NULL; +- char *selector = NULL; +- char *host = NULL; +- char *port = NULL; +- char *escaped_selector = NULL; +- const char *icon_url = NULL; +- char gtype; +- StoreEntry *entry = NULL; +- +- memset(line, '\0', TEMP_BUF_SIZE); +- +- entry = gopherState->entry; +- +- if (gopherState->conversion == gopher_ds::HTML_INDEX_PAGE) { +- char *html_url = html_quote(entry->url()); +- gopherHTMLHeader(entry, "Gopher Index %s", html_url); +- storeAppendPrintf(entry, +- "<p>This is a searchable Gopher index. Use the search\n" +- "function of your browser to enter search terms.\n" +- "<ISINDEX>\n"); +- gopherHTMLFooter(entry); +- /* now let start sending stuff to client */ +- entry->flush(); +- gopherState->HTML_header_added = 1; +- +- return; +- } +- +- if (gopherState->conversion == gopher_ds::HTML_CSO_PAGE) { +- char *html_url = html_quote(entry->url()); +- gopherHTMLHeader(entry, "CSO Search of %s", html_url); +- storeAppendPrintf(entry, +- "<P>A CSO database usually contains a phonebook or\n" +- "directory. Use the search function of your browser to enter\n" +- "search terms.</P><ISINDEX>\n"); +- gopherHTMLFooter(entry); +- /* now let start sending stuff to client */ +- entry->flush(); +- gopherState->HTML_header_added = 1; +- +- return; +- } +- +- SBuf outbuf; +- +- if (!gopherState->HTML_header_added) { +- if (gopherState->conversion == gopher_ds::HTML_CSO_RESULT) +- gopherHTMLHeader(entry, "CSO Search Result", NULL); +- else +- gopherHTMLHeader(entry, "Gopher Menu", NULL); +- +- outbuf.append ("<PRE>"); +- +- gopherState->HTML_header_added = 1; +- +- gopherState->HTML_pre = 1; +- } +- +- while (pos < inbuf + len) { +- int llen; +- int left = len - (pos - inbuf); +- lpos = (char *)memchr(pos, '\n', left); +- if (lpos) { +- ++lpos; /* Next line is after \n */ +- llen = lpos - pos; +- } else { +- llen = left; +- } +- if (gopherState->len + llen >= TEMP_BUF_SIZE) { +- debugs(10, DBG_IMPORTANT, "GopherHTML: Buffer overflow. Lost some data on URL: " << entry->url() ); +- llen = TEMP_BUF_SIZE - gopherState->len - 1; +- } +- if (!lpos) { +- /* there is no complete line in inbuf */ +- /* copy it to temp buffer */ +- /* note: llen is adjusted above */ +- memcpy(gopherState->buf + gopherState->len, pos, llen); +- gopherState->len += llen; +- break; +- } +- if (gopherState->len != 0) { +- /* there is something left from last tx. */ +- memcpy(line, gopherState->buf, gopherState->len); +- memcpy(line + gopherState->len, pos, llen); +- llen += gopherState->len; +- gopherState->len = 0; +- } else { +- memcpy(line, pos, llen); +- } +- line[llen + 1] = '\0'; +- /* move input to next line */ +- pos = lpos; +- +- /* at this point. We should have one line in buffer to process */ +- +- if (*line == '.') { +- /* skip it */ +- memset(line, '\0', TEMP_BUF_SIZE); +- continue; +- } +- +- switch (gopherState->conversion) { +- +- case gopher_ds::HTML_INDEX_RESULT: +- +- case gopher_ds::HTML_DIR: { +- tline = line; +- gtype = *tline; +- ++tline; +- name = tline; +- selector = strchr(tline, TAB); +- +- if (selector) { +- *selector = '\0'; +- ++selector; +- host = strchr(selector, TAB); +- +- if (host) { +- *host = '\0'; +- ++host; +- port = strchr(host, TAB); +- +- if (port) { +- char *junk; +- port[0] = ':'; +- junk = strchr(host, TAB); +- +- if (junk) +- *junk++ = 0; /* Chop port */ +- else { +- junk = strchr(host, '\r'); +- +- if (junk) +- *junk++ = 0; /* Chop port */ +- else { +- junk = strchr(host, '\n'); +- +- if (junk) +- *junk++ = 0; /* Chop port */ +- } +- } +- +- if ((port[1] == '0') && (!port[2])) +- port[0] = 0; /* 0 means none */ +- } +- +- /* escape a selector here */ +- escaped_selector = xstrdup(rfc1738_escape_part(selector)); +- +- switch (gtype) { +- +- case GOPHER_DIRECTORY: +- icon_url = mimeGetIconURL("internal-menu"); +- break; +- +- case GOPHER_HTML: +- +- case GOPHER_FILE: +- icon_url = mimeGetIconURL("internal-text"); +- break; +- +- case GOPHER_INDEX: +- +- case GOPHER_CSO: +- icon_url = mimeGetIconURL("internal-index"); +- break; +- +- case GOPHER_IMAGE: +- +- case GOPHER_GIF: +- +- case GOPHER_PLUS_IMAGE: +- icon_url = mimeGetIconURL("internal-image"); +- break; +- +- case GOPHER_SOUND: +- +- case GOPHER_PLUS_SOUND: +- icon_url = mimeGetIconURL("internal-sound"); +- break; +- +- case GOPHER_PLUS_MOVIE: +- icon_url = mimeGetIconURL("internal-movie"); +- break; +- +- case GOPHER_TELNET: +- +- case GOPHER_3270: +- icon_url = mimeGetIconURL("internal-telnet"); +- break; +- +- case GOPHER_BIN: +- +- case GOPHER_MACBINHEX: +- +- case GOPHER_DOSBIN: +- +- case GOPHER_UUENCODED: +- icon_url = mimeGetIconURL("internal-binary"); +- break; +- +- case GOPHER_INFO: +- icon_url = NULL; +- break; +- +- default: +- icon_url = mimeGetIconURL("internal-unknown"); +- break; +- } +- +- if ((gtype == GOPHER_TELNET) || (gtype == GOPHER_3270)) { +- if (strlen(escaped_selector) != 0) +- outbuf.appendf("<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"telnet://%s@%s%s%s/\">%s</A>\n", +- icon_url, escaped_selector, rfc1738_escape_part(host), +- *port ? ":" : "", port, html_quote(name)); +- else +- outbuf.appendf("<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"telnet://%s%s%s/\">%s</A>\n", +- icon_url, rfc1738_escape_part(host), *port ? ":" : "", +- port, html_quote(name)); +- +- } else if (gtype == GOPHER_INFO) { +- outbuf.appendf("\t%s\n", html_quote(name)); +- } else { +- if (strncmp(selector, "GET /", 5) == 0) { +- /* WWW link */ +- outbuf.appendf("<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"http://%s/%s\">%s</A>\n", +- icon_url, host, rfc1738_escape_unescaped(selector + 5), html_quote(name)); +- } else if (gtype == GOPHER_WWW) { +- outbuf.appendf("<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"gopher://%s/%c%s\">%s</A>\n", +- icon_url, rfc1738_escape_unescaped(selector), html_quote(name)); +- } else { +- /* Standard link */ +- outbuf.appendf("<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"gopher://%s/%c%s\">%s</A>\n", +- icon_url, host, gtype, escaped_selector, html_quote(name)); +- } +- } +- +- safe_free(escaped_selector); +- } else { +- memset(line, '\0', TEMP_BUF_SIZE); +- continue; +- } +- } else { +- memset(line, '\0', TEMP_BUF_SIZE); +- continue; +- } +- +- break; +- } /* HTML_DIR, HTML_INDEX_RESULT */ +- +- case gopher_ds::HTML_CSO_RESULT: { +- if (line[0] == '-') { +- int code, recno; +- char *s_code, *s_recno, *result; +- +- s_code = strtok(line + 1, ":\n"); +- s_recno = strtok(NULL, ":\n"); +- result = strtok(NULL, "\n"); +- +- if (!result) +- break; +- +- code = atoi(s_code); +- +- recno = atoi(s_recno); +- +- if (code != 200) +- break; +- +- if (gopherState->cso_recno != recno) { +- outbuf.appendf("</PRE><HR noshade size=\"1px\"><H2>Record# %d<br><i>%s</i></H2>\n<PRE>", recno, html_quote(result)); +- gopherState->cso_recno = recno; +- } else { +- outbuf.appendf("%s\n", html_quote(result)); +- } +- +- break; +- } else { +- int code; +- char *s_code, *result; +- +- s_code = strtok(line, ":"); +- result = strtok(NULL, "\n"); +- +- if (!result) +- break; +- +- code = atoi(s_code); +- +- switch (code) { +- +- case 200: { +- /* OK */ +- /* Do nothing here */ +- break; +- } +- +- case 102: /* Number of matches */ +- +- case 501: /* No Match */ +- +- case 502: { /* Too Many Matches */ +- /* Print the message the server returns */ +- outbuf.appendf("</PRE><HR noshade size=\"1px\"><H2>%s</H2>\n<PRE>", html_quote(result)); +- break; +- } +- +- } +- } +- +- } /* HTML_CSO_RESULT */ +- +- default: +- break; /* do nothing */ +- +- } /* switch */ +- +- } /* while loop */ +- +- if (outbuf.length() > 0) { +- entry->append(outbuf.rawContent(), outbuf.length()); +- /* now let start sending stuff to client */ +- entry->flush(); +- } +- +- return; +-} +- +-/// \ingroup ServerProtocolGopherInternal +-static void +-gopherTimeout(const CommTimeoutCbParams &io) +-{ +- GopherStateData *gopherState = static_cast<GopherStateData *>(io.data); +- debugs(10, 4, HERE << io.conn << ": '" << gopherState->entry->url() << "'" ); +- +- gopherState->fwd->fail(new ErrorState(ERR_READ_TIMEOUT, Http::scGatewayTimeout, gopherState->fwd->request)); +- +- if (Comm::IsConnOpen(io.conn)) +- io.conn->close(); +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * This will be called when data is ready to be read from fd. +- * Read until error or connection closed. +- */ +-static void +-gopherReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm::Flag flag, int xerrno, void *data) +-{ +- GopherStateData *gopherState = (GopherStateData *)data; +- StoreEntry *entry = gopherState->entry; +- int clen; +- int bin; +- size_t read_sz = BUFSIZ; +-#if USE_DELAY_POOLS +- DelayId delayId = entry->mem_obj->mostBytesAllowed(); +-#endif +- +- /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */ +- +- if (flag == Comm::ERR_CLOSING) { +- return; +- } +- +- assert(buf == gopherState->replybuf); +- +- if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) { +- gopherState->serverConn->close(); +- return; +- } +- +-#if USE_DELAY_POOLS +- read_sz = delayId.bytesWanted(1, read_sz); +-#endif +- +- /* leave one space for \0 in gopherToHTML */ +- +- if (flag == Comm::OK && len > 0) { +-#if USE_DELAY_POOLS +- delayId.bytesIn(len); +-#endif +- +- kb_incr(&(statCounter.server.all.kbytes_in), len); +- kb_incr(&(statCounter.server.other.kbytes_in), len); +- } +- +- debugs(10, 5, HERE << conn << " read len=" << len); +- +- if (flag == Comm::OK && len > 0) { +- AsyncCall::Pointer nil; +- commSetConnTimeout(conn, Config.Timeout.read, nil); +- ++IOStats.Gopher.reads; +- +- for (clen = len - 1, bin = 0; clen; ++bin) +- clen >>= 1; +- +- ++IOStats.Gopher.read_hist[bin]; +- +- HttpRequest *req = gopherState->fwd->request; +- if (req->hier.bodyBytesRead < 0) +- req->hier.bodyBytesRead = 0; +- +- req->hier.bodyBytesRead += len; +- } +- +- if (flag != Comm::OK) { +- debugs(50, DBG_IMPORTANT, "gopherReadReply: error reading: " << xstrerror()); +- +- if (ignoreErrno(xerrno)) { +- AsyncCall::Pointer call = commCbCall(5,4, "gopherReadReply", +- CommIoCbPtrFun(gopherReadReply, gopherState)); +- comm_read(conn, buf, read_sz, call); +- } else { +- ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scInternalServerError, gopherState->fwd->request); +- err->xerrno = xerrno; +- gopherState->fwd->fail(err); +- gopherState->serverConn->close(); +- } +- } else if (len == 0 && entry->isEmpty()) { +- gopherState->fwd->fail(new ErrorState(ERR_ZERO_SIZE_OBJECT, Http::scServiceUnavailable, gopherState->fwd->request)); +- gopherState->serverConn->close(); +- } else if (len == 0) { +- /* Connection closed; retrieval done. */ +- /* flush the rest of data in temp buf if there is one. */ +- +- if (gopherState->conversion != gopher_ds::NORMAL) +- gopherEndHTML(gopherState); +- +- entry->timestampsSet(); +- entry->flush(); +- gopherState->fwd->complete(); +- gopherState->serverConn->close(); +- } else { +- if (gopherState->conversion != gopher_ds::NORMAL) { +- gopherToHTML(gopherState, buf, len); +- } else { +- entry->append(buf, len); +- } +- AsyncCall::Pointer call = commCbCall(5,4, "gopherReadReply", +- CommIoCbPtrFun(gopherReadReply, gopherState)); +- comm_read(conn, buf, read_sz, call); +- } +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * This will be called when request write is complete. Schedule read of reply. +- */ +-static void +-gopherSendComplete(const Comm::ConnectionPointer &conn, char *buf, size_t size, Comm::Flag errflag, int xerrno, void *data) +-{ +- GopherStateData *gopherState = (GopherStateData *) data; +- StoreEntry *entry = gopherState->entry; +- debugs(10, 5, HERE << conn << " size: " << size << " errflag: " << errflag); +- +- if (size > 0) { +- fd_bytes(conn->fd, size, FD_WRITE); +- kb_incr(&(statCounter.server.all.kbytes_out), size); +- kb_incr(&(statCounter.server.other.kbytes_out), size); +- } +- +- if (errflag) { +- ErrorState *err; +- err = new ErrorState(ERR_WRITE_ERROR, Http::scServiceUnavailable, gopherState->fwd->request); +- err->xerrno = xerrno; +- err->port = gopherState->fwd->request->port; +- err->url = xstrdup(entry->url()); +- gopherState->fwd->fail(err); +- gopherState->serverConn->close(); +- +- if (buf) +- memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */ +- +- return; +- } +- +- /* +- * OK. We successfully reach remote site. Start MIME typing +- * stuff. Do it anyway even though request is not HTML type. +- */ +- entry->buffer(); +- +- gopherMimeCreate(gopherState); +- +- switch (gopherState->type_id) { +- +- case GOPHER_DIRECTORY: +- /* we got to convert it first */ +- gopherState->conversion = gopher_ds::HTML_DIR; +- gopherState->HTML_header_added = 0; +- break; +- +- case GOPHER_INDEX: +- /* we got to convert it first */ +- gopherState->conversion = gopher_ds::HTML_INDEX_RESULT; +- gopherState->HTML_header_added = 0; +- break; +- +- case GOPHER_CSO: +- /* we got to convert it first */ +- gopherState->conversion = gopher_ds::HTML_CSO_RESULT; +- gopherState->cso_recno = 0; +- gopherState->HTML_header_added = 0; +- break; +- +- default: +- gopherState->conversion = gopher_ds::NORMAL; +- entry->flush(); +- } +- +- /* Schedule read reply. */ +- AsyncCall::Pointer call = commCbCall(5,5, "gopherReadReply", +- CommIoCbPtrFun(gopherReadReply, gopherState)); +- entry->delayAwareRead(conn, gopherState->replybuf, BUFSIZ, call); +- +- if (buf) +- memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */ +-} +- +-/** +- \ingroup ServerProtocolGopherInternal +- * This will be called when connect completes. Write request. +- */ +-static void +-gopherSendRequest(int fd, void *data) +-{ +- GopherStateData *gopherState = (GopherStateData *)data; +- char *buf = (char *)memAllocate(MEM_4K_BUF); +- +- if (gopherState->type_id == GOPHER_CSO) { +- const char *t = strchr(gopherState->request, '?'); +- +- if (t != NULL) +- ++t; /* skip the ? */ +- else +- t = ""; +- +- snprintf(buf, 4096, "query %s\r\nquit\r\n", t); +- } else if (gopherState->type_id == GOPHER_INDEX) { +- char *t = strchr(gopherState->request, '?'); +- +- if (t != NULL) +- *t = '\t'; +- +- snprintf(buf, 4096, "%s\r\n", gopherState->request); +- } else { +- snprintf(buf, 4096, "%s\r\n", gopherState->request); +- } +- +- debugs(10, 5, HERE << gopherState->serverConn); +- AsyncCall::Pointer call = commCbCall(5,5, "gopherSendComplete", +- CommIoCbPtrFun(gopherSendComplete, gopherState)); +- Comm::Write(gopherState->serverConn, buf, strlen(buf), call, NULL); +- +- gopherState->entry->makePublic(); +-} +- +-/// \ingroup ServerProtocolGopherInternal +-CBDATA_TYPE(GopherStateData); +- +-/// \ingroup ServerProtocolGopherAPI +-void +-gopherStart(FwdState * fwd) +-{ +- StoreEntry *entry = fwd->entry; +- GopherStateData *gopherState; +- CBDATA_INIT_TYPE(GopherStateData); +- gopherState = cbdataAlloc(GopherStateData); +- gopherState->buf = (char *)memAllocate(MEM_4K_BUF); +- +- entry->lock("gopherState"); +- gopherState->entry = entry; +- +- gopherState->fwd = fwd; +- +- debugs(10, 3, "gopherStart: " << entry->url() ); +- +- ++ statCounter.server.all.requests; +- +- ++ statCounter.server.other.requests; +- +- /* Parse url. */ +- gopher_request_parse(fwd->request, +- &gopherState->type_id, gopherState->request); +- +- comm_add_close_handler(fwd->serverConnection()->fd, gopherStateFree, gopherState); +- +- if (((gopherState->type_id == GOPHER_INDEX) || (gopherState->type_id == GOPHER_CSO)) +- && (strchr(gopherState->request, '?') == NULL)) { +- /* Index URL without query word */ +- /* We have to generate search page back to client. No need for connection */ +- gopherMimeCreate(gopherState); +- +- if (gopherState->type_id == GOPHER_INDEX) { +- gopherState->conversion = gopher_ds::HTML_INDEX_PAGE; +- } else { +- if (gopherState->type_id == GOPHER_CSO) { +- gopherState->conversion = gopher_ds::HTML_CSO_PAGE; +- } else { +- gopherState->conversion = gopher_ds::HTML_INDEX_PAGE; +- } +- } +- +- gopherToHTML(gopherState, (char *) NULL, 0); +- fwd->complete(); +- return; +- } +- +- gopherState->serverConn = fwd->serverConnection(); +- gopherSendRequest(fwd->serverConnection()->fd, gopherState); +- AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "gopherTimeout", +- CommTimeoutCbPtrFun(gopherTimeout, gopherState)); +- commSetConnTimeout(fwd->serverConnection(), Config.Timeout.read, timeoutCall); +-} +- +diff --git a/src/gopher.h b/src/gopher.h +deleted file mode 100644 +index b68e465..0000000 +--- a/src/gopher.h ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* +- * Copyright (C) 1996-2016 The Squid Software Foundation and contributors +- * +- * Squid software is distributed under GPLv2+ license and includes +- * contributions from numerous individuals and organizations. +- * Please see the COPYING and CONTRIBUTORS files for details. +- */ +- +-/* DEBUG: section 10 Gopher */ +- +-#ifndef SQUID_GOPHER_H_ +-#define SQUID_GOPHER_H_ +- +-class FwdState; +-class HttpRequest; +- +-/** +- \defgroup ServerProtocolGopherAPI Server-Side Gopher API +- \ingroup ServerProtocol +- */ +- +-/// \ingroup ServerProtocolGopherAPI +-void gopherStart(FwdState *); +- +-/// \ingroup ServerProtocolGopherAPI +-int gopherCachable(const HttpRequest *); +- +-#endif /* SQUID_GOPHER_H_ */ +- +diff --git a/src/mgr/IoAction.cc b/src/mgr/IoAction.cc +index bf32fe2..a8008da 100644 +--- a/src/mgr/IoAction.cc ++++ b/src/mgr/IoAction.cc +@@ -35,9 +35,6 @@ Mgr::IoActionData::operator += (const IoActionData& stats) + ftp_reads += stats.ftp_reads; + for (int i = 0; i < IoStats::histSize; ++i) + ftp_read_hist[i] += stats.ftp_read_hist[i]; +- gopher_reads += stats.gopher_reads; +- for (int i = 0; i < IoStats::histSize; ++i) +- gopher_read_hist[i] += stats.gopher_read_hist[i]; + + return *this; + } +diff --git a/src/mgr/IoAction.h b/src/mgr/IoAction.h +index 8a5a9f9..ff0c7d5 100644 +--- a/src/mgr/IoAction.h ++++ b/src/mgr/IoAction.h +@@ -27,10 +27,8 @@ public: + public: + double http_reads; + double ftp_reads; +- double gopher_reads; + double http_read_hist[IoStats::histSize]; + double ftp_read_hist[IoStats::histSize]; +- double gopher_read_hist[IoStats::histSize]; + }; + + /// implement aggregated 'io' action +diff --git a/src/squid.8.in b/src/squid.8.in +index a3c101f..0f0ffa3 100644 +--- a/src/squid.8.in ++++ b/src/squid.8.in +@@ -24,7 +24,7 @@ command\-line + .PP + .B squid + is a high\-performance proxy caching server for web clients, +-supporting FTP, gopher, ICAP, ICP, HTCP and HTTP data objects. ++supporting FTP, ICAP, ICP, HTCP and HTTP data objects. + Unlike traditional caching software, + Squid handles all requests in a single, non-blocking process. + .PP +diff --git a/src/stat.cc b/src/stat.cc +index ae3dd69..309de52 100644 +--- a/src/stat.cc ++++ b/src/stat.cc +@@ -209,12 +209,6 @@ GetIoStats(Mgr::IoActionData& stats) + for (i = 0; i < IoStats::histSize; ++i) { + stats.ftp_read_hist[i] = IOStats.Ftp.read_hist[i]; + } +- +- stats.gopher_reads = IOStats.Gopher.reads; +- +- for (i = 0; i < IoStats::histSize; ++i) { +- stats.gopher_read_hist[i] = IOStats.Gopher.read_hist[i]; +- } + } + + void +@@ -247,19 +241,6 @@ DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry) + Math::doublePercent(stats.ftp_read_hist[i], stats.ftp_reads)); + } + +- storeAppendPrintf(sentry, "\n"); +- storeAppendPrintf(sentry, "Gopher I/O\n"); +- storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.gopher_reads); +- storeAppendPrintf(sentry, "Read Histogram:\n"); +- +- for (i = 0; i < IoStats::histSize; ++i) { +- storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n", +- i ? (1 << (i - 1)) + 1 : 1, +- 1 << i, +- stats.gopher_read_hist[i], +- Math::doublePercent(stats.gopher_read_hist[i], stats.gopher_reads)); +- } +- + storeAppendPrintf(sentry, "\n"); + } + +diff --git a/src/url.cc b/src/url.cc +index 44255c2..1e14d05 100644 +--- a/src/url.cc ++++ b/src/url.cc +@@ -108,9 +108,6 @@ urlParseProtocol(const char *b, const char *e) + if (strncasecmp(b, "coaps", len) == 0) + return AnyP::PROTO_COAPS; + +- if (strncasecmp(b, "gopher", len) == 0) +- return AnyP::PROTO_GOPHER; +- + if (strncasecmp(b, "wais", len) == 0) + return AnyP::PROTO_WAIS; + +@@ -146,9 +143,6 @@ urlDefaultPort(AnyP::ProtocolType p) + // Assuming IANA policy of allocating same port for base and TLS protocol versions will occur. + return 5683; + +- case AnyP::PROTO_GOPHER: +- return 70; +- + case AnyP::PROTO_WAIS: + return 210; + +@@ -809,8 +803,6 @@ urlCheckRequest(const HttpRequest * r) + if (r->method == Http::METHOD_PUT) + rc = 1; + +- case AnyP::PROTO_GOPHER: +- + case AnyP::PROTO_WAIS: + + case AnyP::PROTO_WHOIS: +diff --git a/test-suite/squidconf/regressions-3.4.0.1 b/test-suite/squidconf/regressions-3.4.0.1 +index 35a3fe1..c0ad827 100644 +--- a/test-suite/squidconf/regressions-3.4.0.1 ++++ b/test-suite/squidconf/regressions-3.4.0.1 +@@ -44,6 +44,5 @@ refresh_pattern -i \.(gif|png|jpg|jpeg|ico)$ 40320 75% 86400 + refresh_pattern -i \.(iso|avi|wav|mp3|mpeg|swf|flv|x-flv)$ 1440 40% 40320 + + refresh_pattern ^ftp: 1440 20% 10080 +-refresh_pattern ^gopher: 1440 0% 1440 + refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 + refresh_pattern . 0 20% 4320 +-- +2.43.0 + diff --git a/SOURCES/squid-3.5.20-CVE-2023-49285.patch b/SOURCES/squid-3.5.20-CVE-2023-49285.patch new file mode 100644 index 0000000..f6351e4 --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2023-49285.patch @@ -0,0 +1,30 @@ +commit 77b3fb4df0f126784d5fd4967c28ed40eb8d521b +Author: Alex Rousskov <rousskov@measurement-factory.com> +Date: Wed Oct 25 19:41:45 2023 +0000 + + RFC 1123: Fix date parsing (#1538) + + The bug was discovered and detailed by Joshua Rogers at + https://megamansec.github.io/Squid-Security-Audit/datetime-overflow.html + where it was filed as "1-Byte Buffer OverRead in RFC 1123 date/time + Handling". + +diff --git a/lib/rfc1123.c b/lib/rfc1123.c +index e5bf9a4d7..cb484cc00 100644 +--- a/lib/rfc1123.c ++++ b/lib/rfc1123.c +@@ -50,7 +50,13 @@ make_month(const char *s) + char month[3]; + + month[0] = xtoupper(*s); ++ if (!month[0]) ++ return -1; // protects *(s + 1) below ++ + month[1] = xtolower(*(s + 1)); ++ if (!month[1]) ++ return -1; // protects *(s + 2) below ++ + month[2] = xtolower(*(s + 2)); + + for (i = 0; i < 12; i++) + diff --git a/SOURCES/squid-3.5.20-CVE-2023-49286.patch b/SOURCES/squid-3.5.20-CVE-2023-49286.patch new file mode 100644 index 0000000..1d7a19e --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2023-49286.patch @@ -0,0 +1,76 @@ +diff --git a/src/Debug.h b/src/Debug.h +index 6819d57..ccf2864 100644 +--- a/src/Debug.h ++++ b/src/Debug.h +@@ -92,6 +92,9 @@ public: + /// logs output buffer created in Start() and closes debugging context + static void Finish(); + ++ /// prefixes each grouped debugs() line after the first one in the group ++ static std::ostream& Extra(std::ostream &os) { return os << "\n "; } ++ + private: + static Context *Current; ///< deepest active context; nil outside debugs() + }; +diff --git a/src/ipc.cc b/src/ipc.cc +index df638b0..9793949 100644 +--- a/src/ipc.cc ++++ b/src/ipc.cc +@@ -19,6 +19,11 @@ + #include "SquidConfig.h" + #include "SquidIpc.h" + #include "tools.h" ++#include <cstdlib> ++ ++#if HAVE_UNISTD_H ++#include <unistd.h> ++#endif + + static const char *hello_string = "hi there\n"; + #define HELLO_BUF_SZ 32 +@@ -333,6 +338,22 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name + } + + PutEnvironment(); ++ ++ // A dup(2) wrapper that reports and exits the process on errors. The ++ // exiting logic is only suitable for this child process context. ++ const auto dupOrExit = [prog,name](const int oldFd) { ++ const auto newFd = dup(oldFd); ++ if (newFd < 0) { ++ const auto savedErrno = errno; ++ debugs(54, DBG_CRITICAL, "ERROR: Helper process initialization failure: " << name << ++ Debug::Extra << "helper (CHILD) PID: " << getpid() << ++ Debug::Extra << "helper program name: " << prog << ++ Debug::Extra << "dup(2) system call error for FD " << oldFd << ": " << xstrerr(savedErrno)); ++ _exit(EXIT_FAILURE); ++ } ++ return newFd; ++ }; ++ + /* + * This double-dup stuff avoids problems when one of + * crfd, cwfd, or debug_log are in the rage 0-2. +@@ -340,17 +361,16 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name + + do { + /* First make sure 0-2 is occupied by something. Gets cleaned up later */ +- x = dup(crfd); +- assert(x > -1); +- } while (x < 3 && x > -1); ++ x = dupOrExit(crfd); ++ } while (x < 3); + + close(x); + +- t1 = dup(crfd); ++ t1 = dupOrExit(crfd); + +- t2 = dup(cwfd); ++ t2 = dupOrExit(cwfd); + +- t3 = dup(fileno(debug_log)); ++ t3 = dupOrExit(fileno(debug_log)); + + assert(t1 > 2 && t2 > 2 && t3 > 2); + diff --git a/SOURCES/squid-3.5.20-CVE-2023-50269.patch b/SOURCES/squid-3.5.20-CVE-2023-50269.patch new file mode 100644 index 0000000..181e0d7 --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2023-50269.patch @@ -0,0 +1,80 @@ +From 9f7136105bff920413042a8806cc5de3f6086d6d Mon Sep 17 00:00:00 2001 +From: Thomas Leroy <32497783+p4zuu@users.noreply.github.com> +Date: Tue, 28 Nov 2023 07:35:46 +0000 +Subject: [PATCH] Limit the number of allowed X-Forwarded-For hops (#1589) + +Squid will ignore all X-Forwarded-For elements listed after the first 64 +addresses allowed by the follow_x_forwarded_for directive. A different +limit can be specified by defining a C++ SQUID_X_FORWARDED_FOR_HOP_MAX +macro, but that macro is not a supported Squid configuration interface +and may change or disappear at any time. + +Squid will log a cache.log ERROR if the hop limit has been reached. + +This change works around problematic ACLChecklist and/or slow ACLs +implementation that results in immediate nonBlockingCheck() callbacks. +Such callbacks have caused many bugs and development complications. In +clientFollowXForwardedForCheck() context, they lead to indirect +recursion that was bound only by the number of allowed XFF entries, +which could reach thousands and exhaust Squid process call stack. + +This recursion bug was discovered and detailed by Joshua Rogers at +https://megamansec.github.io/Squid-Security-Audit/xff-stackoverflow.html +where it was filed as "X-Forwarded-For Stack Overflow". +--- + src/ClientRequestContext.h | 4 ++++ + src/client_side_request.cc | 17 +++++++++++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/src/ClientRequestContext.h b/src/ClientRequestContext.h +index 7dde9bc..775e308 100644 +--- a/src/ClientRequestContext.h ++++ b/src/ClientRequestContext.h +@@ -90,6 +90,10 @@ public: + ErrorState *error; ///< saved error page for centralized/delayed processing + bool readNextRequest; ///< whether Squid should read after error handling + ++#if FOLLOW_X_FORWARDED_FOR ++ size_t currentXffHopNumber = 0; ///< number of X-Forwarded-For header values processed so far ++#endif ++ + private: + CBDATA_CLASS2(ClientRequestContext); + }; +diff --git a/src/client_side_request.cc b/src/client_side_request.cc +index 57d8975..9b77271 100644 +--- a/src/client_side_request.cc ++++ b/src/client_side_request.cc +@@ -362,6 +362,11 @@ clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * stre + request->client_addr.setNoAddr(); + + #if FOLLOW_X_FORWARDED_FOR ++ ++#if !defined(SQUID_X_FORWARDED_FOR_HOP_MAX) ++#define SQUID_X_FORWARDED_FOR_HOP_MAX 64 ++#endif ++ + request->indirect_client_addr.setNoAddr(); + #endif /* FOLLOW_X_FORWARDED_FOR */ + +@@ -475,8 +480,15 @@ clientFollowXForwardedForCheck(allow_t answer, void *data) + /* override the default src_addr tested if we have to go deeper than one level into XFF */ + Filled(calloutContext->acl_checklist)->src_addr = request->indirect_client_addr; + } +- calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); +- return; ++ if (++calloutContext->currentXffHopNumber < SQUID_X_FORWARDED_FOR_HOP_MAX) { ++ calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); ++ return; ++ } ++ debugs(28, DBG_CRITICAL, "ERROR: Ignoring trailing X-Forwarded-For addresses" << ++ Debug::Extra << "addresses allowed by follow_x_forwarded_for: " << calloutContext->currentXffHopNumber << ++ Debug::Extra << "last/accepted address: " << request->indirect_client_addr << ++ Debug::Extra << "ignored trailing addresses: " << request->x_forwarded_for_iterator); ++ // fall through to resume clientAccessCheck() processing + } + } /*if (answer == ACCESS_ALLOWED && + request->x_forwarded_for_iterator.size () != 0)*/ +-- +2.43.0 + diff --git a/SOURCES/squid-3.5.20-CVE-2024-25617.patch b/SOURCES/squid-3.5.20-CVE-2024-25617.patch new file mode 100644 index 0000000..01ba885 --- /dev/null +++ b/SOURCES/squid-3.5.20-CVE-2024-25617.patch @@ -0,0 +1,134 @@ +From 653a5fe81e0e98f33c4830cd59ee60ed3be43d93 Mon Sep 17 00:00:00 2001 +From: Stepan Broz <sbroz@redhat.com> +Date: Fri, 8 Mar 2024 19:04:34 +0100 +Subject: [PATCH] Improve handling of expanding HTTP header values + +Backport of upstream commit 72a3bbd5e431597c3fdb56d752bc56b010ba3817 +(upstream PR #1536) to squid-3.5.20. +--- + src/SquidString.h | 16 +++++++++++++++- + src/cache_cf.cc | 12 ++++++++++++ + src/cf.data.pre | 26 ++++++++++++++++---------- + src/http.cc | 5 +++-- + 4 files changed, 46 insertions(+), 13 deletions(-) + +diff --git a/src/SquidString.h b/src/SquidString.h +index c452308..0068e46 100644 +--- a/src/SquidString.h ++++ b/src/SquidString.h +@@ -42,6 +42,11 @@ public: + */ + _SQUID_INLINE_ char operator [](unsigned int pos) const; + ++ /// The absolute size limit on data held in a String. ++ /// Since Strings can be nil-terminated implicitly it is best to ensure ++ /// the useful content length is strictly less than this limit. ++ static size_type SizeMaxXXX() { return SizeMax_; } ++ + _SQUID_INLINE_ size_type size() const; + /// variant of size() suited to be used for printf-alikes. + /// throws when size() > MAXINT +@@ -106,7 +111,16 @@ private: + + size_type len_; /* current length */ + +- static const size_type SizeMax_ = 65535; ///< 64K limit protects some fixed-size buffers ++ /// An earlier 64KB limit was meant to protect some fixed-size buffers, but ++ /// (a) we do not know where those buffers are (or whether they still exist) ++ /// (b) too many String users unknowingly exceeded that limit and asserted. ++ /// We are now using a larger limit to reduce the number of (b) cases, ++ /// especially cases where "compact" lists of items grow 50% in size when we ++ /// convert them to canonical form. The new limit is selected to withstand ++ /// concatenation and ~50% expansion of two HTTP headers limited by default ++ /// request_header_max_size and reply_header_max_size settings. ++ static const size_type SizeMax_ = 3*64*1024 - 1; ++ + /// returns true after increasing the first argument by extra if the sum does not exceed SizeMax_ + static bool SafeAdd(size_type &base, size_type extra) { if (extra <= SizeMax_ && base <= SizeMax_ - extra) { base += extra; return true; } return false; } + +diff --git a/src/cache_cf.cc b/src/cache_cf.cc +index e6b231c..435aaf9 100644 +--- a/src/cache_cf.cc ++++ b/src/cache_cf.cc +@@ -921,6 +921,18 @@ configDoConfigure(void) + (uint32_t)Config.maxRequestBufferSize, (uint32_t)Config.maxRequestHeaderSize); + } + ++ // Warn about the dangers of exceeding String limits when manipulating HTTP ++ // headers. Technically, we do not concatenate _requests_, so we could relax ++ // their check, but we keep the two checks the same for simplicity sake. ++ const auto safeRawHeaderValueSizeMax = (String::SizeMaxXXX()+1)/3; ++ // TODO: static_assert(safeRawHeaderValueSizeMax >= 64*1024); // no WARNINGs for default settings ++ if (Config.maxRequestHeaderSize > safeRawHeaderValueSizeMax) ++ debugs(3, DBG_CRITICAL, "WARNING: Increasing request_header_max_size beyond " << safeRawHeaderValueSizeMax << ++ " bytes makes Squid more vulnerable to denial-of-service attacks; configured value: " << Config.maxRequestHeaderSize << " bytes"); ++ if (Config.maxReplyHeaderSize > safeRawHeaderValueSizeMax) ++ debugs(3, DBG_CRITICAL, "WARNING: Increasing reply_header_max_size beyond " << safeRawHeaderValueSizeMax << ++ " bytes makes Squid more vulnerable to denial-of-service attacks; configured value: " << Config.maxReplyHeaderSize << " bytes"); ++ + /* + * Disable client side request pipelining if client_persistent_connections OFF. + * Waste of resources queueing any pipelined requests when the first will close the connection. +diff --git a/src/cf.data.pre b/src/cf.data.pre +index 5bdef86..c9301ee 100644 +--- a/src/cf.data.pre ++++ b/src/cf.data.pre +@@ -5683,11 +5683,14 @@ TYPE: b_size_t + DEFAULT: 64 KB + LOC: Config.maxRequestHeaderSize + DOC_START +- This specifies the maximum size for HTTP headers in a request. +- Request headers are usually relatively small (about 512 bytes). +- Placing a limit on the request header size will catch certain +- bugs (for example with persistent connections) and possibly +- buffer-overflow or denial-of-service attacks. ++ This directives limits the header size of a received HTTP request ++ (including request-line). Increasing this limit beyond its 64 KB default ++ exposes certain old Squid code to various denial-of-service attacks. This ++ limit also applies to received FTP commands. ++ ++ This limit has no direct affect on Squid memory consumption. ++ ++ Squid does not check this limit when sending requests. + DOC_END + + NAME: reply_header_max_size +@@ -5696,11 +5699,14 @@ TYPE: b_size_t + DEFAULT: 64 KB + LOC: Config.maxReplyHeaderSize + DOC_START +- This specifies the maximum size for HTTP headers in a reply. +- Reply headers are usually relatively small (about 512 bytes). +- Placing a limit on the reply header size will catch certain +- bugs (for example with persistent connections) and possibly +- buffer-overflow or denial-of-service attacks. ++ This directives limits the header size of a received HTTP response ++ (including status-line). Increasing this limit beyond its 64 KB default ++ exposes certain old Squid code to various denial-of-service attacks. This ++ limit also applies to FTP command responses. ++ ++ Squid also checks this limit when loading hit responses from disk cache. ++ ++ Squid does not check this limit when sending responses. + DOC_END + + NAME: request_body_max_size +diff --git a/src/http.cc b/src/http.cc +index f0fe648..bff14b1 100644 +--- a/src/http.cc ++++ b/src/http.cc +@@ -1775,8 +1775,9 @@ HttpStateData::httpBuildRequestHeader(HttpRequest * request, + + String strFwd = hdr_in->getList(HDR_X_FORWARDED_FOR); + +- // if we cannot double strFwd size, then it grew past 50% of the limit +- if (!strFwd.canGrowBy(strFwd.size())) { ++ // Detect unreasonably long header values. And paranoidly check String ++ // limits: a String ought to accommodate two reasonable-length values. ++ if (strFwd.size() > 32*1024 || !strFwd.canGrowBy(strFwd.size())) { + // There is probably a forwarding loop with Via detection disabled. + // If we do nothing, String will assert on overflow soon. + // TODO: Terminate all transactions with huge XFF? +-- +2.44.0 + diff --git a/SPECS/squid.spec b/SPECS/squid.spec index ef5ea47..ba9b9f7 100644 --- a/SPECS/squid.spec +++ b/SPECS/squid.spec @@ -4,7 +4,7 @@ Name: squid Version: 3.5.20 -Release: 17%{?dist}.9 +Release: 17%{?dist}.10 Summary: The Squid proxy caching server Epoch: 7 # See CREDITS for breakdown of non GPLv2+ code @@ -94,6 +94,18 @@ Patch513: squid-3.5.20-CVE-2021-46784.patch Patch514: squid-3.5.20-CVE-2022-41318.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2245916 Patch515: squid-3.5.20-CVE-2023-46847.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2248521 +Patch516: squid-3.5.20-CVE-2023-46728.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2252926 +Patch517: squid-3.5.20-CVE-2023-49285.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2252923 +Patch518: squid-3.5.20-CVE-2023-49286.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2247567 +Patch519: squid-3.5.20-CVE-2023-46724.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2254663 +Patch520: squid-3.5.20-CVE-2023-50269.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2264309 +Patch521: squid-3.5.20-CVE-2024-25617.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: bash >= 2.0 @@ -129,7 +141,7 @@ BuildRequires: gcc-c++ %description Squid is a high-performance proxy caching server for Web clients, -supporting FTP, gopher, and HTTP data objects. Unlike traditional +supporting FTP, and HTTP data objects. Unlike traditional caching software, Squid handles all requests in a single, non-blocking, I/O-driven process. Squid keeps meta data and especially hot objects cached in RAM, caches DNS lookups, supports non-blocking @@ -197,6 +209,12 @@ migration and script which prepares squid for downgrade operation. %patch513 -p1 -b .CVE-2021-46784 %patch514 -p1 -b .CVE-2022-41318 %patch515 -p1 -b .CVE-2023-46847 +%patch516 -p1 -b .CVE-2023-46728 +%patch517 -p1 -b .CVE-2023-49285 +%patch518 -p1 -b .CVE-2023-49286 +%patch519 -p1 -b .CVE-2023-46724 +%patch520 -p1 -b .CVE-2023-50269 +%patch521 -p1 -b .CVE-2024-25617 # https://bugzilla.redhat.com/show_bug.cgi?id=1471140 # Patch in the vendor documentation and used different location for documentation @@ -426,6 +444,20 @@ fi chgrp squid /var/cache/samba/winbindd_privileged >/dev/null 2>&1 || : %changelog +* Tue Feb 06 2024 Stepan Broz <sbroz@redhat.com> - 7:3.5.20-17.10 +- Resolves: RHEL-16779 - squid: NULL pointer dereference in the gopher protocol + code -- Remove support for Gopher protocol (CVE-2023-46728) +- Resolves: RHEL-18176 - squid: Buffer over-read in the HTTP Message processing + feature (CVE-2023-49285) +- Resolves: RHEL-18171 - squid: Incorrect Check of Function Return Value In + Helper Process management (CVE-2023-49286) +- Resolves: RHEL-16758 - squid: Denial of Service in SSL Certificate validation + (CVE-2023-46724) +- Resolves: RHEL-19557 - squid: denial of service in HTTP request parsing + (CVE-2023-50269) +- Resolves: RHEL-26082 - squid: denial of service in HTTP header parser + (CVE-2024-25617) + * Wed Nov 01 2023 Stepan Broz <sbroz@redhat.com> - 7:3.5.20-17.9 - Resolves: RHEL-14789 - squid: Denial of Service in HTTP Digest Authentication (CVE-2023-46847)