Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove AclMatchedName from ACL::ParseAclLine() #239

Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7493545
Remove AclMatchedName from ACL::ParseAclLine()
eduard-bagdasaryan Nov 21, 2023
7e0237b
Merged several ACL configuration admin-level error messages
eduard-bagdasaryan Nov 21, 2023
f577b68
Removed a stale comment
eduard-bagdasaryan Nov 22, 2023
9300f69
Apply CallContextCreator() wrapper to the entire parse_line()
eduard-bagdasaryan Nov 24, 2023
26917d3
Add ACL dstdomain, src, http_status test cases
eduard-bagdasaryan Nov 24, 2023
754f7b0
Do not duplicate context in ConfigParser::destruct() messages
eduard-bagdasaryan Nov 24, 2023
a0bda44
Polished
eduard-bagdasaryan Nov 24, 2023
8d8b7a0
Added a helper CallContextParser()
eduard-bagdasaryan Nov 28, 2023
f705d5e
Added Debug::Extra to error messages and adjusted tests
eduard-bagdasaryan Nov 28, 2023
b76b76b
Fixed a typo
eduard-bagdasaryan Nov 28, 2023
988e062
Renamed tests according to the 'bad-acl...' convention
eduard-bagdasaryan Nov 28, 2023
7f4c9ba
Imporoved 'negative' tests and added a positive one
eduard-bagdasaryan Nov 28, 2023
c71e2b2
Removed previous tests
eduard-bagdasaryan Nov 29, 2023
5047883
Removed a previous test
eduard-bagdasaryan Nov 29, 2023
7283c34
Added 'src' tests for ipv6 and range addresses (combining with masks)
eduard-bagdasaryan Nov 29, 2023
9ad99d2
Simplified expressions in *instructions
eduard-bagdasaryan Nov 29, 2023
4ccfdbe
Polished documentation
eduard-bagdasaryan Nov 29, 2023
83d8c36
Added USE_IPV6 precondition on IPv6 tests
eduard-bagdasaryan Nov 29, 2023
567290a
Support a second argument for skip-unless-autoconf-defines instruction
eduard-bagdasaryan Nov 30, 2023
6a796cc
Adjusted tests with the second skip-unless-autoconf-defines parameter
eduard-bagdasaryan Nov 30, 2023
0a182f4
Merged from master
eduard-bagdasaryan Jan 9, 2024
5dbf871
Merged from master
eduard-bagdasaryan Jan 16, 2024
931c505
Removed AclMatchedName leftovers after merge
eduard-bagdasaryan Jan 16, 2024
b41958e
Removed test-suite tests
eduard-bagdasaryan Jan 16, 2024
abf8097
Adjusted tests
eduard-bagdasaryan Jan 16, 2024
662f661
Fixed broken tests
eduard-bagdasaryan Jan 17, 2024
56609b9
Removed AclMatchedName from ACL note parsing code
eduard-bagdasaryan Jan 17, 2024
56364c5
fixup: Removed Acl:: from code inside that namespace
rousskov Jan 17, 2024
4030d00
fixup: Polished single-parameter ctor declaration
rousskov Jan 17, 2024
e9f6009
fixup: Make ParsingContext creator not responsible for name lifetime
rousskov Jan 17, 2024
5decf4f
fixup: Do not expose non-ACL_parsing code to Acl::ParsingContext
rousskov Jan 17, 2024
7b81eb6
fixup: Polished CallContextParser() name and docs
rousskov Jan 17, 2024
68a0d95
fixup: Minor names/comments polishing
rousskov Jan 17, 2024
e8781bb
fixup: Expose c-string-to-SBuf conversion,
rousskov Jan 17, 2024
941d688
fixup: Restored testing of expected aclnames
rousskov Jan 17, 2024
50d9e50
fixup: Formatted modified sources
rousskov Jan 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/acl/Acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ Acl::SetKey(SBuf &keyStorage, const char *keyParameterName, const char *newKey)
Here());
}

ScopedId
Acl::ParsingContext::codeContextGist() const {
return ScopedId("acl");
}

std::ostream &
Acl::ParsingContext::detailCodeContext(std::ostream &os) const
{
return os << Debug::Extra << "acl name: " << name_ <<
Debug::Extra << "configuration context: " << ConfigParser::CurrentLocation();
}

void *
ACL::operator new (size_t)
{
Expand Down Expand Up @@ -193,9 +205,7 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
{
/* we're already using strtok() to grok the line */
char *t = nullptr;
ACL *A = nullptr;
LOCAL_ARRAY(char, aclname, ACL_NAME_SZ);
int new_acl = 0;

/* snarf the ACL name */

Expand All @@ -213,6 +223,15 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
}

xstrncpy(aclname, t, ACL_NAME_SZ);

CallContextParser(Acl::ParsingContext::Pointer::Make(aclname), [&] {
ParseNamed(parser, head, aclname);
});
}

void
ACL::ParseNamed(ConfigParser &parser, ACL ** head, const char *aclname)
{
/* snarf the ACL type */
const char *theType;

Expand Down Expand Up @@ -253,6 +272,8 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
theType = "client_connection_mark";
}

ACL *A = nullptr;
int new_acl = 0;
if ((A = FindByName(aclname)) == nullptr) {
debugs(28, 3, "aclParseAclLine: Creating ACL '" << aclname << "'");
A = Acl::Make(theType);
Expand All @@ -269,22 +290,11 @@ ACL::ParseAclLine(ConfigParser &parser, ACL ** head)
new_acl = 0;
}

/*
* Here we set AclMatchedName in case we need to use it in a
* warning message in aclDomainCompare().
*/
AclMatchedName = A->name; /* ugly */

A->parseFlags();

/*split the function here */
A->parse();

/*
* Clear AclMatchedName from our temporary hack
*/
AclMatchedName = nullptr; /* ugly */

if (!new_acl)
return;

Expand Down
20 changes: 20 additions & 0 deletions src/acl/Acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "acl/forward.h"
#include "acl/Options.h"
#include "base/CodeContext.h"
#include "cbdata.h"
#include "defines.h"
#include "dlink.h"
Expand All @@ -36,6 +37,22 @@ void RegisterMaker(TypeName typeName, Maker maker);
/// Key comparison is case-insensitive.
void SetKey(SBuf &keyStorage, const char *keyParameterName, const char *newKey);

/// CodeContext of the ACL being parsed
class ParsingContext : public CodeContext
{
public:
using Pointer = RefCount<ParsingContext>;

ParsingContext(const char *name) : name_(name) {}

/* CodeContext API */
ScopedId codeContextGist() const override;
std::ostream &detailCodeContext(std::ostream &os) const override;

private:
const char *name_; ///< the parsed ACL name
};

} // namespace Acl

/// A configurable condition. A node in the ACL expression tree.
Expand Down Expand Up @@ -111,6 +128,9 @@ class ACL
/// \returns (linked) "line" Options supported by this ACL
/// \see ACL::options()
virtual const Acl::Options &lineOptions() { return Acl::NoOptions(); }

/// parses the rest of ACL line following ACL name
static void ParseNamed(ConfigParser &, ACL ** head, const char *name);
};

/// \ingroup ACLAPI
Expand Down
19 changes: 12 additions & 7 deletions src/acl/DomainData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
#include "acl/Checklist.h"
#include "acl/DomainData.h"
#include "anyp/Uri.h"
#include "base/TextException.h"
#include "cache_cf.h"
#include "ConfigParser.h"
#include "debug/Stream.h"
#include "sbuf/Stream.h"
#include "util.h"

template<class T>
Expand Down Expand Up @@ -78,24 +80,27 @@ aclDomainCompare(T const &a, T const &b)
// When a.example.com comes after .example.com in an ACL
// sub-domain is ignored. That is okay. Just important
bool d3big = (strlen(d3) > strlen(d4)); // Always suggest removing the longer one.
debugs(28, DBG_IMPORTANT, "WARNING: '" << (d3big?d3:d4) << "' is a subdomain of '" << (d3big?d4:d3) << "'");
debugs(28, DBG_IMPORTANT, "WARNING: You should remove '" << (d3big?d3:d4) << "' from the ACL named '" << AclMatchedName << "'");
const auto longer = d3big ? d3 : d4;
const auto shorter = d3big ? d4 : d3;
debugs(28, DBG_IMPORTANT, "WARNING: '" << longer << "' is a subdomain of '" << shorter << "'" <<
Debug::Extra << "You should remove '" << longer << "' from the ACL");
debugs(28, 2, "Ignore '" << d3 << "' to keep splay tree searching predictable");
}
} else if (ret == 0) {
// It may be an exact duplicate. No problem. Just drop.
if (strcmp(d1,d2)==0) {
debugs(28, 2, "WARNING: '" << d2 << "' is duplicated in the list.");
debugs(28, 2, "WARNING: You should remove one '" << d2 << "' from the ACL named '" << AclMatchedName << "'");
debugs(28, DBG_PARSE_NOTE(2), "WARNING: '" << d2 << "' is duplicated in the list." <<
Debug::Extra << "You should remove one '" << d2 << "' from the ACL");
return ret;
}
// When a.example.com comes before .example.com in an ACL
// discarding the wildcard is critically bad.
// or Maybe even both are wildcards. Things are very weird in those cases.
bool d1big = (strlen(d1) > strlen(d2)); // Always suggest removing the longer one.
debugs(28, DBG_CRITICAL, "ERROR: '" << (d1big?d1:d2) << "' is a subdomain of '" << (d1big?d2:d1) << "'");
debugs(28, DBG_CRITICAL, "ERROR: You need to remove '" << (d1big?d1:d2) << "' from the ACL named '" << AclMatchedName << "'");
self_destruct();
const auto longer = d1big ? d1 : d2;
const auto shorter = d1big ? d2 : d1;
throw TextException(ToSBuf("'", longer, "' is a subdomain of '", shorter, "'",
Debug::Extra, "You need to remove '", longer, "' from the ACL"), Here());
}

return ret;
Expand Down
6 changes: 3 additions & 3 deletions src/acl/HttpStatus.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ int acl_httpstatus_data::compare(acl_httpstatus_data* const& a, acl_httpstatus_d
if (ret == 0) {
const SBuf sa = a->toStr();
const SBuf sb = b->toStr();
debugs(28, DBG_CRITICAL, "WARNING: '" << sa << "' is a subrange of '" << sb << "'");
debugs(28, DBG_CRITICAL, "WARNING: because of this '" << sa << "' is ignored to keep splay tree searching predictable");
debugs(28, DBG_CRITICAL, "WARNING: You should probably remove '" << sb << "' from the ACL named '" << AclMatchedName << "'");
debugs(28, DBG_CRITICAL, "WARNING: '" << sa << "' is a subrange of '" << sb << "'" <<
Debug::Extra << "Because of this '" << sa << "' is ignored to keep splay tree searching predictable" <<
Debug::Extra << "You should probably remove '" << sb << "' from the ACL");
}

return ret;
Expand Down
6 changes: 3 additions & 3 deletions src/acl/Ip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ acl_ip_data::NetworkCompare(acl_ip_data * const & a, acl_ip_data * const &b)
a->toStr(buf_n1, 3*(MAX_IPSTRLEN+1));
b->toStr(buf_n2, 3*(MAX_IPSTRLEN+1));
}
debugs(28, DBG_CRITICAL, "WARNING: (" << (bina?'B':'A') << ") '" << buf_n1 << "' is a subnetwork of (" << (bina?'A':'B') << ") '" << buf_n2 << "'");
debugs(28, DBG_CRITICAL, "WARNING: because of this '" << (bina?buf_n2:buf_n1) << "' is ignored to keep splay tree searching predictable");
debugs(28, DBG_CRITICAL, "WARNING: You should probably remove '" << buf_n1 << "' from the ACL named '" << AclMatchedName << "'");
debugs(28, DBG_CRITICAL, "WARNING: (" << (bina?'B':'A') << ") '" << buf_n1 << "' is a subnetwork of (" << (bina?'A':'B') << ") '" << buf_n2 << "'" <<
Debug::Extra << "Because of this '" << (bina?buf_n2:buf_n1) << "' is ignored to keep splay tree searching predictable" <<
Debug::Extra << "You should probably remove '" << buf_n1 << "' from the ACL");
}

return ret;
Expand Down
2 changes: 1 addition & 1 deletion src/acl/ProtocolData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ ACLProtocolData::parse()
}
}
if (p == AnyP::PROTO_UNKNOWN) {
debugs(28, DBG_IMPORTANT, "WARNING: Ignoring unknown protocol '" << t << "' in the ACL named '" << AclMatchedName << "'");
debugs(28, DBG_IMPORTANT, "WARNING: Ignoring unknown protocol '" << t << "' in the ACL");
// XXX: store the text pattern of this protocol name for live comparisons
}
}
Expand Down
32 changes: 25 additions & 7 deletions src/base/CodeContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,38 @@ class CodeContextGuard
CodeContext::Pointer savedCodeContext;
};

/// Executes service `callback` in `callbackContext`. If an exception occurs,
/// the callback context is preserved, so that the exception is associated with
/// the callback that triggered them (rather than with the service).
/// Executes 'fun' in `funContext`. If an exception occurs,
/// the funContext is preserved, so that the exception is associated with
/// the call that triggered it.
template <typename Fun>
inline void
CallAndRestore_(const CodeContext::Pointer &funContext, Fun &&fun)
{
const auto savedCodeContext(CodeContext::Current());
CodeContext::Reset(funContext);
fun();
CodeContext::Reset(savedCodeContext);
}

/// \copydoc CallAndRestore_(const CodeContext::Pointer &funContext, Fun &&fun)
///
/// Service code running in its own service context should use this function.
template <typename Fun>
inline void
CallBack(const CodeContext::Pointer &callbackContext, Fun &&callback)
{
// TODO: Consider catching exceptions and letting CodeContext handle them.
const auto savedCodeContext(CodeContext::Current());
CodeContext::Reset(callbackContext);
callback();
CodeContext::Reset(savedCodeContext);
CallAndRestore_(callbackContext, callback);
}

/// \copydoc CallAndRestore_(const CodeContext::Pointer &funContext, Fun &&fun)
///
/// Specific parser code initiated by parse_line() should use this function.
template <typename Fun>
inline void
CallContextParser(const CodeContext::Pointer &parserContext, Fun &&parse)
{
CallAndRestore_(parserContext, parse);
}

/// Executes `service` in `serviceContext` but due to automatic caller context
Expand Down
2 changes: 1 addition & 1 deletion src/external_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ ACLExternal::parse()

// def->name is the name of the external_acl_type.
// this is the name of the 'acl' directive being tested
data->name = xstrdup(AclMatchedName);
data->name = xstrdup(name);

while ((token = ConfigParser::strtokFile())) {
wordlistAdd(&data->arguments, token);
Expand Down
20 changes: 20 additions & 0 deletions test-suite/squidconf/acl-src-dstdomain-http-status.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Copyright (C) 1996-2023 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.
##

acl foo_dstdomain dstdomain example.com one.example.org
acl foo_dstdomain dstdomain .example.net two.example.org
acl foo_dstdomain dstdomain .three.example.org

acl foo_src_4 src 192.168.2.0/24 192.168.1.0/24
acl foo_src_4 src 192.168.3.0-192.168.3.255

# TODO: make configurable depending on USE_IPV6
# acl foo_src_6 src fed0::2-fee0:: fee0::1
# acl foo_src_6 src fec0::-fed0:: fed0::1

acl foo http_status 404 200 199
acl foo http_status 500 206
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-dstdomain-dup.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo dstdomain .example.com .example.com
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-message WARNING:.*example.com..is.duplicated.in.the.list
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-dstdomain-subdomain-after.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo dstdomain .example.com a.example.com
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-message WARNING:..a.example.com..is.a.subdomain.of.*example.com
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-dstdomain-subdomain-before.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo dstdomain a.example.com .example.com
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-failure ERROR:.configuration.failure:..a.example.com..is.a.subdomain.of.*example.com
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-http-status-dup.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo http_status 200 200
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-message WARNING:..200..is.a.subrange.of..200
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-src-subnetwork-range-v6.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo src fec0::-fed0:: fec0::/10
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
skip-unless-autoconf-defines USE_IPV6 1
expect-message WARNING:.*fec0::-fed0::..is.a.subnetwork.of.*fec0::/10
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-src-subnetwork-range.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo src 192.168.0.0/16 192.168.1.0-192.168.1.255
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-message WARNING:.*192.168.1.0-192.168.1.255..is.a.subnetwork.of.*192.168.0.0/16
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-src-subnetwork-v6.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo src fec0::/10 fee0::/11
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
skip-unless-autoconf-defines USE_IPV6 1
expect-message WARNING:.*fee0::/11..is.a.subnetwork.of.*fec0::/10
8 changes: 8 additions & 0 deletions test-suite/squidconf/bad-acl-src-subnetwork.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Copyright (C) 1996-2023 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.
##

acl foo src 192.168.0.0/16 192.168.1.0/24
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expect-message WARNING:.*192.168.1.0/24..is.a.subnetwork.of.*192.168.0.0/16
13 changes: 7 additions & 6 deletions test-suite/test-squid-conf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,7 @@ then
then
# Skip test unless the given macro is #defined in autoconf.h
defineName=$p1

if test -n "$p2"
then
echo "$here: ERROR: Bad $instructionName instruction: Unexpected second parameter: $p2";
exit 1;
fi
defineValue=$p2

autoconfHeader="$top_builddir/include/autoconf.h"
if ! grep -q -w "$defineName" $autoconfHeader
Expand All @@ -99,6 +94,12 @@ then
exit 0;
fi

if ! grep -q "# *define *\b$defineName\b $defineValue *$" $autoconfHeader
then
echo "$here: WARNING: Skipping $configFile test because $defineName is not $defineValue in $autoconfHeader";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that we want to keep the second parameter (i.e. $p2 and $defineValue) optional (rather than require it in all use cases).

exit 0;
fi

if ! grep -q "# *define *\b$defineName\b" $autoconfHeader
then
echo "$here: ERROR: Cannot determine status of $defineName macro";
Expand Down