import squid-4.4-8.module+el8.2.0+6449+6ba3df3e.1
This commit is contained in:
commit
b4990d7207
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
SOURCES/squid-4.4.tar.xz
|
1
.squid.metadata
Normal file
1
.squid.metadata
Normal file
@ -0,0 +1 @@
|
|||||||
|
0ab6b133f65866d825bf72cbbe8cef209768b2fa SOURCES/squid-4.4.tar.xz
|
16
SOURCES/cache_swap.sh
Normal file
16
SOURCES/cache_swap.sh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
if [ -f /etc/sysconfig/squid ]; then
|
||||||
|
. /etc/sysconfig/squid
|
||||||
|
fi
|
||||||
|
|
||||||
|
SQUID_CONF=${SQUID_CONF:-"/etc/squid/squid.conf"}
|
||||||
|
|
||||||
|
CACHE_SWAP=`sed -e 's/#.*//g' $SQUID_CONF | \
|
||||||
|
grep cache_dir | awk '{ print $3 }'`
|
||||||
|
|
||||||
|
for adir in $CACHE_SWAP; do
|
||||||
|
if [ ! -d $adir/00 ]; then
|
||||||
|
echo -n "init_cache_dir $adir... "
|
||||||
|
squid -N -z -F -f $SQUID_CONF >> /var/log/squid/squid.out 2>&1
|
||||||
|
fi
|
||||||
|
done
|
3
SOURCES/perl-requires-squid.sh
Executable file
3
SOURCES/perl-requires-squid.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
/usr/lib/rpm/perl.req $* | grep -v "Authen::Smb"
|
10
SOURCES/squid-3.0.STABLE1-perlpath.patch
Normal file
10
SOURCES/squid-3.0.STABLE1-perlpath.patch
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
diff --git a/contrib/url-normalizer.pl b/contrib/url-normalizer.pl
|
||||||
|
index 90ac6a4..8dbed90 100755
|
||||||
|
--- a/contrib/url-normalizer.pl
|
||||||
|
+++ b/contrib/url-normalizer.pl
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-#!/usr/local/bin/perl -Tw
|
||||||
|
+#!/usr/bin/perl -Tw
|
||||||
|
#
|
||||||
|
# * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
|
||||||
|
# *
|
32
SOURCES/squid-3.1.0.9-location.patch
Normal file
32
SOURCES/squid-3.1.0.9-location.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
diff -up squid-3.1.0.9/QUICKSTART.location squid-3.1.0.9/QUICKSTART
|
||||||
|
--- squid-3.1.0.9/QUICKSTART.location 2009-06-26 12:35:27.000000000 +0200
|
||||||
|
+++ squid-3.1.0.9/QUICKSTART 2009-07-17 14:03:10.000000000 +0200
|
||||||
|
@@ -10,10 +10,9 @@ After you retrieved, compiled and instal
|
||||||
|
INSTALL in the same directory), you have to configure the squid.conf
|
||||||
|
file. This is the list of the values you *need* to change, because no
|
||||||
|
sensible defaults could be defined. Do not touch the other variables
|
||||||
|
-for now. We assume you have installed Squid in the default location:
|
||||||
|
-/usr/local/squid
|
||||||
|
+for now.
|
||||||
|
|
||||||
|
-Uncomment and edit the following lines in /usr/local/squid/etc/squid.conf:
|
||||||
|
+Uncomment and edit the following lines in /etc/squid/squid.conf:
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
@@ -82,12 +81,12 @@ After editing squid.conf to your liking,
|
||||||
|
line TWICE:
|
||||||
|
|
||||||
|
To create any disk cache_dir configured:
|
||||||
|
- % /usr/local/squid/sbin/squid -z
|
||||||
|
+ % /usr/sbin/squid -z
|
||||||
|
|
||||||
|
To start squid:
|
||||||
|
- % /usr/local/squid/sbin/squid
|
||||||
|
+ % /usr/sbin/squid
|
||||||
|
|
||||||
|
-Check in the cache.log (/usr/local/squid/var/logs/cache.log) that
|
||||||
|
+Check in the cache.log (/var/log/squid/cache.log) that
|
||||||
|
everything is all right.
|
||||||
|
|
||||||
|
Once Squid created all its files (it can take several minutes on some
|
95
SOURCES/squid-3.5.9-include-guards.patch
Normal file
95
SOURCES/squid-3.5.9-include-guards.patch
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
------------------------------------------------------------
|
||||||
|
revno: 14311
|
||||||
|
revision-id: squid3@treenet.co.nz-20150924130537-lqwzd1z99a3l9gt4
|
||||||
|
parent: squid3@treenet.co.nz-20150924032241-6cx3g6hwz9xfoybr
|
||||||
|
------------------------------------------------------------
|
||||||
|
revno: 14311
|
||||||
|
revision-id: squid3@treenet.co.nz-20150924130537-lqwzd1z99a3l9gt4
|
||||||
|
parent: squid3@treenet.co.nz-20150924032241-6cx3g6hwz9xfoybr
|
||||||
|
fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4323
|
||||||
|
author: Francesco Chemolli <kinkie@squid-cache.org>
|
||||||
|
committer: Amos Jeffries <squid3@treenet.co.nz>
|
||||||
|
branch nick: trunk
|
||||||
|
timestamp: Thu 2015-09-24 06:05:37 -0700
|
||||||
|
message:
|
||||||
|
Bug 4323: Netfilter broken cross-includes with Linux 4.2
|
||||||
|
------------------------------------------------------------
|
||||||
|
# Bazaar merge directive format 2 (Bazaar 0.90)
|
||||||
|
# revision_id: squid3@treenet.co.nz-20150924130537-lqwzd1z99a3l9gt4
|
||||||
|
# target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/
|
||||||
|
# testament_sha1: c67cfca81040f3845d7c4caf2f40518511f14d0b
|
||||||
|
# timestamp: 2015-09-24 13:06:33 +0000
|
||||||
|
# source_branch: http://bzr.squid-cache.org/bzr/squid3/trunk
|
||||||
|
# base_revision_id: squid3@treenet.co.nz-20150924032241-\
|
||||||
|
# 6cx3g6hwz9xfoybr
|
||||||
|
#
|
||||||
|
# Begin patch
|
||||||
|
=== modified file 'compat/os/linux.h'
|
||||||
|
--- compat/os/linux.h 2015-01-13 07:25:36 +0000
|
||||||
|
+++ compat/os/linux.h 2015-09-24 13:05:37 +0000
|
||||||
|
@@ -30,6 +30,21 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Netfilter header madness. (see Bug 4323)
|
||||||
|
+ *
|
||||||
|
+ * Netfilter have a history of defining their own versions of network protocol
|
||||||
|
+ * primitives without sufficient protection against the POSIX defines which are
|
||||||
|
+ * aways present in Linux.
|
||||||
|
+ *
|
||||||
|
+ * netinet/in.h must be included before any other sys header in order to properly
|
||||||
|
+ * activate include guards in <linux/libc-compat.h> the kernel maintainers added
|
||||||
|
+ * to workaround it.
|
||||||
|
+ */
|
||||||
|
+#if HAVE_NETINET_IN_H
|
||||||
|
+#include <netinet/in.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* sys/capability.h is only needed in Linux apparently.
|
||||||
|
*
|
||||||
|
* HACK: LIBCAP_BROKEN Ugly glue to get around linux header madness colliding with glibc
|
||||||
|
fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4323
|
||||||
|
author: Francesco Chemolli <kinkie@squid-cache.org>
|
||||||
|
committer: Amos Jeffries <squid3@treenet.co.nz>
|
||||||
|
branch nick: trunk
|
||||||
|
timestamp: Thu 2015-09-24 06:05:37 -0700
|
||||||
|
message:
|
||||||
|
Bug 4323: Netfilter broken cross-includes with Linux 4.2
|
||||||
|
------------------------------------------------------------
|
||||||
|
# Bazaar merge directive format 2 (Bazaar 0.90)
|
||||||
|
# revision_id: squid3@treenet.co.nz-20150924130537-lqwzd1z99a3l9gt4
|
||||||
|
# target_branch: http://bzr.squid-cache.org/bzr/squid3/trunk/
|
||||||
|
# testament_sha1: c67cfca81040f3845d7c4caf2f40518511f14d0b
|
||||||
|
# timestamp: 2015-09-24 13:06:33 +0000
|
||||||
|
# source_branch: http://bzr.squid-cache.org/bzr/squid3/trunk
|
||||||
|
# base_revision_id: squid3@treenet.co.nz-20150924032241-\
|
||||||
|
# 6cx3g6hwz9xfoybr
|
||||||
|
#
|
||||||
|
# Begin patch
|
||||||
|
=== modified file 'compat/os/linux.h'
|
||||||
|
--- compat/os/linux.h 2015-01-13 07:25:36 +0000
|
||||||
|
+++ compat/os/linux.h 2015-09-24 13:05:37 +0000
|
||||||
|
@@ -30,6 +30,21 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
+ * Netfilter header madness. (see Bug 4323)
|
||||||
|
+ *
|
||||||
|
+ * Netfilter have a history of defining their own versions of network protocol
|
||||||
|
+ * primitives without sufficient protection against the POSIX defines which are
|
||||||
|
+ * aways present in Linux.
|
||||||
|
+ *
|
||||||
|
+ * netinet/in.h must be included before any other sys header in order to properly
|
||||||
|
+ * activate include guards in <linux/libc-compat.h> the kernel maintainers added
|
||||||
|
+ * to workaround it.
|
||||||
|
+ */
|
||||||
|
+#if HAVE_NETINET_IN_H
|
||||||
|
+#include <netinet/in.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
* sys/capability.h is only needed in Linux apparently.
|
||||||
|
*
|
||||||
|
* HACK: LIBCAP_BROKEN Ugly glue to get around linux header madness colliding with glibc
|
||||||
|
|
26
SOURCES/squid-4.0.11-config.patch
Normal file
26
SOURCES/squid-4.0.11-config.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
diff -up squid-4.0.11/src/cf.data.pre.config squid-4.0.11/src/cf.data.pre
|
||||||
|
--- squid-4.0.11/src/cf.data.pre.config 2016-06-09 22:32:57.000000000 +0200
|
||||||
|
+++ squid-4.0.11/src/cf.data.pre 2016-07-11 21:08:35.090976840 +0200
|
||||||
|
@@ -4658,7 +4658,7 @@ DOC_END
|
||||||
|
|
||||||
|
NAME: logfile_rotate
|
||||||
|
TYPE: int
|
||||||
|
-DEFAULT: 10
|
||||||
|
+DEFAULT: 0
|
||||||
|
LOC: Config.Log.rotateNumber
|
||||||
|
DOC_START
|
||||||
|
Specifies the default number of logfile rotations to make when you
|
||||||
|
@@ -6444,11 +6444,11 @@ COMMENT_END
|
||||||
|
|
||||||
|
NAME: cache_mgr
|
||||||
|
TYPE: string
|
||||||
|
-DEFAULT: webmaster
|
||||||
|
+DEFAULT: root
|
||||||
|
LOC: Config.adminEmail
|
||||||
|
DOC_START
|
||||||
|
Email-address of local cache manager who will receive
|
||||||
|
- mail if the cache dies. The default is "webmaster".
|
||||||
|
+ mail if the cache dies. The default is "root".
|
||||||
|
DOC_END
|
||||||
|
|
||||||
|
NAME: mail_from
|
178
SOURCES/squid-4.0.21-large-acl.patch
Normal file
178
SOURCES/squid-4.0.21-large-acl.patch
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
diff --git a/src/acl/RegexData.cc b/src/acl/RegexData.cc
|
||||||
|
index 01a4c12..b5c1679 100644
|
||||||
|
--- a/src/acl/RegexData.cc
|
||||||
|
+++ b/src/acl/RegexData.cc
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include "ConfigParser.h"
|
||||||
|
#include "Debug.h"
|
||||||
|
#include "sbuf/List.h"
|
||||||
|
+#include "sbuf/Algorithms.h"
|
||||||
|
|
||||||
|
ACLRegexData::~ACLRegexData()
|
||||||
|
{
|
||||||
|
@@ -129,6 +130,18 @@ compileRE(std::list<RegexPattern> &curlist, const char * RE, int flags)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static bool
|
||||||
|
+compileRE(std::list<RegexPattern> &curlist, const SBufList &RE, int flags)
|
||||||
|
+{
|
||||||
|
+ if (RE.empty())
|
||||||
|
+ return curlist.empty(); // XXX: old code did this. It looks wrong.
|
||||||
|
+ SBuf regexp;
|
||||||
|
+ static const SBuf openparen("("), closeparen(")"), separator(")|(");
|
||||||
|
+ JoinContainerIntoSBuf(regexp, RE.begin(), RE.end(), separator, openparen,
|
||||||
|
+ closeparen);
|
||||||
|
+ return compileRE(curlist, regexp.c_str(), flags);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/** Compose and compile one large RE from a set of (small) REs.
|
||||||
|
* The ultimate goal is to have only one RE per ACL so that match() is
|
||||||
|
* called only once per ACL.
|
||||||
|
@@ -137,16 +150,11 @@ static int
|
||||||
|
compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
||||||
|
{
|
||||||
|
std::list<RegexPattern> newlist;
|
||||||
|
- int numREs = 0;
|
||||||
|
+ SBufList accumulatedRE;
|
||||||
|
+ int numREs = 0, reSize = 0;
|
||||||
|
int flags = REG_EXTENDED | REG_NOSUB;
|
||||||
|
- int largeREindex = 0;
|
||||||
|
- char largeRE[BUFSIZ];
|
||||||
|
- *largeRE = 0;
|
||||||
|
|
||||||
|
for (const SBuf & configurationLineWord : sl) {
|
||||||
|
- int RElen;
|
||||||
|
- RElen = configurationLineWord.length();
|
||||||
|
-
|
||||||
|
static const SBuf minus_i("-i");
|
||||||
|
static const SBuf plus_i("+i");
|
||||||
|
if (configurationLineWord == minus_i) {
|
||||||
|
@@ -155,10 +163,11 @@ compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
||||||
|
debugs(28, 2, "optimisation of -i ... -i" );
|
||||||
|
} else {
|
||||||
|
debugs(28, 2, "-i" );
|
||||||
|
- if (!compileRE(newlist, largeRE, flags))
|
||||||
|
+ if (!compileRE(newlist, accumulatedRE, flags))
|
||||||
|
return 0;
|
||||||
|
flags |= REG_ICASE;
|
||||||
|
- largeRE[largeREindex=0] = '\0';
|
||||||
|
+ accumulatedRE.clear();
|
||||||
|
+ reSize = 0;
|
||||||
|
}
|
||||||
|
} else if (configurationLineWord == plus_i) {
|
||||||
|
if ((flags & REG_ICASE) == 0) {
|
||||||
|
@@ -166,37 +175,34 @@ compileOptimisedREs(std::list<RegexPattern> &curlist, const SBufList &sl)
|
||||||
|
debugs(28, 2, "optimisation of +i ... +i");
|
||||||
|
} else {
|
||||||
|
debugs(28, 2, "+i");
|
||||||
|
- if (!compileRE(newlist, largeRE, flags))
|
||||||
|
+ if (!compileRE(newlist, accumulatedRE, flags))
|
||||||
|
return 0;
|
||||||
|
flags &= ~REG_ICASE;
|
||||||
|
- largeRE[largeREindex=0] = '\0';
|
||||||
|
+ accumulatedRE.clear();
|
||||||
|
+ reSize = 0;
|
||||||
|
}
|
||||||
|
- } else if (RElen + largeREindex + 3 < BUFSIZ-1) {
|
||||||
|
+ } else if (reSize < 1024) {
|
||||||
|
debugs(28, 2, "adding RE '" << configurationLineWord << "'");
|
||||||
|
- if (largeREindex > 0) {
|
||||||
|
- largeRE[largeREindex] = '|';
|
||||||
|
- ++largeREindex;
|
||||||
|
- }
|
||||||
|
- largeRE[largeREindex] = '(';
|
||||||
|
- ++largeREindex;
|
||||||
|
- configurationLineWord.copy(largeRE+largeREindex, BUFSIZ-largeREindex);
|
||||||
|
- largeREindex += configurationLineWord.length();
|
||||||
|
- largeRE[largeREindex] = ')';
|
||||||
|
- ++largeREindex;
|
||||||
|
- largeRE[largeREindex] = '\0';
|
||||||
|
+ accumulatedRE.push_back(configurationLineWord);
|
||||||
|
++numREs;
|
||||||
|
+ reSize += configurationLineWord.length();
|
||||||
|
} else {
|
||||||
|
debugs(28, 2, "buffer full, generating new optimised RE..." );
|
||||||
|
- if (!compileRE(newlist, largeRE, flags))
|
||||||
|
+ accumulatedRE.push_back(configurationLineWord);
|
||||||
|
+ if (!compileRE(newlist, accumulatedRE, flags))
|
||||||
|
return 0;
|
||||||
|
- largeRE[largeREindex=0] = '\0';
|
||||||
|
+ accumulatedRE.clear();
|
||||||
|
+ reSize = 0;
|
||||||
|
continue; /* do the loop again to add the RE to largeRE */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!compileRE(newlist, largeRE, flags))
|
||||||
|
+ if (!compileRE(newlist, accumulatedRE, flags))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ accumulatedRE.clear();
|
||||||
|
+ reSize = 0;
|
||||||
|
+
|
||||||
|
/* all was successful, so put the new list at the tail */
|
||||||
|
curlist.splice(curlist.end(), newlist);
|
||||||
|
|
||||||
|
diff --git a/src/sbuf/Algorithms.h b/src/sbuf/Algorithms.h
|
||||||
|
index 21ee889..338e9c0 100644
|
||||||
|
--- a/src/sbuf/Algorithms.h
|
||||||
|
+++ b/src/sbuf/Algorithms.h
|
||||||
|
@@ -81,6 +81,57 @@ SBufContainerJoin(const Container &items, const SBuf& separator)
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/** Join container of SBufs and append to supplied target
|
||||||
|
+ *
|
||||||
|
+ * append to the target SBuf all elements in the [begin,end) range from
|
||||||
|
+ * an iterable container, prefixed by prefix, separated by separator and
|
||||||
|
+ * followed by suffix. Prefix and suffix are added also in case of empty
|
||||||
|
+ * iterable
|
||||||
|
+ *
|
||||||
|
+ * \return the modified dest
|
||||||
|
+ */
|
||||||
|
+template <class ContainerIterator>
|
||||||
|
+SBuf&
|
||||||
|
+JoinContainerIntoSBuf(SBuf &dest, const ContainerIterator &begin,
|
||||||
|
+ const ContainerIterator &end, const SBuf& separator,
|
||||||
|
+ const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf())
|
||||||
|
+{
|
||||||
|
+ if (begin == end) {
|
||||||
|
+ dest.append(prefix).append(suffix);
|
||||||
|
+ return dest;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // optimization: pre-calculate needed storage
|
||||||
|
+ const SBuf::size_type totalContainerSize =
|
||||||
|
+ std::accumulate(begin, end, 0, SBufAddLength(separator)) +
|
||||||
|
+ dest.length() + prefix.length() + suffix.length();
|
||||||
|
+ SBufReservationRequirements req;
|
||||||
|
+ req.minSpace = totalContainerSize;
|
||||||
|
+ dest.reserve(req);
|
||||||
|
+
|
||||||
|
+ auto i = begin;
|
||||||
|
+ dest.append(prefix);
|
||||||
|
+ dest.append(*i);
|
||||||
|
+ ++i;
|
||||||
|
+ for (; i != end; ++i)
|
||||||
|
+ dest.append(separator).append(*i);
|
||||||
|
+ dest.append(suffix);
|
||||||
|
+ return dest;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/// convenience wrapper of JoinContainerIntoSBuf with no caller-supplied SBuf
|
||||||
|
+template <class ContainerIterator>
|
||||||
|
+SBuf
|
||||||
|
+JoinContainerToSBuf(const ContainerIterator &begin,
|
||||||
|
+ const ContainerIterator &end, const SBuf& separator,
|
||||||
|
+ const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf())
|
||||||
|
+{
|
||||||
|
+ SBuf rv;
|
||||||
|
+ return JoinContainerIntoSBuf(rv, begin, end, separator, prefix, suffix);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
namespace std {
|
||||||
|
/// default hash functor to support std::unordered_map<SBuf,*>
|
||||||
|
template <>
|
296
SOURCES/squid-4.4.0-CVE-2019-12519.patch
Normal file
296
SOURCES/squid-4.4.0-CVE-2019-12519.patch
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
commit fdd4123629320aa1ee4c3481bb392437c90d188d
|
||||||
|
Author: Amos Jeffries <yadij@users.noreply.github.com>
|
||||||
|
Date: 2019-05-20 11:23:13 +0000
|
||||||
|
|
||||||
|
ESI: convert parse exceptions into 500 status response (#411)
|
||||||
|
|
||||||
|
Produce a valid HTTP 500 status reply and continue operations when
|
||||||
|
ESI parser throws an exception. This will prevent incomplete ESI
|
||||||
|
responses reaching clients on server errors. Such responses might
|
||||||
|
have been cacheable and thus corrupted, albeit corrupted consistently
|
||||||
|
and at source by the reverse-proxy delivering them.
|
||||||
|
|
||||||
|
ESI: throw on large stack recursions (#408)
|
||||||
|
|
||||||
|
This reduces the impact on concurrent clients to only those
|
||||||
|
accessing the malformed resource.
|
||||||
|
|
||||||
|
Depending on what type of recursion is being performed the
|
||||||
|
resource may appear to the client with missing segments, or
|
||||||
|
not at all.
|
||||||
|
|
||||||
|
diff --git a/src/esi/Context.h b/src/esi/Context.h
|
||||||
|
index f3281a1..1b08cfb 100644
|
||||||
|
--- a/src/esi/Context.h
|
||||||
|
+++ b/src/esi/Context.h
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#include "clientStream.h"
|
||||||
|
#include "err_type.h"
|
||||||
|
#include "esi/Element.h"
|
||||||
|
+#include "esi/Esi.h"
|
||||||
|
#include "esi/Parser.h"
|
||||||
|
#include "http/forward.h"
|
||||||
|
#include "http/StatusCode.h"
|
||||||
|
@@ -113,7 +114,7 @@ public:
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
- ESIElement::Pointer stack[10]; /* a stack of esi elements that are open */
|
||||||
|
+ ESIElement::Pointer stack[ESI_STACK_DEPTH_LIMIT]; /* a stack of esi elements that are open */
|
||||||
|
int stackdepth; /* self explanatory */
|
||||||
|
ESIParser::Pointer theParser;
|
||||||
|
ESIElement::Pointer top();
|
||||||
|
diff --git a/src/esi/Esi.cc b/src/esi/Esi.cc
|
||||||
|
index cc662c4..e41d593 100644
|
||||||
|
--- a/src/esi/Esi.cc
|
||||||
|
+++ b/src/esi/Esi.cc
|
||||||
|
@@ -29,6 +29,7 @@
|
||||||
|
#include "esi/Expression.h"
|
||||||
|
#include "esi/Segment.h"
|
||||||
|
#include "esi/VarState.h"
|
||||||
|
+#include "FadingCounter.h"
|
||||||
|
#include "fatal.h"
|
||||||
|
#include "http/Stream.h"
|
||||||
|
#include "HttpHdrSc.h"
|
||||||
|
@@ -930,13 +931,18 @@ void
|
||||||
|
ESIContext::addStackElement (ESIElement::Pointer element)
|
||||||
|
{
|
||||||
|
/* Put on the stack to allow skipping of 'invalid' markup */
|
||||||
|
- assert (parserState.stackdepth <11);
|
||||||
|
+
|
||||||
|
+ // throw an error if the stack location would be invalid
|
||||||
|
+ if (parserState.stackdepth >= ESI_STACK_DEPTH_LIMIT)
|
||||||
|
+ throw Esi::Error("ESI Too many nested elements");
|
||||||
|
+ if (parserState.stackdepth < 0)
|
||||||
|
+ throw Esi::Error("ESI elements stack error, probable error in ESI template");
|
||||||
|
+
|
||||||
|
assert (!failed());
|
||||||
|
debugs(86, 5, "ESIContext::addStackElement: About to add ESI Node " << element.getRaw());
|
||||||
|
|
||||||
|
if (!parserState.top()->addElement(element)) {
|
||||||
|
- debugs(86, DBG_IMPORTANT, "ESIContext::addStackElement: failed to add esi node, probable error in ESI template");
|
||||||
|
- flags.error = 1;
|
||||||
|
+ throw Esi::Error("ESIContext::addStackElement failed, probable error in ESI template");
|
||||||
|
} else {
|
||||||
|
/* added ok, push onto the stack */
|
||||||
|
parserState.stack[parserState.stackdepth] = element;
|
||||||
|
@@ -1188,13 +1194,10 @@ ESIContext::addLiteral (const char *s, int len)
|
||||||
|
assert (len);
|
||||||
|
debugs(86, 5, "literal length is " << len);
|
||||||
|
/* give a literal to the current element */
|
||||||
|
- assert (parserState.stackdepth <11);
|
||||||
|
ESIElement::Pointer element (new esiLiteral (this, s, len));
|
||||||
|
|
||||||
|
- if (!parserState.top()->addElement(element)) {
|
||||||
|
- debugs(86, DBG_IMPORTANT, "ESIContext::addLiteral: failed to add esi node, probable error in ESI template");
|
||||||
|
- flags.error = 1;
|
||||||
|
- }
|
||||||
|
+ if (!parserState.top()->addElement(element))
|
||||||
|
+ throw Esi::Error("ESIContext::addLiteral failed, probable error in ESI template");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1256,8 +1259,24 @@ ESIContext::parse()
|
||||||
|
|
||||||
|
PROF_start(esiParsing);
|
||||||
|
|
||||||
|
- while (buffered.getRaw() && !flags.error)
|
||||||
|
- parseOneBuffer();
|
||||||
|
+ try {
|
||||||
|
+ while (buffered.getRaw() && !flags.error)
|
||||||
|
+ parseOneBuffer();
|
||||||
|
+
|
||||||
|
+ } catch (Esi::ErrorDetail &errMsg) { // FIXME: non-const for c_str()
|
||||||
|
+ // level-2: these are protocol/syntax errors from upstream
|
||||||
|
+ debugs(86, 2, "WARNING: ESI syntax error: " << errMsg);
|
||||||
|
+ setError();
|
||||||
|
+ setErrorMessage(errMsg.c_str());
|
||||||
|
+
|
||||||
|
+ } catch (...) {
|
||||||
|
+ // DBG_IMPORTANT because these are local issues the admin needs to fix
|
||||||
|
+ static FadingCounter logEntries; // TODO: set horizon less than infinity
|
||||||
|
+ if (logEntries.count(1) < 100)
|
||||||
|
+ debugs(86, DBG_IMPORTANT, "ERROR: ESI parser: " << CurrentException);
|
||||||
|
+ setError();
|
||||||
|
+ setErrorMessage("ESI parser error");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
PROF_stop(esiParsing);
|
||||||
|
|
||||||
|
diff --git a/src/esi/Esi.h b/src/esi/Esi.h
|
||||||
|
index 180b2c4..6fd5aac 100644
|
||||||
|
--- a/src/esi/Esi.h
|
||||||
|
+++ b/src/esi/Esi.h
|
||||||
|
@@ -10,6 +10,11 @@
|
||||||
|
#define SQUID_ESI_H
|
||||||
|
|
||||||
|
#include "clientStream.h"
|
||||||
|
+#include "sbuf/SBuf.h"
|
||||||
|
+
|
||||||
|
+#if !defined(ESI_STACK_DEPTH_LIMIT)
|
||||||
|
+#define ESI_STACK_DEPTH_LIMIT 20
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* ESI.c */
|
||||||
|
extern CSR esiStreamRead;
|
||||||
|
@@ -18,5 +23,14 @@ extern CSD esiStreamDetach;
|
||||||
|
extern CSS esiStreamStatus;
|
||||||
|
int esiEnableProcessing (HttpReply *);
|
||||||
|
|
||||||
|
+namespace Esi
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+typedef SBuf ErrorDetail;
|
||||||
|
+/// prepare an Esi::ErrorDetail for throw on ESI parser internal errors
|
||||||
|
+inline Esi::ErrorDetail Error(const char *msg) { return ErrorDetail(msg); }
|
||||||
|
+
|
||||||
|
+} // namespace Esi
|
||||||
|
+
|
||||||
|
#endif /* SQUID_ESI_H */
|
||||||
|
|
||||||
|
diff --git a/src/esi/Expression.cc b/src/esi/Expression.cc
|
||||||
|
index 2b5b762..8519b03 100644
|
||||||
|
--- a/src/esi/Expression.cc
|
||||||
|
+++ b/src/esi/Expression.cc
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
|
||||||
|
#include "squid.h"
|
||||||
|
#include "Debug.h"
|
||||||
|
+#include "esi/Esi.h"
|
||||||
|
#include "esi/Expression.h"
|
||||||
|
#include "profiler/Profiler.h"
|
||||||
|
|
||||||
|
@@ -97,6 +98,17 @@ stackpop(stackmember * s, int *depth)
|
||||||
|
cleanmember(&s[*depth]);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+stackpush(stackmember *stack, stackmember &item, int *depth)
|
||||||
|
+{
|
||||||
|
+ if (*depth < 0)
|
||||||
|
+ throw Esi::Error("ESIExpression stack has negative size");
|
||||||
|
+ if (*depth >= ESI_STACK_DEPTH_LIMIT)
|
||||||
|
+ throw Esi::Error("ESIExpression stack is full, cannot push");
|
||||||
|
+
|
||||||
|
+ stack[(*depth)++] = item;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static evaluate evalnegate;
|
||||||
|
static evaluate evalliteral;
|
||||||
|
static evaluate evalor;
|
||||||
|
@@ -208,6 +220,11 @@ evalnegate(stackmember * stack, int *depth, int whereAmI, stackmember * candidat
|
||||||
|
/* invalid stack */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
+ if (whereAmI < 0)
|
||||||
|
+ throw Esi::Error("negate expression location too small");
|
||||||
|
+ if (*depth >= ESI_STACK_DEPTH_LIMIT)
|
||||||
|
+ throw Esi::Error("negate expression too complex");
|
||||||
|
+
|
||||||
|
if (stack[whereAmI + 1].valuetype != ESI_EXPR_EXPR)
|
||||||
|
/* invalid operand */
|
||||||
|
return 1;
|
||||||
|
@@ -280,7 +297,7 @@ evalor(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -327,7 +344,7 @@ evaland(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -373,7 +390,7 @@ evallesseq(stackmember * stack, int *depth, int whereAmI, stackmember * candidat
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -421,7 +438,7 @@ evallessthan(stackmember * stack, int *depth, int whereAmI, stackmember * candid
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -469,7 +486,7 @@ evalmoreeq(stackmember * stack, int *depth, int whereAmI, stackmember * candidat
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -517,7 +534,7 @@ evalmorethan(stackmember * stack, int *depth, int whereAmI, stackmember * candid
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -566,7 +583,7 @@ evalequals(stackmember * stack, int *depth, int whereAmI,
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -613,7 +630,7 @@ evalnotequals(stackmember * stack, int *depth, int whereAmI, stackmember * candi
|
||||||
|
|
||||||
|
srv.precedence = 1;
|
||||||
|
|
||||||
|
- stack[(*depth)++] = srv;
|
||||||
|
+ stackpush(stack, srv, depth);
|
||||||
|
|
||||||
|
/* we're out of way, try adding now */
|
||||||
|
if (!addmember(stack, depth, candidate))
|
||||||
|
@@ -953,6 +970,9 @@ addmember(stackmember * stack, int *stackdepth, stackmember * candidate)
|
||||||
|
/* !(!(a==b))) is why thats safe */
|
||||||
|
/* strictly less than until we unwind */
|
||||||
|
|
||||||
|
+ if (*stackdepth >= ESI_STACK_DEPTH_LIMIT)
|
||||||
|
+ throw Esi::Error("ESI expression too complex to add member");
|
||||||
|
+
|
||||||
|
if (candidate->precedence < stack[*stackdepth - 1].precedence ||
|
||||||
|
candidate->precedence < stack[*stackdepth - 2].precedence) {
|
||||||
|
/* must be an operator */
|
||||||
|
@@ -968,10 +988,10 @@ addmember(stackmember * stack, int *stackdepth, stackmember * candidate)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- stack[(*stackdepth)++] = *candidate;
|
||||||
|
+ stackpush(stack, *candidate, stackdepth);
|
||||||
|
}
|
||||||
|
} else if (candidate->valuetype != ESI_EXPR_INVALID)
|
||||||
|
- stack[(*stackdepth)++] = *candidate;
|
||||||
|
+ stackpush(stack, *candidate, stackdepth);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -979,7 +999,7 @@ addmember(stackmember * stack, int *stackdepth, stackmember * candidate)
|
||||||
|
int
|
||||||
|
ESIExpression::Evaluate(char const *s)
|
||||||
|
{
|
||||||
|
- stackmember stack[20];
|
||||||
|
+ stackmember stack[ESI_STACK_DEPTH_LIMIT];
|
||||||
|
int stackdepth = 0;
|
||||||
|
char const *end;
|
||||||
|
PROF_start(esiExpressionEval);
|
30
SOURCES/squid-4.4.0-CVE-2019-12525.patch
Normal file
30
SOURCES/squid-4.4.0-CVE-2019-12525.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
commit 409956536647b3a05ee1e367424a24ae6b8f13fd
|
||||||
|
Author: Amos Jeffries <yadij@users.noreply.github.com>
|
||||||
|
Date: 2019-06-08 21:09:23 +0000
|
||||||
|
|
||||||
|
Fix Digest auth parameter parsing (#415)
|
||||||
|
|
||||||
|
Only remove quoting if the domain=, uri= or qop= parameter
|
||||||
|
value is surrounded by double-quotes.
|
||||||
|
|
||||||
|
diff --git a/src/auth/digest/Config.cc b/src/auth/digest/Config.cc
|
||||||
|
index a8a07cd..b547bf8 100644
|
||||||
|
--- a/src/auth/digest/Config.cc
|
||||||
|
+++ b/src/auth/digest/Config.cc
|
||||||
|
@@ -787,14 +787,14 @@ Auth::Digest::Config::decode(char const *proxy_auth, const char *aRequestRealm)
|
||||||
|
if (keyName == SBuf("domain",6) || keyName == SBuf("uri",3)) {
|
||||||
|
// domain is Special. Not a quoted-string, must not be de-quoted. But is wrapped in '"'
|
||||||
|
// BUG 3077: uri= can also be sent to us in a mangled (invalid!) form like domain
|
||||||
|
- if (*p == '"' && *(p + vlen -1) == '"') {
|
||||||
|
+ if (vlen > 1 && *p == '"' && *(p + vlen -1) == '"') {
|
||||||
|
value.limitInit(p+1, vlen-2);
|
||||||
|
}
|
||||||
|
} else if (keyName == SBuf("qop",3)) {
|
||||||
|
// qop is more special.
|
||||||
|
// On request this must not be quoted-string de-quoted. But is several values wrapped in '"'
|
||||||
|
// On response this is a single un-quoted token.
|
||||||
|
- if (*p == '"' && *(p + vlen -1) == '"') {
|
||||||
|
+ if (vlen > 1 && *p == '"' && *(p + vlen -1) == '"') {
|
||||||
|
value.limitInit(p+1, vlen-2);
|
||||||
|
} else {
|
||||||
|
value.limitInit(p, vlen);
|
139
SOURCES/squid-4.4.0-CVE-2019-12527.patch
Normal file
139
SOURCES/squid-4.4.0-CVE-2019-12527.patch
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
commit 7f73e9c5d17664b882ed32590e6af310c247f320
|
||||||
|
Author: Amos Jeffries <yadij@users.noreply.github.com>
|
||||||
|
Date: 2019-06-19 05:58:36 +0000
|
||||||
|
|
||||||
|
Update HttpHeader::getAuth to SBuf (#416)
|
||||||
|
|
||||||
|
Replace the fixed-size buffer for decoding base64 tokens with an
|
||||||
|
SBuf to avoid decoder issues on large inputs.
|
||||||
|
|
||||||
|
Update callers to SBuf API operations for more efficient memory
|
||||||
|
management.
|
||||||
|
|
||||||
|
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
|
||||||
|
index 1e2b650..284a057 100644
|
||||||
|
--- a/src/HttpHeader.cc
|
||||||
|
+++ b/src/HttpHeader.cc
|
||||||
|
@@ -1268,43 +1268,46 @@ HttpHeader::getContRange() const
|
||||||
|
return cr;
|
||||||
|
}
|
||||||
|
|
||||||
|
-const char *
|
||||||
|
-HttpHeader::getAuth(Http::HdrType id, const char *auth_scheme) const
|
||||||
|
+SBuf
|
||||||
|
+HttpHeader::getAuthToken(Http::HdrType id, const char *auth_scheme) const
|
||||||
|
{
|
||||||
|
const char *field;
|
||||||
|
int l;
|
||||||
|
assert(auth_scheme);
|
||||||
|
field = getStr(id);
|
||||||
|
|
||||||
|
+ static const SBuf nil;
|
||||||
|
if (!field) /* no authorization field */
|
||||||
|
- return NULL;
|
||||||
|
+ return nil;
|
||||||
|
|
||||||
|
l = strlen(auth_scheme);
|
||||||
|
|
||||||
|
if (!l || strncasecmp(field, auth_scheme, l)) /* wrong scheme */
|
||||||
|
- return NULL;
|
||||||
|
+ return nil;
|
||||||
|
|
||||||
|
field += l;
|
||||||
|
|
||||||
|
if (!xisspace(*field)) /* wrong scheme */
|
||||||
|
- return NULL;
|
||||||
|
+ return nil;
|
||||||
|
|
||||||
|
/* skip white space */
|
||||||
|
for (; field && xisspace(*field); ++field);
|
||||||
|
|
||||||
|
if (!*field) /* no authorization cookie */
|
||||||
|
- return NULL;
|
||||||
|
+ return nil;
|
||||||
|
|
||||||
|
- static char decodedAuthToken[8192];
|
||||||
|
+ const auto fieldLen = strlen(field);
|
||||||
|
+ SBuf result;
|
||||||
|
+ char *decodedAuthToken = result.rawAppendStart(BASE64_DECODE_LENGTH(fieldLen));
|
||||||
|
struct base64_decode_ctx ctx;
|
||||||
|
base64_decode_init(&ctx);
|
||||||
|
size_t decodedLen = 0;
|
||||||
|
- if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), strlen(field), field) ||
|
||||||
|
+ if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast<uint8_t*>(decodedAuthToken), fieldLen, field) ||
|
||||||
|
!base64_decode_final(&ctx)) {
|
||||||
|
- return NULL;
|
||||||
|
+ return nil;
|
||||||
|
}
|
||||||
|
- decodedAuthToken[decodedLen] = '\0';
|
||||||
|
- return decodedAuthToken;
|
||||||
|
+ result.rawAppendFinish(decodedAuthToken, decodedLen);
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ETag
|
||||||
|
diff --git a/src/HttpHeader.h b/src/HttpHeader.h
|
||||||
|
index a26b127..3b262be 100644
|
||||||
|
--- a/src/HttpHeader.h
|
||||||
|
+++ b/src/HttpHeader.h
|
||||||
|
@@ -134,7 +134,7 @@ public:
|
||||||
|
HttpHdrRange *getRange() const;
|
||||||
|
HttpHdrSc *getSc() const;
|
||||||
|
HttpHdrContRange *getContRange() const;
|
||||||
|
- const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
|
||||||
|
+ SBuf getAuthToken(Http::HdrType id, const char *auth_scheme) const;
|
||||||
|
ETag getETag(Http::HdrType id) const;
|
||||||
|
TimeOrTag getTimeOrTag(Http::HdrType id) const;
|
||||||
|
int hasListMember(Http::HdrType id, const char *member, const char separator) const;
|
||||||
|
diff --git a/src/cache_manager.cc b/src/cache_manager.cc
|
||||||
|
index da22f7a..2fae767 100644
|
||||||
|
--- a/src/cache_manager.cc
|
||||||
|
+++ b/src/cache_manager.cc
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "mgr/FunAction.h"
|
||||||
|
#include "mgr/QueryParams.h"
|
||||||
|
#include "protos.h"
|
||||||
|
+#include "sbuf/StringConvert.h"
|
||||||
|
#include "SquidConfig.h"
|
||||||
|
#include "SquidTime.h"
|
||||||
|
#include "Store.h"
|
||||||
|
@@ -243,20 +244,20 @@ CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams ¶m
|
||||||
|
// TODO: use the authentication system decode to retrieve these details properly.
|
||||||
|
|
||||||
|
/* base 64 _decoded_ user:passwd pair */
|
||||||
|
- const char *basic_cookie = request->header.getAuth(Http::HdrType::AUTHORIZATION, "Basic");
|
||||||
|
+ const auto basic_cookie(request->header.getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
|
||||||
|
|
||||||
|
- if (!basic_cookie)
|
||||||
|
+ if (basic_cookie.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
- const char *passwd_del;
|
||||||
|
- if (!(passwd_del = strchr(basic_cookie, ':'))) {
|
||||||
|
+ const auto colonPos = basic_cookie.find(':');
|
||||||
|
+ if (colonPos == SBuf::npos) {
|
||||||
|
debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* found user:password pair, reset old values */
|
||||||
|
- params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
|
||||||
|
- params.password = passwd_del + 1;
|
||||||
|
+ params.userName = SBufToString(basic_cookie.substr(0, colonPos));
|
||||||
|
+ params.password = SBufToString(basic_cookie.substr(colonPos+1));
|
||||||
|
|
||||||
|
/* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */
|
||||||
|
debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
|
||||||
|
diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc
|
||||||
|
index b958b14..7ca5d24 100644
|
||||||
|
--- a/src/clients/FtpGateway.cc
|
||||||
|
+++ b/src/clients/FtpGateway.cc
|
||||||
|
@@ -1050,7 +1050,7 @@ Ftp::Gateway::checkAuth(const HttpHeader * req_hdr)
|
||||||
|
|
||||||
|
#if HAVE_AUTH_MODULE_BASIC
|
||||||
|
/* Check HTTP Authorization: headers (better than defaults, but less than URL) */
|
||||||
|
- const SBuf auth(req_hdr->getAuth(Http::HdrType::AUTHORIZATION, "Basic"));
|
||||||
|
+ const auto auth(req_hdr->getAuthToken(Http::HdrType::AUTHORIZATION, "Basic"));
|
||||||
|
if (!auth.isEmpty()) {
|
||||||
|
flags.authenticated = 1;
|
||||||
|
loginParser(auth, false);
|
64
SOURCES/squid-4.4.0-CVE-2019-13345.patch
Normal file
64
SOURCES/squid-4.4.0-CVE-2019-13345.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
diff --git a/tools/cachemgr.cc b/tools/cachemgr.cc
|
||||||
|
index 0c745c2..8a67eba 100644
|
||||||
|
--- a/tools/cachemgr.cc
|
||||||
|
+++ b/tools/cachemgr.cc
|
||||||
|
@@ -355,7 +355,7 @@ auth_html(const char *host, int port, const char *user_name)
|
||||||
|
|
||||||
|
printf("<TR><TH ALIGN=\"left\">Manager name:</TH><TD><INPUT NAME=\"user_name\" ");
|
||||||
|
|
||||||
|
- printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", user_name);
|
||||||
|
+ printf("size=\"30\" VALUE=\"%s\"></TD></TR>\n", rfc1738_escape(user_name));
|
||||||
|
|
||||||
|
printf("<TR><TH ALIGN=\"left\">Password:</TH><TD><INPUT TYPE=\"password\" NAME=\"passwd\" ");
|
||||||
|
|
||||||
|
@@ -419,7 +419,7 @@ menu_url(cachemgr_request * req, const char *action)
|
||||||
|
script_name,
|
||||||
|
req->hostname,
|
||||||
|
req->port,
|
||||||
|
- safe_str(req->user_name),
|
||||||
|
+ rfc1738_escape(safe_str(req->user_name)),
|
||||||
|
action,
|
||||||
|
safe_str(req->pub_auth));
|
||||||
|
return url;
|
||||||
|
@@ -1074,8 +1074,8 @@ make_pub_auth(cachemgr_request * req)
|
||||||
|
const int bufLen = snprintf(buf, sizeof(buf), "%s|%d|%s|%s",
|
||||||
|
req->hostname,
|
||||||
|
(int) now,
|
||||||
|
- req->user_name ? req->user_name : "",
|
||||||
|
- req->passwd);
|
||||||
|
+ rfc1738_escape(safe_str(req->user_name)),
|
||||||
|
+ rfc1738_escape(req->passwd));
|
||||||
|
debug("cmgr: pre-encoded for pub: %s\n", buf);
|
||||||
|
|
||||||
|
const int encodedLen = base64_encode_len(bufLen);
|
||||||
|
@@ -1094,8 +1094,6 @@ decode_pub_auth(cachemgr_request * req)
|
||||||
|
char *buf;
|
||||||
|
const char *host_name;
|
||||||
|
const char *time_str;
|
||||||
|
- const char *user_name;
|
||||||
|
- const char *passwd;
|
||||||
|
|
||||||
|
debug("cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth));
|
||||||
|
safe_free(req->passwd);
|
||||||
|
@@ -1131,17 +1129,21 @@ decode_pub_auth(cachemgr_request * req)
|
||||||
|
|
||||||
|
debug("cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);
|
||||||
|
|
||||||
|
+ char *user_name;
|
||||||
|
if ((user_name = strtok(NULL, "|")) == NULL) {
|
||||||
|
xfree(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ rfc1738_unescape(user_name);
|
||||||
|
|
||||||
|
debug("cmgr: decoded uname: '%s'\n", user_name);
|
||||||
|
|
||||||
|
+ char *passwd;
|
||||||
|
if ((passwd = strtok(NULL, "|")) == NULL) {
|
||||||
|
xfree(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ rfc1738_unescape(passwd);
|
||||||
|
|
||||||
|
debug("cmgr: decoded passwd: '%s'\n", passwd);
|
||||||
|
|
50
SOURCES/squid-4.4.0-CVE-2020-11945.patch
Normal file
50
SOURCES/squid-4.4.0-CVE-2020-11945.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
diff --git a/src/auth/digest/Config.cc b/src/auth/digest/Config.cc
|
||||||
|
index 45e46c0..433335a 100644
|
||||||
|
--- a/src/auth/digest/Config.cc
|
||||||
|
+++ b/src/auth/digest/Config.cc
|
||||||
|
@@ -94,9 +94,6 @@ static void authenticateDigestNonceDelete(digest_nonce_h * nonce);
|
||||||
|
static void authenticateDigestNonceSetup(void);
|
||||||
|
static void authDigestNonceEncode(digest_nonce_h * nonce);
|
||||||
|
static void authDigestNonceLink(digest_nonce_h * nonce);
|
||||||
|
-#if NOT_USED
|
||||||
|
-static int authDigestNonceLinks(digest_nonce_h * nonce);
|
||||||
|
-#endif
|
||||||
|
static void authDigestNonceUserUnlink(digest_nonce_h * nonce);
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -287,21 +284,10 @@ authDigestNonceLink(digest_nonce_h * nonce)
|
||||||
|
{
|
||||||
|
assert(nonce != NULL);
|
||||||
|
++nonce->references;
|
||||||
|
+ assert(nonce->references != 0); // no overflows
|
||||||
|
debugs(29, 9, "nonce '" << nonce << "' now at '" << nonce->references << "'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if NOT_USED
|
||||||
|
-static int
|
||||||
|
-authDigestNonceLinks(digest_nonce_h * nonce)
|
||||||
|
-{
|
||||||
|
- if (!nonce)
|
||||||
|
- return -1;
|
||||||
|
-
|
||||||
|
- return nonce->references;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
void
|
||||||
|
authDigestNonceUnlink(digest_nonce_h * nonce)
|
||||||
|
{
|
||||||
|
diff --git a/src/auth/digest/Config.h b/src/auth/digest/Config.h
|
||||||
|
index b79ff30..2840865 100644
|
||||||
|
--- a/src/auth/digest/Config.h
|
||||||
|
+++ b/src/auth/digest/Config.h
|
||||||
|
@@ -44,7 +44,7 @@ struct _digest_nonce_h : public hash_link {
|
||||||
|
/* number of uses we've seen of this nonce */
|
||||||
|
unsigned long nc;
|
||||||
|
/* reference count */
|
||||||
|
- short references;
|
||||||
|
+ uint64_t references;
|
||||||
|
/* the auth_user this nonce has been tied to */
|
||||||
|
Auth::Digest::User *user;
|
||||||
|
/* has this nonce been invalidated ? */
|
127
SOURCES/squid-4.4.0-active-ftp.patch
Normal file
127
SOURCES/squid-4.4.0-active-ftp.patch
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
diff --git a/src/clients/FtpClient.cc b/src/clients/FtpClient.cc
|
||||||
|
index 777210c..4c80511 100644
|
||||||
|
--- a/src/clients/FtpClient.cc
|
||||||
|
+++ b/src/clients/FtpClient.cc
|
||||||
|
@@ -778,7 +778,8 @@ Ftp::Client::connectDataChannel()
|
||||||
|
bool
|
||||||
|
Ftp::Client::openListenSocket()
|
||||||
|
{
|
||||||
|
- return false;
|
||||||
|
+ debugs(9, 3, HERE);
|
||||||
|
+ return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// creates a data channel Comm close callback
|
||||||
|
diff --git a/src/clients/FtpClient.h b/src/clients/FtpClient.h
|
||||||
|
index 465fdb7..75dbd3b 100644
|
||||||
|
--- a/src/clients/FtpClient.h
|
||||||
|
+++ b/src/clients/FtpClient.h
|
||||||
|
@@ -118,7 +118,7 @@ public:
|
||||||
|
bool sendPort();
|
||||||
|
bool sendPassive();
|
||||||
|
void connectDataChannel();
|
||||||
|
- bool openListenSocket();
|
||||||
|
+ virtual bool openListenSocket();
|
||||||
|
void switchTimeoutToDataChannel();
|
||||||
|
|
||||||
|
CtrlChannel ctrl; ///< FTP control channel state
|
||||||
|
diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc
|
||||||
|
index a13cdda..b958b14 100644
|
||||||
|
--- a/src/clients/FtpGateway.cc
|
||||||
|
+++ b/src/clients/FtpGateway.cc
|
||||||
|
@@ -87,6 +87,13 @@ struct GatewayFlags {
|
||||||
|
class Gateway;
|
||||||
|
typedef void (StateMethod)(Ftp::Gateway *);
|
||||||
|
|
||||||
|
+} // namespace FTP
|
||||||
|
+
|
||||||
|
+static void ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback);
|
||||||
|
+
|
||||||
|
+namespace Ftp
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
/// FTP Gateway: An FTP client that takes an HTTP request with an ftp:// URI,
|
||||||
|
/// converts it into one or more FTP commands, and then
|
||||||
|
/// converts one or more FTP responses into the final HTTP response.
|
||||||
|
@@ -137,7 +144,11 @@ public:
|
||||||
|
|
||||||
|
/// create a data channel acceptor and start listening.
|
||||||
|
void listenForDataChannel(const Comm::ConnectionPointer &conn);
|
||||||
|
-
|
||||||
|
+ virtual bool openListenSocket() {
|
||||||
|
+ debugs(9, 3, HERE);
|
||||||
|
+ ftpOpenListenSocket(this, 0);
|
||||||
|
+ return Comm::IsConnOpen(data.conn);
|
||||||
|
+ }
|
||||||
|
int checkAuth(const HttpHeader * req_hdr);
|
||||||
|
void checkUrlpath();
|
||||||
|
void buildTitleUrl();
|
||||||
|
@@ -1792,6 +1803,7 @@ ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
ftpState->listenForDataChannel(temp);
|
||||||
|
+ ftpState->data.listenConn = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -1827,13 +1839,19 @@ ftpSendPORT(Ftp::Gateway * ftpState)
|
||||||
|
// pull out the internal IP address bytes to send in PORT command...
|
||||||
|
// source them from the listen_conn->local
|
||||||
|
|
||||||
|
+ struct sockaddr_in addr;
|
||||||
|
+ socklen_t addrlen = sizeof(addr);
|
||||||
|
+ getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
|
||||||
|
+ unsigned char port_high = ntohs(addr.sin_port) >> 8;
|
||||||
|
+ unsigned char port_low = ntohs(addr.sin_port) & 0xff;
|
||||||
|
+
|
||||||
|
struct addrinfo *AI = NULL;
|
||||||
|
ftpState->data.listenConn->local.getAddrInfo(AI, AF_INET);
|
||||||
|
unsigned char *addrptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_addr;
|
||||||
|
- unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
|
||||||
|
+ // unsigned char *portptr = (unsigned char *) &((struct sockaddr_in*)AI->ai_addr)->sin_port;
|
||||||
|
snprintf(cbuf, CTRL_BUFLEN, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||||
|
addrptr[0], addrptr[1], addrptr[2], addrptr[3],
|
||||||
|
- portptr[0], portptr[1]);
|
||||||
|
+ port_high, port_low);
|
||||||
|
ftpState->writeCommand(cbuf);
|
||||||
|
ftpState->state = Ftp::Client::SENT_PORT;
|
||||||
|
|
||||||
|
@@ -1886,14 +1904,27 @@ ftpSendEPRT(Ftp::Gateway * ftpState)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+ unsigned int port;
|
||||||
|
+ struct sockaddr_storage addr;
|
||||||
|
+ socklen_t addrlen = sizeof(addr);
|
||||||
|
+ getsockname(ftpState->data.listenConn->fd, (struct sockaddr *) &addr, &addrlen);
|
||||||
|
+ if (addr.ss_family == AF_INET) {
|
||||||
|
+ struct sockaddr_in *addr4 = (struct sockaddr_in*) &addr;
|
||||||
|
+ port = ntohs( addr4->sin_port );
|
||||||
|
+ } else {
|
||||||
|
+ struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr;
|
||||||
|
+ port = ntohs( addr6->sin6_port );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
char buf[MAX_IPSTRLEN];
|
||||||
|
|
||||||
|
/* RFC 2428 defines EPRT as IPv6 equivalent to IPv4 PORT command. */
|
||||||
|
/* Which can be used by EITHER protocol. */
|
||||||
|
- snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%d|\r\n",
|
||||||
|
+ snprintf(cbuf, CTRL_BUFLEN, "EPRT |%d|%s|%u|\r\n",
|
||||||
|
( ftpState->data.listenConn->local.isIPv6() ? 2 : 1 ),
|
||||||
|
ftpState->data.listenConn->local.toStr(buf,MAX_IPSTRLEN),
|
||||||
|
- ftpState->data.listenConn->local.port() );
|
||||||
|
+ port);
|
||||||
|
|
||||||
|
ftpState->writeCommand(cbuf);
|
||||||
|
ftpState->state = Ftp::Client::SENT_EPRT;
|
||||||
|
@@ -1912,7 +1943,7 @@ ftpReadEPRT(Ftp::Gateway * ftpState)
|
||||||
|
ftpSendPORT(ftpState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ ftpState->ctrl.message = NULL;
|
||||||
|
ftpRestOrList(ftpState);
|
||||||
|
}
|
||||||
|
|
12
SOURCES/squid-4.4.0-lower-cachepeer.patch
Normal file
12
SOURCES/squid-4.4.0-lower-cachepeer.patch
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/src/cache_cf.cc b/src/cache_cf.cc
|
||||||
|
index 9165ef99c..32a3df322 100644
|
||||||
|
--- a/src/cache_cf.cc
|
||||||
|
+++ b/src/cache_cf.cc
|
||||||
|
@@ -2081,6 +2081,7 @@ parse_peer(CachePeer ** head)
|
||||||
|
|
||||||
|
CachePeer *p = new CachePeer;
|
||||||
|
p->host = xstrdup(host_str);
|
||||||
|
+ Tolower(p->host);
|
||||||
|
p->name = xstrdup(host_str);
|
||||||
|
p->type = parseNeighborType(token);
|
||||||
|
|
26
SOURCES/squid-4.4.0-man-pages.patch
Normal file
26
SOURCES/squid-4.4.0-man-pages.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
diff --git a/src/http/url_rewriters/LFS/url_lfs_rewrite.8 b/src/http/url_rewriters/LFS/url_lfs_rewrite.8
|
||||||
|
index 3053180..1d295fb 100644
|
||||||
|
--- a/src/http/url_rewriters/LFS/url_lfs_rewrite.8
|
||||||
|
+++ b/src/http/url_rewriters/LFS/url_lfs_rewrite.8
|
||||||
|
@@ -135,7 +135,7 @@
|
||||||
|
.if n .ad l
|
||||||
|
.nh
|
||||||
|
.SH "NAME"
|
||||||
|
-url_lfs_rewrite
|
||||||
|
+\& url_lfs_rewrite \- a URL-rewriter based on local file existence
|
||||||
|
.SH "SYNOPSIS"
|
||||||
|
.IX Header "SYNOPSIS"
|
||||||
|
.Vb 1
|
||||||
|
diff --git a/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in b/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
|
||||||
|
index a7168e0..da7055c 100755
|
||||||
|
--- a/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
|
||||||
|
+++ b/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
|
||||||
|
@@ -8,7 +8,7 @@ use Pod::Usage;
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
-B<url_lfs_rewrite>
|
||||||
|
+B<url_lfs_rewrite> - a URL-rewriter based on local file existence
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
25
SOURCES/squid-4.4.tar.xz.asc
Normal file
25
SOURCES/squid-4.4.tar.xz.asc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
File: squid-4.4.tar.xz
|
||||||
|
Date: Sat Oct 27 21:20:24 UTC 2018
|
||||||
|
Size: 2436468
|
||||||
|
MD5 : 892504ca9700e1f139a53f84098613bd
|
||||||
|
SHA1: 0ab6b133f65866d825bf72cbbe8cef209768b2fa
|
||||||
|
Key : CD6DBF8EF3B17D3E <squid3@treenet.co.nz>
|
||||||
|
B068 84ED B779 C89B 044E 64E3 CD6D BF8E F3B1 7D3E
|
||||||
|
keyring = http://www.squid-cache.org/pgp.asc
|
||||||
|
keyserver = pool.sks-keyservers.net
|
||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCgAdFiEEsGiE7bd5yJsETmTjzW2/jvOxfT4FAlvU1qAACgkQzW2/jvOx
|
||||||
|
fT5Y3Q//R3/ZtDHal9H9c4VUB1fEzkk22JfgXTzRRUdzNkN+XxDkVGmM9R0E0Opo
|
||||||
|
9E/lsE9PcLX1EBtBXbPfwLESzfMe4QJgqq1B4FocpJcdtfCQX6ADU4Qdfc+oo8Z1
|
||||||
|
J/xCf8XrU3yUgXn3pMnQ9DT+IuPYe+Jte7Awm148mC15GMC49NBAYAd793XZ+L2t
|
||||||
|
fVPCbVYA40AU3xVJkxlblh7O0E8UEQ7zQMxcXM2jJJ4jJOjqecOIoJt6lyPD59q3
|
||||||
|
UjD0EmcjTj54BpaU8r++kAc2TkLyBvFV1vWQuQRNG5IAMEOF3H8OfujCXl3lX9fD
|
||||||
|
Tvi9763f9LxdImLJttkzgTt20XAudlUmKOdpj6t1uF+7EmNJg/ChowyLsLzlLLST
|
||||||
|
1mGNdcUdP9VhX2aoTXN/ctn8BTQ/cNIx2VY8kKWsXB+ymFcCJRBW1cBAr3R+UzuX
|
||||||
|
KVlsDzlxP6Dp8EFvKN3sIbM/QtpstKgbTkxro7d9XBkeldsasd5uI2Yt5PSMIs+y
|
||||||
|
VtscqCnwDjxAIW6FNqB96J4hcOYECdWHDL3s46wEDnQaiR0IdBAN5QHn1imzM5e1
|
||||||
|
eHuwZimqBW6vE4rPnVpPIr1Gml5OlLl3te2jsbUVmBiOwDVlQLZJQGzI5UTazvnN
|
||||||
|
eR3QeTW+ggSAdVc6GEApELARfKPRxywLQTOlAhEPn0xayy4ByME=
|
||||||
|
=1eSQ
|
||||||
|
-----END PGP SIGNATURE-----
|
16
SOURCES/squid.logrotate
Normal file
16
SOURCES/squid.logrotate
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/var/log/squid/*.log {
|
||||||
|
weekly
|
||||||
|
rotate 5
|
||||||
|
compress
|
||||||
|
notifempty
|
||||||
|
missingok
|
||||||
|
nocreate
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
# Asks squid to reopen its logs. (logfile_rotate 0 is set in squid.conf)
|
||||||
|
# errors redirected to make it silent if squid is not running
|
||||||
|
/usr/sbin/squid -k rotate 2>/dev/null
|
||||||
|
# Wait a little to allow Squid to catch up before the logs is compressed
|
||||||
|
sleep 1
|
||||||
|
endscript
|
||||||
|
}
|
7
SOURCES/squid.nm
Executable file
7
SOURCES/squid.nm
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
up|down|vpn-up|vpn-down)
|
||||||
|
/bin/systemctl -q reload squid.service || :
|
||||||
|
;;
|
||||||
|
esac
|
3
SOURCES/squid.pam
Normal file
3
SOURCES/squid.pam
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#%PAM-1.0
|
||||||
|
auth include password-auth
|
||||||
|
account include password-auth
|
17
SOURCES/squid.service
Normal file
17
SOURCES/squid.service
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Squid caching proxy
|
||||||
|
Documentation=man:squid(8)
|
||||||
|
After=network.target network-online.target nss-lookup.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
LimitNOFILE=16384
|
||||||
|
EnvironmentFile=/etc/sysconfig/squid
|
||||||
|
ExecStartPre=/usr/libexec/squid/cache_swap.sh
|
||||||
|
ExecStart=/usr/sbin/squid $SQUID_OPTS -f $SQUID_CONF
|
||||||
|
ExecReload=/usr/sbin/squid $SQUID_OPTS -k reconfigure -f $SQUID_CONF
|
||||||
|
ExecStop=/usr/sbin/squid -k shutdown -f $SQUID_CONF
|
||||||
|
TimeoutSec=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
9
SOURCES/squid.sysconfig
Normal file
9
SOURCES/squid.sysconfig
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# default squid options
|
||||||
|
SQUID_OPTS=""
|
||||||
|
|
||||||
|
# Time to wait for Squid to shut down when asked. Should not be necessary
|
||||||
|
# most of the time.
|
||||||
|
SQUID_SHUTDOWN_TIMEOUT=100
|
||||||
|
|
||||||
|
# default squid conf file
|
||||||
|
SQUID_CONF="/etc/squid/squid.conf"
|
1648
SPECS/squid.spec
Normal file
1648
SPECS/squid.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user