return std::unique_ptr<RegexPattern>(new RegexPattern(pattern, flags));
}
-void
-ConfigParser::SetAclKey(SBuf &keyStorage, const char *keyParameterName)
-{
- extern const char *AclMatchedName;
-
- const auto newKey = strtokFile();
- if (!newKey) {
- throw TextException(ToSBuf("An acl declaration is missing a ", keyParameterName,
- Debug::Extra, "ACL name: ", AclMatchedName),
- Here());
- }
-
- if (keyStorage.isEmpty()) {
- keyStorage = newKey;
- return;
- }
-
- if (keyStorage.caseCmp(newKey) == 0)
- return; // no change
-
- throw TextException(ToSBuf("Attempt to change the value of the ", keyParameterName, " argument in a subsequent acl declaration:",
- Debug::Extra, "previously seen value: ", keyStorage,
- Debug::Extra, "new/conflicting value: ", newKey,
- Debug::Extra, "ACL name: ", AclMatchedName,
- Debug::Extra, "advice: Use a dedicated ACL name for each distinct ", keyParameterName,
- " (and group those ACLs together using an 'any-of' ACL)."),
- Here());
-}
-
CachePeer &
ConfigParser::cachePeer(const char *peerNameTokenDescription)
{
*/
static bool NextKvPair(char * &key, char * &value);
- // TODO: Convert into a non-static method after exposing the current parser.
- /// Extract, validate, and store the ACL key parameter for ACL types
- /// declared using "acl aclname type key argument..." declaration that
- /// require unique key values for each aclname+type combination.
- /// Key comparison is case-insensitive.
- static void SetAclKey(SBuf &keyStorage, const char *keyParameterName);
-
/**
* Preview the next token. The next NextToken() and strtokFile() call
* will return the same token.
TheMakers().emplace(typeName, maker);
}
+void
+Acl::SetKey(SBuf &keyStorage, const char *keyParameterName, const char *newKey)
+{
+ if (!newKey) {
+ throw TextException(ToSBuf("An acl declaration is missing a ", keyParameterName,
+ Debug::Extra, "ACL name: ", AclMatchedName),
+ Here());
+ }
+
+ if (keyStorage.isEmpty()) {
+ keyStorage = newKey;
+ return;
+ }
+
+ if (keyStorage.caseCmp(newKey) == 0)
+ return; // no change
+
+ throw TextException(ToSBuf("Attempt to change the value of the ", keyParameterName, " argument in a subsequent acl declaration:",
+ Debug::Extra, "previously seen value: ", keyStorage,
+ Debug::Extra, "new/conflicting value: ", newKey,
+ Debug::Extra, "ACL name: ", AclMatchedName,
+ Debug::Extra, "advice: Use a dedicated ACL name for each distinct ", keyParameterName,
+ " (and group those ACLs together using an 'any-of' ACL)."),
+ Here());
+}
+
void *
ACL::operator new (size_t)
{
/// use the given ACL Maker for all ACLs of the named type
void RegisterMaker(TypeName typeName, Maker maker);
+/// Validate and store the ACL key parameter for ACL types
+/// declared using "acl aclname type key argument..." declaration that
+/// require unique key values (if any) for each aclname+type combination.
+/// Key comparison is case-insensitive.
+void SetKey(SBuf &keyStorage, const char *keyParameterName, const char *newKey);
+
} // namespace Acl
/// A configurable condition. A node in the ACL expression tree.
#include "debug/Stream.h"
#include "wordlist.h"
-ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE *sslStrategy, const char *attrs, bool optionalAttr) : validAttributesStr(attrs), attributeIsOptional(optionalAttr), attribute (nullptr), values (), sslAttributeCall (sslStrategy)
+ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE * const sslStrategy, const char * const attrs, const bool optionalAttr):
+ validAttributesStr(attrs),
+ attributeIsOptional(optionalAttr),
+ sslAttributeCall(sslStrategy)
{
if (attrs) {
size_t current = 0;
xfree (thing);
}
-ACLCertificateData::~ACLCertificateData()
-{
- safe_free (attribute);
-}
-
template<class T>
inline int
splaystrcmp (T&l, T&r)
if (!cert)
return 0;
- char const *value = sslAttributeCall(cert, attribute);
- debugs(28, 6, (attribute ? attribute : "value") << "=" << value);
+ const auto value = sslAttributeCall(cert, attribute.c_str());
+ debugs(28, 6, (attribute.isEmpty() ? attribute.c_str() : "value") << "=" << value);
if (value == nullptr)
return 0;
{
SBufList sl;
if (validAttributesStr)
- sl.push_back(SBuf(attribute));
+ sl.push_back(attribute);
sl.splice(sl.end(),values.dump());
return sl;
return;
}
- /* an acl must use consistent attributes in all config lines */
- if (attribute) {
- if (strcasecmp(newAttribute, attribute) != 0) {
- debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ").");
- self_destruct();
- return;
- }
- } else {
+ // If attribute has been set already, then we do not need to call OBJ_create()
+ // below because either we did that for the same attribute when we set it, or
+ // Acl::SetKey() below will reject this new/different attribute spelling.
+ if (attribute.isEmpty()) {
if (strcasecmp(newAttribute, "DN") != 0) {
int nid = OBJ_txt2nid(newAttribute);
if (nid == 0) {
return;
}
}
- attribute = xstrdup(newAttribute);
}
+
+ Acl::SetKey(attribute, "SSL certificate attribute", newAttribute);
}
}
public:
ACLCertificateData(Ssl::GETX509ATTRIBUTE *, const char *attributes, bool optionalAttr = false);
- ~ACLCertificateData() override;
bool match(X509 *) override;
SBufList dump() const override;
void parse() override;
std::list<std::string> validAttributes;
/// True if the attribute is optional (-xxx options)
bool attributeIsOptional;
- char *attribute;
+ SBuf attribute;
ACLStringData values;
private:
void
ACLHTTPHeaderData::parse()
{
- ConfigParser::SetAclKey(hdrName, "header-name");
+ Acl::SetKey(hdrName, "header-name", ConfigParser::strtokFile());
hdrId = Http::HeaderLookupTable.lookup(hdrName).id;
regex_rule->parse();
}
void
ACLNoteData::parse()
{
- ConfigParser::SetAclKey(name, "annotation name");
+ Acl::SetKey(name, "annotation name", ConfigParser::strtokFile());
values->parse();
}