diff --git a/.travis.yml b/.travis.yml index 9e78797c12..4b6fde61d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -dist: trusty +dist: bionic sudo: true addons: @@ -9,7 +9,6 @@ addons: - libgeoip-dev - liblua5.2-dev - liblmdb-dev - - cppcheck language: cpp @@ -38,9 +37,12 @@ before_script: - '[ "$TRAVIS_OS_NAME" != osx ] || brew install libmaxminddb' - '[ "$TRAVIS_OS_NAME" != osx ] || brew install lmdb' - '[ "$TRAVIS_OS_NAME" != linux ] || sudo add-apt-repository --yes ppa:maxmind/ppa' + - '[ "$TRAVIS_OS_NAME" != linux ] || sudo add-apt-repository --yes ppa:grochefort/cppcheck' - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get update' - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-cache search maxmind' - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get install -y libmaxminddb-dev' + - '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get install -y cppcheck' + - '[ "$TRAVIS_OS_NAME" != linux ] || cppcheck --version' script: - ./build.sh diff --git a/Makefile.am b/Makefile.am index 734b6f3597..75ce55d1dd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -57,14 +57,16 @@ parser: cppcheck: @cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \ - -D MS_CPPCHECK_DISABLED_FOR_PARSER \ + -D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \ --suppressions-list=./test/cppcheck_suppressions.txt \ --enable=all \ --inconclusive \ --template="warning: {file},{line},{severity},{id},{message}" \ -I headers -I . -I others -I src -I others/mbedtls -I src/parser \ --error-exitcode=1 \ - -i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \ + -i "src/parser/seclang-parser.cc" \ + -i "src/parser/seclang-scanner.cc" \ + -i "parser/driver.cc" \ --force --verbose . diff --git a/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h b/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h index 4e3694454a..a6595aaa94 100644 --- a/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h +++ b/examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h @@ -176,21 +176,22 @@ class ReadingLogsViaRuleMessage { return; } - const modsecurity::RuleMessage *ruleMessage = \ - reinterpret_cast(ruleMessagev); + modsecurity::RuleMessage ruleMessage( + *reinterpret_cast(ruleMessagev)); - std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId); - std::cout << " phase: " << std::to_string(ruleMessage->m_phase); + + std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId()); + std::cout << " phase: " << std::to_string(ruleMessage.getPhase()); std::cout << std::endl; - if (ruleMessage->m_isDisruptive) { + if (ruleMessage.isDisruptive()) { std::cout << " * Disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(&ruleMessage); std::cout << std::endl; std::cout << " ** %d is meant to be informed by the webserver."; std::cout << std::endl; } else { std::cout << " * Match, but no disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(&ruleMessage); std::cout << std::endl; } } diff --git a/examples/using_bodies_in_chunks/simple_request.cc b/examples/using_bodies_in_chunks/simple_request.cc index 853668bdc0..cca090109e 100644 --- a/examples/using_bodies_in_chunks/simple_request.cc +++ b/examples/using_bodies_in_chunks/simple_request.cc @@ -69,21 +69,21 @@ static void logCb(void *data, const void *ruleMessagev) { return; } - const modsecurity::RuleMessage *ruleMessage = \ - reinterpret_cast(ruleMessagev); + modsecurity::RuleMessage ruleMessage( + *reinterpret_cast(ruleMessagev)); - std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId); - std::cout << " phase: " << std::to_string(ruleMessage->m_phase); + std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId()); + std::cout << " phase: " << std::to_string(ruleMessage.getPhase()); std::cout << std::endl; - if (ruleMessage->m_isDisruptive) { + if (ruleMessage.isDisruptive()) { std::cout << " * Disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(&ruleMessage); std::cout << std::endl; std::cout << " ** %d is meant to be informed by the webserver."; std::cout << std::endl; } else { std::cout << " * Match, but no disruptive action: "; - std::cout << modsecurity::RuleMessage::log(ruleMessage); + std::cout << modsecurity::RuleMessage::log(&ruleMessage); std::cout << std::endl; } } diff --git a/headers/modsecurity/actions/action.h b/headers/modsecurity/actions/action.h index 4409660c64..f44b115819 100644 --- a/headers/modsecurity/actions/action.h +++ b/headers/modsecurity/actions/action.h @@ -16,14 +16,11 @@ #ifdef __cplusplus #include -#include -#include + +#include #endif -#include "modsecurity/intervention.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_with_actions.h" #ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #define HEADERS_MODSECURITY_ACTIONS_ACTION_H_ @@ -32,44 +29,59 @@ namespace modsecurity { class Transaction; -class RuleWithOperator; - namespace actions { class Action { public: - explicit Action(const std::string& _action) - : m_isNone(false), - temporaryAction(false), - action_kind(2), - m_name(nullptr), - m_parser_payload("") { - set_name_and_payload(_action); - } - explicit Action(const std::string& _action, int kind) - : m_isNone(false), - temporaryAction(false), - action_kind(kind), - m_name(nullptr), - m_parser_payload("") { - set_name_and_payload(_action); - } + Action() + : m_parserPayload(""), + m_name("") + { + assert(0); + } + + + explicit Action(const std::string& action) + : m_parserPayload(sort_payload(action)), + m_name(sort_name(action)) + { } - virtual ~Action() { } - virtual std::string evaluate(const std::string &exp, - Transaction *transaction); - virtual bool evaluate(RuleWithActions *rule, Transaction *transaction); - virtual bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr ruleMessage) { - return evaluate(rule, transaction); + Action(const Action &other) + : m_parserPayload(other.m_parserPayload), + m_name(other.m_name) + { } + + + Action &operator=(const Action& a) { + m_name = a.m_name; + m_parserPayload = a.m_parserPayload; + return *this; } - virtual bool init(std::string *error) { return true; } - virtual bool isDisruptive() { return false; } - void set_name_and_payload(const std::string& data) { + virtual ~Action() + { } + + + virtual bool init(std::string *error) { + return true; + } + + const std::string *getName() const noexcept { + return &m_name; + } + + + protected: + std::string m_parserPayload; + + + private: + std::string m_name; + + static size_t get_payload_pos(const std::string& data) { size_t pos = data.find(":"); std::string t = "t:"; @@ -77,58 +89,36 @@ class Action { pos = data.find(":", 2); } + return pos; + } + + + static std::string sort_name(const std::string& data) { + size_t pos = get_payload_pos(data); if (pos == std::string::npos) { - m_name = std::shared_ptr(new std::string(data)); - return; + return data; } - m_name = std::shared_ptr(new std::string(data, 0, pos)); - m_parser_payload = std::string(data, pos + 1, data.length()); + std::string ret(data, 0, pos); + return ret; + } + - if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) { - m_parser_payload.erase(0, 1); - m_parser_payload.pop_back(); + static std::string sort_payload(const std::string& data) { + size_t pos = get_payload_pos(data); + std::string ret(""); + if (pos != std::string::npos) { + ret = std::string(data, pos + 1, data.length()); + + if (ret.at(0) == '\'' && ret.size() > 2) { + ret.erase(0, 1); + ret.pop_back(); + } } - } - bool m_isNone; - bool temporaryAction; - int action_kind; - std::shared_ptr m_name; - std::string m_parser_payload; - - /** - * - * Define the action kind regarding to the execution time. - * - * - */ - enum Kind { - /** - * - * Action that are executed while loading the configuration. For instance - * the rule ID or the rule phase. - * - */ - ConfigurationKind, - /** - * - * Those are actions that demands to be executed before call the operator. - * For instance the tranformations. - * - * - */ - RunTimeBeforeMatchAttemptKind, - /** - * - * Actions that are executed after the execution of the operator, only if - * the operator returned Match (or True). For instance the disruptive - * actions. - * - */ - RunTimeOnlyIfMatchKind, - }; - }; + return ret; + } +}; } // namespace actions diff --git a/headers/modsecurity/anchored_set_variable.h b/headers/modsecurity/anchored_set_variable.h index 24d80cdac0..790cf4d819 100644 --- a/headers/modsecurity/anchored_set_variable.h +++ b/headers/modsecurity/anchored_set_variable.h @@ -27,10 +27,13 @@ #include #include #include + +#include "modsecurity/string_view.hpp" #endif #include "modsecurity/variable_value.h" + #ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_ #define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_ @@ -69,33 +72,38 @@ struct MyHash{ class AnchoredSetVariable : public std::unordered_multimap { + std::shared_ptr, MyHash, MyEqual> { public: AnchoredSetVariable(Transaction *t, const std::string &name); - ~AnchoredSetVariable(); void unset(); void set(const std::string &key, const std::string &value, size_t offset); + void set(const std::string &key, const bpstd::string_view &value, + size_t offset); + + void set(const std::string &key, const char *value, + size_t offset); + void set(const std::string &key, const std::string &value, size_t offset, size_t len); void setCopy(std::string key, std::string value, size_t offset); - void resolve(std::vector *l); - void resolve(std::vector *l, + void resolve(std::vector> *l); + void resolve(std::vector> *l, variables::KeyExclusions &ke); void resolve(const std::string &key, - std::vector *l); + std::vector> *l); void resolveRegularExpression(Utils::Regex *r, - std::vector *l); + std::vector> *l); void resolveRegularExpression(Utils::Regex *r, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke); std::unique_ptr resolveFirst(const std::string &key); diff --git a/headers/modsecurity/anchored_variable.h b/headers/modsecurity/anchored_variable.h index aa71b56069..21cbb7bd8f 100644 --- a/headers/modsecurity/anchored_variable.h +++ b/headers/modsecurity/anchored_variable.h @@ -26,10 +26,14 @@ #include #include #include +#include + +#include "modsecurity/string_view.hpp" #endif #include "modsecurity/variable_value.h" + #ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_ #define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_ @@ -55,17 +59,17 @@ class AnchoredVariable { m_var(a.m_var) { } */ - ~AnchoredVariable(); - void unset(); void set(const std::string &a, size_t offset); + void set(const bpstd::string_view &a, size_t offset); + void set(const char *a, size_t offset); void set(const std::string &a, size_t offset, size_t offsetLen); void append(const std::string &a, size_t offset, bool spaceSeparator = false); void append(const std::string &a, size_t offset, bool spaceSeparator, int size); - void evaluate(std::vector *l); + void evaluate(std::vector> *l); std::string * evaluate(); std::unique_ptr resolveFirst(); @@ -75,7 +79,7 @@ class AnchoredVariable { std::string m_value; private: - VariableValue *m_var; + VariableValue m_var; }; } // namespace modsecurity diff --git a/headers/modsecurity/audit_log.h b/headers/modsecurity/audit_log.h index 08ffdbfeb0..1278ecd994 100644 --- a/headers/modsecurity/audit_log.h +++ b/headers/modsecurity/audit_log.h @@ -61,7 +61,7 @@ class AuditLog { NativeAuditLogFormat }; - enum AuditLogParts { + enum AuditLogPartsEnum { /** * Audit log header (mandatory). * @@ -170,9 +170,8 @@ class AuditLog { bool init(std::string *error); virtual bool close(); - bool saveIfRelevant(Transaction *transaction); - bool saveIfRelevant(Transaction *transaction, int parts); - bool isRelevant(int status); + bool saveIfRelevant(Transaction *transaction) const noexcept; + bool isRelevant(int status) const noexcept; static int addParts(int parts, const std::string& new_parts); static int removeParts(int parts, const std::string& new_parts); diff --git a/headers/modsecurity/collection/collection.h b/headers/modsecurity/collection/collection.h index db80e8e789..fbe4ec3d01 100644 --- a/headers/modsecurity/collection/collection.h +++ b/headers/modsecurity/collection/collection.h @@ -60,12 +60,12 @@ class Collection { const std::string& var) = 0; virtual void resolveSingleMatch(const std::string& var, - std::vector *l) = 0; + std::vector> *l) = 0; virtual void resolveMultiMatches(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) = 0; virtual void resolveRegularExpression(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) = 0; @@ -146,7 +146,7 @@ class Collection { /* resolveSingleMatch */ virtual void resolveSingleMatch(const std::string& var, - std::string compartment, std::vector *l) { + std::string compartment, std::vector> *l) { std::string nkey = compartment + "::" + var; resolveSingleMatch(nkey, l); } @@ -154,7 +154,7 @@ class Collection { virtual void resolveSingleMatch(const std::string& var, std::string compartment, std::string compartment2, - std::vector *l) { + std::vector> *l) { std::string nkey = compartment + "::" + compartment2 + "::" + var; resolveSingleMatch(nkey, l); } @@ -162,7 +162,7 @@ class Collection { /* resolveMultiMatches */ virtual void resolveMultiMatches(const std::string& var, - std::string compartment, std::vector *l, + std::string compartment, std::vector> *l, variables::KeyExclusions &ke) { std::string nkey = compartment + "::" + var; resolveMultiMatches(nkey, l, ke); @@ -171,7 +171,7 @@ class Collection { virtual void resolveMultiMatches(const std::string& var, std::string compartment, std::string compartment2, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) { std::string nkey = compartment + "::" + compartment2 + "::" + var; resolveMultiMatches(nkey, l, ke); @@ -180,7 +180,7 @@ class Collection { /* resolveRegularExpression */ virtual void resolveRegularExpression(const std::string& var, - std::string compartment, std::vector *l, + std::string compartment, std::vector> *l, variables::KeyExclusions &ke) { std::string nkey = compartment + "::" + var; resolveRegularExpression(nkey, l, ke); @@ -189,7 +189,7 @@ class Collection { virtual void resolveRegularExpression(const std::string& var, std::string compartment, std::string compartment2, - std::vector *l, variables::KeyExclusions &ke) { + std::vector> *l, variables::KeyExclusions &ke) { std::string nkey = compartment + "::" + compartment2 + "::" + var; resolveRegularExpression(nkey, l, ke); } diff --git a/headers/modsecurity/modsecurity.h b/headers/modsecurity/modsecurity.h index 83cdfd7e8f..54a3c3eac1 100644 --- a/headers/modsecurity/modsecurity.h +++ b/headers/modsecurity/modsecurity.h @@ -89,6 +89,14 @@ typedef struct ModSecurity_t modsecurity; #else namespace modsecurity { + /** + * Further that will be changed to be a stack-based string, + * for the benefit of performance. + */ + using ModSecString = std::string; + + using RuleId = int64_t; + /** * * The Phases enumerator consists in mapping the different stages of a @@ -292,7 +300,7 @@ class ModSecurity { */ void setServerLogCb(ModSecLogCb cb, int properties); - void serverLog(void *data, std::shared_ptr rm); + void serverLog(void *data, RuleMessage *rm); const std::string& getConnectorInformation() const; diff --git a/headers/modsecurity/rule.h b/headers/modsecurity/rule.h index a8426c61f4..77507f941f 100644 --- a/headers/modsecurity/rule.h +++ b/headers/modsecurity/rule.h @@ -29,6 +29,7 @@ #include "modsecurity/modsecurity.h" #include "modsecurity/variable_value.h" + #ifdef __cplusplus namespace modsecurity { @@ -36,47 +37,33 @@ namespace variables { class Variable; class Variables; } -namespace actions { -class Action; -class Severity; -class LogData; -class Msg; -class Rev; -class SetVar; -class Tag; -namespace transformations { -class Transformation; -} -} namespace operators { class Operator; } -using TransformationResult = std::pair, - std::shared_ptr>; -using TransformationResults = std::list; - -using Transformation = actions::transformations::Transformation; -using Transformations = std::vector; - -using Actions = std::vector; - -using Tags = std::vector; -using SetVars = std::vector; -using MatchActions = std::vector; class Rule { public: Rule(std::unique_ptr fileName, int lineNumber) : m_fileName(std::move(fileName)), m_lineNumber(lineNumber), - m_phase(modsecurity::Phases::RequestHeadersPhase) { - } - - virtual bool evaluate(Transaction *transaction) = 0; + m_phase(modsecurity::Phases::RequestHeadersPhase) + { } + + Rule(const Rule &r) + : m_fileName(r.m_fileName), + m_lineNumber(r.m_lineNumber), + m_phase(r.m_phase) + { } + + Rule &operator=(const Rule& other) { + m_fileName = other.m_fileName; + m_lineNumber = other.m_lineNumber; + m_phase = other.m_phase; + return *this; + } - virtual bool evaluate(Transaction *transaction, - std::shared_ptr rm) = 0; + virtual bool evaluate(Transaction *transaction) const = 0; std::shared_ptr getFileName() const { return m_fileName; @@ -89,12 +76,21 @@ class Rule { int getPhase() const { return m_phase; } void setPhase(int phase) { m_phase = phase; } - virtual std::string getReference() { + virtual std::string getReference() const { return *m_fileName + ":" + std::to_string(m_lineNumber); } + virtual void dump(std::stringstream &out) const { + out << getOriginInTextFormat() << std::endl; + } - virtual bool isMarker() { return false; } + protected: + std::string getOriginInTextFormat() const { + std::stringstream ss; + ss << "# File name: " << *getFileName() << std::endl; + ss << "# Line number: " << getLineNumber(); + return ss.str(); + } private: std::shared_ptr m_fileName; diff --git a/headers/modsecurity/rule_message.h b/headers/modsecurity/rule_message.h index b7f2306069..3dfdec17bd 100644 --- a/headers/modsecurity/rule_message.h +++ b/headers/modsecurity/rule_message.h @@ -26,14 +26,15 @@ #include "modsecurity/transaction.h" #include "modsecurity/rule.h" -#include "modsecurity/rule_with_operator.h" #ifdef __cplusplus namespace modsecurity { - - +namespace actions { +class Tag; +}; +class RuleWithActions; class RuleMessage { public: @@ -42,67 +43,49 @@ class RuleMessage { ClientLogMessageInfo = 4 }; - /** - * - * FIXME: RuleMessage is currently too big, doing a lot of - * unnecessary data duplication. Needs to be shrink down. - * - */ - RuleMessage(RuleWithActions *rule, Transaction *trans) : - m_accuracy(rule->m_accuracy), - m_clientIpAddress(trans->m_clientIpAddress), + + explicit RuleMessage(const RuleMessage &ruleMessage) : + m_severity(ruleMessage.m_severity), + m_tags(), + m_data(ruleMessage.m_data), + m_match(ruleMessage.m_match), + m_message(ruleMessage.m_message), + m_reference(ruleMessage.m_reference), + m_transaction(ruleMessage.m_transaction), + m_rule(ruleMessage.m_rule) + { } + + + RuleMessage &operator=(const RuleMessage& ruleMessage) { + m_severity = ruleMessage.m_severity; + m_tags = ruleMessage.m_tags; + m_data = ruleMessage.m_data; + m_match = ruleMessage.m_match; + m_message = ruleMessage.m_message; + m_reference = ruleMessage.m_reference; + m_transaction = ruleMessage.m_transaction; + m_rule = ruleMessage.m_rule; + return *this; + } + + + explicit RuleMessage(Transaction *transaction) : + m_severity(0), + m_tags(), m_data(""), - m_id(trans->m_id), - m_isDisruptive(false), m_match(""), - m_maturity(rule->m_maturity), m_message(""), - m_noAuditLog(false), - m_phase(rule->getPhase() - 1), m_reference(""), - m_rev(rule->m_rev), - m_rule(rule), - m_ruleFile(rule->getFileName()), - m_ruleId(rule->m_ruleId), - m_ruleLine(rule->getLineNumber()), - m_saveMessage(true), - m_serverIpAddress(trans->m_serverIpAddress), - m_severity(0), - m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded), - m_ver(rule->m_ver) + m_transaction(transaction), + m_rule(nullptr) { } - explicit RuleMessage(RuleMessage *rule) : - m_accuracy(rule->m_accuracy), - m_clientIpAddress(rule->m_clientIpAddress), - m_data(rule->m_data), - m_id(rule->m_id), - m_isDisruptive(rule->m_isDisruptive), - m_match(rule->m_match), - m_maturity(rule->m_maturity), - m_message(rule->m_message), - m_noAuditLog(rule->m_noAuditLog), - m_phase(rule->m_phase), - m_reference(rule->m_reference), - m_rev(rule->m_rev), - m_rule(rule->m_rule), - m_ruleFile(rule->m_ruleFile), - m_ruleId(rule->m_ruleId), - m_ruleLine(rule->m_ruleLine), - m_saveMessage(rule->m_saveMessage), - m_serverIpAddress(rule->m_serverIpAddress), - m_severity(rule->m_severity), - m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded), - m_ver(rule->m_ver) - { } void clean() { m_data = ""; m_match = ""; - m_isDisruptive = false; m_reference = ""; m_severity = 0; - m_ver = ""; } std::string log() { @@ -130,29 +113,38 @@ class RuleMessage { static std::string _details(const RuleMessage *rm); static std::string _errorLogTail(const RuleMessage *rm); - int m_accuracy; - std::shared_ptr m_clientIpAddress; + const RuleWithActions *getRule() const; + void setRule(const RuleWithActions *rule); + bool isSettle() const; + int getRuleId() const; + int getPhase() const; + std::string getFileName() const; + int getLineNumber() const; + std::string getRev() const; + std::string getVer() const; + int getMaturity() const; + int getAccuracy() const; + std::string getClientIpAddress() const; + std::string getServerIpAddress() const; + std::string getRequestId() const; + std::string getUri() const; + bool isDisruptive() const; + + bool toBeAuditLog() const; + + int m_severity; + std::list m_tags; + + // Transaction std::string m_data; - std::shared_ptr m_id; - bool m_isDisruptive; std::string m_match; - int m_maturity; + std::string m_message; - bool m_noAuditLog; - int m_phase; std::string m_reference; - std::string m_rev; - RuleWithActions *m_rule; - std::shared_ptr m_ruleFile; - int m_ruleId; - int m_ruleLine; - bool m_saveMessage; - std::shared_ptr m_serverIpAddress; - int m_severity; - std::shared_ptr m_uriNoQueryStringDecoded; - std::string m_ver; - std::list m_tags; + private: + Transaction *m_transaction; + const RuleWithActions *m_rule; }; diff --git a/headers/modsecurity/rule_with_actions.h b/headers/modsecurity/rule_with_actions.h deleted file mode 100644 index 340048382e..0000000000 --- a/headers/modsecurity/rule_with_actions.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#endif - -#ifndef HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_ -#define HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_ - -#include "modsecurity/transaction.h" -#include "modsecurity/modsecurity.h" -#include "modsecurity/variable_value.h" -#include "modsecurity/rule.h" - -#ifdef __cplusplus - -namespace modsecurity { - - -class RuleWithActions : public Rule { - public: - RuleWithActions( - Actions *a, - Transformations *t, - std::unique_ptr fileName, - int lineNumber); - - ~RuleWithActions(); - - virtual bool evaluate(Transaction *transaction, std::shared_ptr ruleMessage) override; - - virtual bool evaluate(Transaction *transaction) override; - - - void executeActionsIndependentOfChainedRuleResult( - Transaction *trasn, - bool *containsDisruptive, - std::shared_ptr ruleMessage); - - void executeActionsAfterFullMatch( - Transaction *trasn, - bool containsDisruptive, - std::shared_ptr ruleMessage); - - void executeAction(Transaction *trans, - bool containsBlock, - std::shared_ptr ruleMessage, - actions::Action *a, - bool context); - - - void executeTransformations( - Transaction *trasn, const std::string &value, TransformationResults &ret); - - inline void executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, - Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const; - - - void performLogging(Transaction *trans, - std::shared_ptr ruleMessage, - bool lastLog = true, - bool chainedParentNull = false); - - std::vector getActionsByName(const std::string& name, - Transaction *t); - bool containsTag(const std::string& name, Transaction *t); - bool containsMsg(const std::string& name, Transaction *t); - - inline bool isChained() const { return m_isChained == true; } - inline bool hasCaptureAction() const { return m_containsCaptureAction == true; } - inline void setChained(bool b) { m_isChained = b; } - inline bool hasDisruptiveAction() const { return m_disruptiveAction != NULL; } - inline bool hasBlockAction() const { return m_containsStaticBlockAction == true; } - inline bool hasMultimatch() const { return m_containsMultiMatchAction == true; } - - inline bool hasLogData() const { return m_logData != NULL; } - std::string logData(Transaction *t); - inline bool hasMsg() const { return m_msg != NULL; } - std::string msg(Transaction *t); - inline bool hasSeverity() const { return m_severity != NULL; } - int severity() const; - - std::string m_rev; - std::string m_ver; - int m_accuracy; - int m_maturity; - - - int64_t m_ruleId; - - std::unique_ptr m_chainedRuleChild; - RuleWithActions *m_chainedRuleParent; - - private: - /* actions */ - actions::Action *m_disruptiveAction; - actions::LogData *m_logData; - actions::Msg *m_msg; - actions::Severity *m_severity; - MatchActions m_actionsRuntimePos; - SetVars m_actionsSetVar; - Tags m_actionsTag; - - /* actions > transformations */ - Transformations m_transformations; - - bool m_containsCaptureAction:1; - bool m_containsMultiMatchAction:1; - bool m_containsStaticBlockAction:1; - bool m_isChained:1; -}; - -} // namespace modsecurity -#endif - - -#endif // HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_ \ No newline at end of file diff --git a/headers/modsecurity/rule_with_operator.h b/headers/modsecurity/rule_with_operator.h deleted file mode 100644 index 63aff6c469..0000000000 --- a/headers/modsecurity/rule_with_operator.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. - * - */ - -#ifdef __cplusplus -#include -#include -#include -#include -#include -#include -#endif - -#ifndef HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_ -#define HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_ - -#include "modsecurity/transaction.h" -#include "modsecurity/modsecurity.h" -#include "modsecurity/variable_value.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_with_actions.h" - -#ifdef __cplusplus - -namespace modsecurity { - - -class RuleWithOperator : public RuleWithActions { - public: - RuleWithOperator(operators::Operator *op, - variables::Variables *variables, - std::vector *actions, - Transformations *transformations, - std::unique_ptr fileName, - int lineNumber); - - virtual ~RuleWithOperator(); - - bool evaluate(Transaction *transaction, - std::shared_ptr rm) override; - - void getVariablesExceptions(Transaction *t, - variables::Variables *exclusion, variables::Variables *addition); - inline void getFinalVars(variables::Variables *vars, - variables::Variables *eclusion, Transaction *trans); - - bool executeOperatorAt(Transaction *trasn, const std::string &key, - std::string value, std::shared_ptr rm); - - static void updateMatchedVars(Transaction *trasn, const std::string &key, - const std::string &value); - static void cleanMatchedVars(Transaction *trasn); - - - std::string getOperatorName() const; - - virtual std::string getReference() override { - return std::to_string(m_ruleId); - } - - private: - modsecurity::variables::Variables *m_variables; - operators::Operator *m_operator; -}; - - -} // namespace modsecurity -#endif - - -#endif // HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_ diff --git a/headers/modsecurity/rules.h b/headers/modsecurity/rules.h index afdd030c27..03be4e9bfe 100644 --- a/headers/modsecurity/rules.h +++ b/headers/modsecurity/rules.h @@ -27,64 +27,55 @@ #endif #include "modsecurity/rule.h" -#include "modsecurity/rule_with_operator.h" -#include "modsecurity/rule_with_actions.h" + #ifndef HEADERS_MODSECURITY_RULES_H_ #define HEADERS_MODSECURITY_RULES_H_ - #ifdef __cplusplus namespace modsecurity { +namespace actions { +namespace transformations { +class Transformation; +} +} +using RulesErrors = std::list>; +using RulesWarnings = std::list>; class Rules { public: - void dump() const { - for (int j = 0; j < m_rules.size(); j++) { - std::cout << " Rule ID: " << m_rules.at(j)->getReference(); - std::cout << "--" << m_rules.at(j) << std::endl; - } - } - - int append(Rules *from, const std::vector &ids, std::ostringstream *err) { - size_t j = 0; - for (; j < from->size(); j++) { - RuleWithOperator *rule = dynamic_cast(from->at(j).get()); - if (rule && std::binary_search(ids.begin(), ids.end(), rule->m_ruleId)) { - if (err != NULL) { - *err << "Rule id: " << std::to_string(rule->m_ruleId) \ - << " is duplicated" << std::endl; - } - return -1; - } - } - m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end()); - return j; - } - - bool insert(std::shared_ptr rule) { - return insert(rule, nullptr, nullptr); - } - - bool insert(std::shared_ptr rule, const std::vector *ids, std::ostringstream *err) { - RuleWithOperator *r = dynamic_cast(rule.get()); - if (r && ids != nullptr && std::binary_search(ids->begin(), ids->end(), r->m_ruleId)) { - if (err != nullptr) { - *err << "Rule id: " << std::to_string(r->m_ruleId) \ - << " is duplicated" << std::endl; - } - return false; - } - m_rules.push_back(rule); - return true; - } - - size_t size() const { return m_rules.size(); } - std::shared_ptr operator[](int index) const { return m_rules[index]; } - std::shared_ptr at(int index) const { return m_rules[index]; } - - std::vector > m_rules; + using container=std::vector>; + using iterator=typename container::iterator; + using const_iterator=typename container::const_iterator; + + int append(Rules *from); + + bool insert(const std::shared_ptr &rule); + + size_t size() const; + + std::shared_ptr operator[](int index) const; + std::shared_ptr at(int index) const; + + void fixDefaultActions(RulesWarnings *warnings, RulesErrors *errors); + + std::vector > m_defaultActions; + std::vector > m_defaultTransformations; + + virtual void dump() { + std::stringstream ss; + dump(ss); + std::cout << ss.str(); + }; + virtual void dump(std::stringstream &out); + + inline iterator begin() noexcept { return m_rules.begin(); } + inline const_iterator cbegin() const noexcept { return m_rules.cbegin(); } + inline iterator end() noexcept { return m_rules.end(); } + inline const_iterator cend() const noexcept { return m_rules.cend(); } + private: + container m_rules; }; diff --git a/headers/modsecurity/rules_exceptions.h b/headers/modsecurity/rules_exceptions.h index a8bcf17392..ec3a552df2 100644 --- a/headers/modsecurity/rules_exceptions.h +++ b/headers/modsecurity/rules_exceptions.h @@ -37,6 +37,9 @@ namespace modsecurity { namespace actions { class Action; +namespace transformations { +class Transformation; +} } namespace variables { class Variable; @@ -79,7 +82,7 @@ class RulesExceptions { std::unordered_multimap> m_variable_update_target_by_id; std::unordered_multimap> m_action_pre_update_target_by_id; + std::shared_ptr> m_action_transformation_update_target_by_id; std::unordered_multimap> m_action_pos_update_target_by_id; std::list m_remove_rule_by_msg; diff --git a/headers/modsecurity/rules_set.h b/headers/modsecurity/rules_set.h index e587033324..7732415512 100644 --- a/headers/modsecurity/rules_set.h +++ b/headers/modsecurity/rules_set.h @@ -22,6 +22,7 @@ #include #include #include +#include #endif @@ -42,8 +43,6 @@ namespace Parser { class Driver; } - - /** @ingroup ModSecurity_CPP_API */ class RulesSet : public RulesSetProperties { public: @@ -68,12 +67,13 @@ class RulesSet : public RulesSetProperties { int load(const char *rules); int load(const char *rules, const std::string &ref); - void dump() const; + void dump(); int merge(Parser::Driver *driver); int merge(RulesSet *rules); int evaluate(int phase, Transaction *transaction); + std::string getParserError(); void debug(int level, const std::string &id, const std::string &uri, @@ -81,6 +81,7 @@ class RulesSet : public RulesSetProperties { RulesSetPhases m_rulesSetPhases; private: + bool containsDuplicatedIds(RulesWarnings *warnings, RulesErrors *errors); #ifndef NO_LOGS uint8_t m_secmarker_skipped; #endif diff --git a/headers/modsecurity/rules_set_phases.h b/headers/modsecurity/rules_set_phases.h index 59d3fdf3da..2b9b67c937 100644 --- a/headers/modsecurity/rules_set_phases.h +++ b/headers/modsecurity/rules_set_phases.h @@ -23,6 +23,7 @@ #include #include #include +#include #endif @@ -42,18 +43,33 @@ class Driver; /** @ingroup ModSecurity_CPP_API */ class RulesSetPhases { public: + using container = std::array; + using iterator = typename container::iterator; + using const_iterator = typename container::const_iterator; - bool insert(std::shared_ptr rule); + void insert(std::shared_ptr rule); + void append(RulesSetPhases *from); int append(RulesSetPhases *from, std::ostringstream *err); - void dump() const; + void dump(); - Rules *operator[](int index) { return &m_rulesAtPhase[index]; } - Rules *at(int index) { return &m_rulesAtPhase[index]; } + Rules *operator[](int index); + Rules *at(int index); + static size_t size() { return modsecurity::Phases::NUMBER_OF_PHASES; } - private: - Rules m_rulesAtPhase[8]; + void fixDefaultActions(RulesWarnings *warnings, RulesErrors *errors) { + for (auto &phase : m_rulesAtPhase) { + phase.fixDefaultActions(warnings, errors); + } + } + + inline iterator begin() noexcept { return m_rulesAtPhase.begin(); } + inline const_iterator cbegin() const noexcept { return m_rulesAtPhase.cbegin(); } + inline iterator end() noexcept { return m_rulesAtPhase.end(); } + inline const_iterator cend() const noexcept { return m_rulesAtPhase.cend(); } + private: + container m_rulesAtPhase; }; diff --git a/headers/modsecurity/rules_set_properties.h b/headers/modsecurity/rules_set_properties.h index 6a6d4262a2..7fc4017843 100644 --- a/headers/modsecurity/rules_set_properties.h +++ b/headers/modsecurity/rules_set_properties.h @@ -201,16 +201,6 @@ class RulesSetProperties { RulesSetProperties &operator =(const RulesSetProperties &r) = delete; ~RulesSetProperties() { - int i = 0; - - for (i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector > *tmp = \ - &m_defaultActions[i]; - while (tmp->empty() == false) { - tmp->pop_back(); - } - } - delete m_debugLog; delete m_auditLog; } @@ -410,16 +400,6 @@ class RulesSetProperties { to->m_responseBodyTypeToBeInspected.m_set = true; } - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector > *actions_from = \ - &from->m_defaultActions[i]; - std::vector > *actions_to = \ - &to->m_defaultActions[i]; - for (size_t j = 0; j < actions_from->size(); j++) { - actions_to->push_back(actions_from->at(j)); - } - } - if (to->m_auditLog) { std::string error; to->m_auditLog->merge(from->m_auditLog, &error); @@ -481,8 +461,6 @@ class RulesSetProperties { ConfigString m_uploadTmpDirectory; ConfigString m_secArgumentSeparator; ConfigString m_secWebAppId; - std::vector > \ - m_defaultActions[modsecurity::Phases::NUMBER_OF_PHASES]; ConfigUnicodeMap m_unicodeMapTable; }; diff --git a/headers/modsecurity/string_view.hpp b/headers/modsecurity/string_view.hpp new file mode 100644 index 0000000000..ce9929534b --- /dev/null +++ b/headers/modsecurity/string_view.hpp @@ -0,0 +1,1422 @@ +/** + * \file string_view.hpp + * + * \brief This header contains the definition of the string_view type, as + * described by the C++17 standard. + * + * \author Matthew Rodusek (matthew.rodusek@gmail.com) + * \copyright Matthew Rodusek + */ + +/* + * The MIT License (MIT) + * + * Licensed under the MIT License . + * Copyright (c) 2016 Matthew Rodusek + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef BPSTD_STRING_VIEW_HPP +#define BPSTD_STRING_VIEW_HPP + +#include // std:: +#include // std::char_traits +#include // std::basic_ostream +#include // std::size_t +#include // std::allocator +#include // std::out_of_range +#include // std::reverse_iterator +namespace bpstd { // back-port std + + //////////////////////////////////////////////////////////////////////////// + /// \brief A wrapper around non-owned strings. + /// + /// This is an implementation of the C++17 string_view proposal + /// + /// \ingroup core + //////////////////////////////////////////////////////////////////////////// + template< + typename CharT, + typename Traits = std::char_traits + > + class basic_string_view final + { + //------------------------------------------------------------------------ + // Public Member Types + //------------------------------------------------------------------------ + public: + + using char_type = CharT; + using traits_type = Traits; + using size_type = std::size_t; + + using value_type = CharT; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + + using iterator = const CharT*; + using const_iterator = const CharT*; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + //------------------------------------------------------------------------ + // Public Members + //------------------------------------------------------------------------ + public: + + static constexpr size_type npos = size_type(-1); + + //------------------------------------------------------------------------ + // Constructors + //------------------------------------------------------------------------ + public: + + /// \brief Default constructs a basic_string_view without any content + constexpr basic_string_view() noexcept; + + /// \brief Constructs a basic_string_view by copying another one + /// + /// \param other the string view being copied + constexpr basic_string_view(const basic_string_view& other) noexcept = default; + + /// \brief Constructs a basic_string_view by moving anothe rone + /// + /// \param other the string view being moved + constexpr basic_string_view(basic_string_view&& other) noexcept = default; + + /// \brief Constructs a basic_string_view from a std::basic_string + /// + /// \param str the string to view + template + basic_string_view(const std::basic_string& str) noexcept; + + /// \brief Constructs a basic_string_view from an ansi-string + /// + /// \param str the string to view + constexpr basic_string_view(const char_type* str) noexcept; + + /// \brief Constructs a basic_string_view from an ansi string of a given size + /// + /// \param str the string to view + /// \param count the size of the string + constexpr basic_string_view(const char_type* str, size_type count) noexcept; + + //------------------------------------------------------------------------ + // Assignment + //------------------------------------------------------------------------ + public: + + /// \brief Assigns a basic_string_view from an ansi-string + /// + /// \param view the string to view + /// \return reference to \c (*this) + basic_string_view& operator=(const basic_string_view& view) = default; + + //------------------------------------------------------------------------ + // Capacity + //------------------------------------------------------------------------ + public: + + /// \brief Returns the length of the string, in terms of bytes + /// + /// \return the length of the string, in terms of bytes + constexpr size_type size() const noexcept; + + /// \copydoc basic_string_view::size + constexpr size_type length() const noexcept; + + /// \brief The largest possible number of char-like objects that can be + /// referred to by a basic_string_view. + /// \return Maximum number of characters + constexpr size_type max_size() const noexcept; + + /// \brief Returns whether the basic_string_view is empty + /// (i.e. whether its length is 0). + /// + /// \return whether the basic_string_view is empty + constexpr bool empty() const noexcept; + + //------------------------------------------------------------------------ + // Element Access + //------------------------------------------------------------------------ + public: + + /// \brief Gets the ansi-string of the current basic_string_view + /// + /// \return the ansi-string pointer + constexpr const char_type* c_str() const noexcept; + + /// \brief Gets the data of the current basic_string_view + /// + /// \note This is an alias of #c_str + /// + /// \return the data this basic_string_view contains + constexpr const char_type* data() const noexcept; + + /// \brief Accesses the element at index \p pos + /// + /// \param pos the index to access + /// \return const reference to the character + constexpr const_reference operator[](size_type pos) const noexcept; + + /// \brief Accesses the element at index \p pos + /// + /// \param pos the index to access + /// \return const reference to the character + constexpr const_reference at(size_type pos) const; + + /// \brief Access the first character of the string + /// + /// \note Undefined behavior if basic_string_view is empty + /// + /// \return reference to the first character of the string + constexpr const_reference front() const noexcept; + + /// \brief References the last character of the string + /// + /// \note Undefined behavior if basic_string_view is empty + /// + /// \return reference to the last character of the string + constexpr const_reference back() const noexcept; + + //------------------------------------------------------------------------ + // Modifiers + //------------------------------------------------------------------------ + public: + + /// \brief Moves the start of the view forward by n characters. + /// + /// The behavior is undefined if n > size(). + /// + /// \param n number of characters to remove from the start of the view + void remove_prefix(size_type n) noexcept; + + /// \brief Moves the end of the view back by n characters. + /// + /// The behavior is undefined if n > size(). + /// + /// \param n number of characters to remove from the end of the view + void remove_suffix(size_type n) noexcept; + + /// \brief Exchanges the view with that of v. + /// + /// \param v view to swap with + void swap(basic_string_view& v) noexcept; + + //------------------------------------------------------------------------ + // Conversions + //------------------------------------------------------------------------ + public: + + /// \brief Creates a basic_string with a copy of the content of the current view. + /// + /// \tparam Allocator type used to allocate internal storage + /// \param a Allocator instance to use for allocating the new string + /// + /// \return A basic_string containing a copy of the characters of the current view. + template> + constexpr std::basic_string + to_string(const Allocator& a = Allocator()) const; + + /// \copydoc basic_string_view::to_string + template + explicit constexpr operator std::basic_string() const; + + //------------------------------------------------------------------------ + // Operations + //------------------------------------------------------------------------ + public: + + /// \brief Copies the substring [pos, pos + rcount) to the character string pointed + /// to by dest, where rcount is the smaller of count and size() - pos. + /// + /// \param dest pointer to the destination character string + /// \param count requested substring length + /// \param pos position of the first character + size_type copy( char_type* dest, + size_type count = npos, + size_type pos = 0 ) const; + + /// \brief Returns a substring of this viewed string + /// + /// \param pos the position of the first character in the substring + /// \param len the length of the substring + /// \return the created substring + basic_string_view substr(size_t pos = 0, size_t len = npos) const; + + //------------------------------------------------------------------------ + + /// \brief Compares two character sequences + /// + /// \param v view to compare + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare(basic_string_view v) const noexcept; + + /// \brief Compares two character sequences + /// + /// \param pos position of the first character in this view to compare + /// \param count number of characters of this view to compare + /// \param v view to compare + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare(size_type pos, size_type count, basic_string_view v) const; + + /// \brief Compares two character sequences + /// + /// \param pos1 position of the first character in this view to compare + /// \param count1 number of characters of this view to compare + /// \param v view to compare + /// \param pos2 position of the second character in this view to compare + /// \param count2 number of characters of the given view to compare + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare( size_type pos1, size_type count1, basic_string_view v, + size_type pos2, size_type count2 ) const; + + /// \brief Compares two character sequences + /// + /// \param s pointer to the character string to compare to + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare(const char_type* s) const; + + /// \brief Compares two character sequences + /// + /// \param pos position of the first character in this view to compare + /// \param count number of characters of this view to compare + /// \param s pointer to the character string to compare to + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare(size_type pos, size_type count, const char_type* s) const; + + /// \brief Compares two character sequences + /// + /// \param pos position of the first character in this view to compare + /// \param count1 number of characters of this view to compare + /// \param s pointer to the character string to compare to + /// \param count2 number of characters of the given view to compare + /// \return negative value if this view is less than the other character + /// sequence, zero if the both character sequences are equal, positive + /// value if this view is greater than the other character sequence. + int compare( size_type pos, size_type count1, const char_type* s, + size_type count2 ) const; + + //------------------------------------------------------------------------ + + size_type find(basic_string_view v, size_type pos = 0) const; + + size_type find(char_type c, size_type pos = 0) const; + + size_type find(const char_type* s, size_type pos, size_type count) const; + + size_type find(const char_type* s, size_type pos = 0) const; + + //------------------------------------------------------------------------ + + size_type rfind(basic_string_view v, size_type pos = npos) const; + + size_type rfind(char_type c, size_type pos = npos) const; + + size_type rfind(const char_type* s, size_type pos, size_type count) const; + + size_type rfind(const char_type* s, size_type pos = npos) const; + + //------------------------------------------------------------------------ + + size_type find_first_of(basic_string_view v, size_type pos = 0) const; + + size_type find_first_of(char_type c, size_type pos = 0) const; + + size_type find_first_of(const char_type* s, size_type pos, size_type count) const; + + size_type find_first_of(const char_type* s, size_type pos = 0) const; + + //------------------------------------------------------------------------ + + size_type find_last_of(basic_string_view v, size_type pos = npos) const; + + size_type find_last_of(char_type c, size_type pos = npos) const; + + size_type find_last_of(const char_type* s, size_type pos, size_type count) const; + + size_type find_last_of(const char_type* s, size_type pos = npos) const; + + //------------------------------------------------------------------------ + + size_type find_first_not_of(basic_string_view v, size_type pos = 0) const; + + size_type find_first_not_of(char_type c, size_type pos = 0) const; + + size_type find_first_not_of(const char_type* s, size_type pos, size_type count) const; + + size_type find_first_not_of(const char_type* s, size_type pos = 0) const; + + //------------------------------------------------------------------------ + + size_type find_last_not_of(basic_string_view v, size_type pos = npos) const; + + size_type find_last_not_of(char_type c, size_type pos = npos) const; + + size_type find_last_not_of(const char_type* s, size_type pos, size_type count) const; + + size_type find_last_not_of(const char_type* s, size_type pos = npos) const; + + //------------------------------------------------------------------------ + // Iterators + //------------------------------------------------------------------------ + public: + + /// \{ + /// \brief Retrieves the begin iterator for this basic_string_view + /// + /// \return the begin iterator + const_iterator begin() const noexcept; + const_iterator cbegin() const noexcept; + /// \} + + /// \{ + /// \brief Retrieves the end iterator for this basic_string_view + /// + /// \return the end iterator + const_iterator end() const noexcept; + const_iterator cend() const noexcept; + /// \} + + /// \{ + /// \brief Retrieves the reverse begin iterator for this basic_string_view + /// + /// \return the reverse begin iterator + const_reverse_iterator rbegin() const noexcept; + const_reverse_iterator rend() const noexcept; + /// \} + + /// \{ + /// \brief Retrieves the reverse end iterator for this basic_string_view + /// + /// \return the reverse end iterator + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; + /// \} + + //------------------------------------------------------------------------ + // Private Member + //------------------------------------------------------------------------ + private: + + const char_type* m_str; ///< The internal string type + size_type m_size; ///< The size of this string + + /// \brief Checks whether \p c is one of the characters in \p str + /// + /// \param c the character to check + /// \param str the characters to compare against + /// \return true if \p c is one of the characters in \p str + static bool is_one_of(CharT c, basic_string_view str); + }; + + template + const typename basic_string_view::size_type + basic_string_view::npos; + + //-------------------------------------------------------------------------- + // Public Functions + //-------------------------------------------------------------------------- + + /// \brief Overload for ostream output of basic_string_view + /// + /// \param o The output stream to print to + /// \param str the string to print + /// \return reference to the output stream + template + std::basic_ostream& operator<<(std::basic_ostream& o, + const basic_string_view& str); + + template + void swap(basic_string_view& lhs, + basic_string_view& rhs) noexcept; + + //-------------------------------------------------------------------------- + // Comparison Functions + //-------------------------------------------------------------------------- + + template + bool operator==(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + template + bool operator!=(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + template + bool operator<(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + template + bool operator>(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + template + bool operator<=(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + template + bool operator>=(const basic_string_view& lhs, + const basic_string_view& rhs) noexcept; + + //-------------------------------------------------------------------------- + // Type Aliases + //-------------------------------------------------------------------------- + + using string_view = basic_string_view; + using wstring_view = basic_string_view; + using u16string_view = basic_string_view; + using u32string_view = basic_string_view; + +} // namespace bpstd + +#ifndef BPSTD_DETAIL_STRING_VIEW_INL +#define BPSTD_DETAIL_STRING_VIEW_INL + +namespace bpstd { + + //-------------------------------------------------------------------------- + // Constructor + //-------------------------------------------------------------------------- + + template + inline constexpr basic_string_view::basic_string_view() + noexcept + : m_str(nullptr), + m_size(0) + { + + } + + template + template + inline basic_string_view::basic_string_view(const std::basic_string& str) + noexcept + : m_str(str.c_str()), + m_size(str.size()) + { + + } + + template + inline constexpr basic_string_view::basic_string_view(const char_type* str) + noexcept + : m_str(str), + m_size(traits_type::length(str)) + { + + } + + template + inline constexpr basic_string_view::basic_string_view(const char_type* str, size_type count) + noexcept + : m_str(str), + m_size(count) + { + + } + + //-------------------------------------------------------------------------- + // Capacity + //-------------------------------------------------------------------------- + + template + inline constexpr typename basic_string_view::size_type + basic_string_view::size() + const noexcept + { + return m_size; + } + + template + inline constexpr typename basic_string_view::size_type + basic_string_view::length() + const noexcept + { + return size(); + } + + template + inline constexpr typename basic_string_view::size_type + basic_string_view::max_size() + const noexcept + { + return npos - 1; + } + + template + inline constexpr bool basic_string_view::empty() + const noexcept + { + return m_size == 0; + } + + //-------------------------------------------------------------------------- + // Element Access + //-------------------------------------------------------------------------- + + template + inline constexpr const typename basic_string_view::char_type* + basic_string_view::c_str() + const noexcept + { + return m_str; + } + + template + inline constexpr const typename basic_string_view::char_type* + basic_string_view::data() + const noexcept + { + return m_str; + } + + template + inline constexpr typename basic_string_view::const_reference + basic_string_view::operator[](size_type pos) + const noexcept + { + return m_str[pos]; + } + + template + inline constexpr typename basic_string_view::const_reference + basic_string_view::at(size_type pos) + const + { + return pos < m_size ? m_str[pos] : throw std::out_of_range("Input out of range in basic_string_view::at"), m_str[pos]; + } + + template + inline constexpr typename basic_string_view::const_reference + basic_string_view::front( ) + const noexcept + { + return *m_str; + } + + template + inline constexpr typename basic_string_view::const_reference + basic_string_view::back( ) + const noexcept + { + return m_str[m_size-1]; + } + + //-------------------------------------------------------------------------- + // Modifiers + //-------------------------------------------------------------------------- + + template + inline void + basic_string_view::remove_prefix(size_type n) + noexcept + { + m_str += n, m_size -= n; + } + + template + inline void + basic_string_view::remove_suffix(size_type n) + noexcept + { + m_size -= n; + } + + template + inline void + basic_string_view::swap(basic_string_view& v) + noexcept + { + using std::swap; + swap(m_size,v.m_size); + swap(m_str,v.m_str); + } + + //-------------------------------------------------------------------------- + // Conversions + //-------------------------------------------------------------------------- + + template + template + inline constexpr std::basic_string + basic_string_view::to_string(const Allocator& a) + const + { + return std::basic_string(m_str, m_size, a); + } + + template + template + inline constexpr basic_string_view::operator + std::basic_string() + const + { + return std::basic_string(m_str, m_size); + } + + //-------------------------------------------------------------------------- + // String Operations + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::copy(char_type* dest, + size_type count, + size_type pos) + const + { + if(pos >= m_size) { + throw std::out_of_range("Index out of range in basic_string_view::copy"); + } + + const size_type rcount = std::min(m_size - pos,count+1); + std::copy( m_str + pos, m_str + pos + rcount, dest); + return rcount; + } + + template + inline basic_string_view + basic_string_view::substr(size_type pos, + size_type len) + const + { + const size_type max_length = pos > m_size ? 0 : m_size - pos; + + if (pos > size()) { + throw std::out_of_range("Index out of range in basic_string_view::substr"); + } + + return basic_string_view(m_str + pos, std::min(len, max_length) ); + } + + //-------------------------------------------------------------------------- + + template + inline int basic_string_view::compare(basic_string_view v) + const noexcept + { + const size_type rlen = std::min(m_size,v.m_size); + const int compare = Traits::compare(m_str,v.m_str,rlen); + + return (compare ? compare : (m_size < v.m_size ? -1 : (m_size > v.m_size ? 1 : 0))); + } + + template + inline int basic_string_view::compare(size_type pos, + size_type count, + basic_string_view v) + const + { + return substr(pos,count).compare(v); + } + + template + inline int basic_string_view::compare(size_type pos1, + size_type count1, + basic_string_view v, + size_type pos2, + size_type count2) + const + { + return substr(pos1,count1).compare(v.substr(pos2,count2)); + } + + template + inline int basic_string_view::compare(const char_type* s) + const + { + return compare(basic_string_view(s)); + } + + template + inline int basic_string_view::compare(size_type pos, + size_type count, + const char_type* s) + const + { + return substr(pos, count).compare(basic_string_view(s)); + } + + template + inline int basic_string_view::compare(size_type pos, + size_type count1, + const char_type* s, + size_type count2) + const + { + return substr(pos, count1).compare(basic_string_view(s, count2)); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::find(basic_string_view v, + size_type pos) + const + { + // Can't find a substring if the substring is bigger than this + if (pos > size()) { + return npos; + } + if ((pos + v.size()) > size()) { + return npos; + } + + const auto offset = pos; + const auto increments = size() - v.size(); + + for (auto i = 0u; i <= increments; ++i) { + const auto j = i + offset; + if (substr(j, v.size()) == v) { + return j; + } + } + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::find(char_type c, + size_type pos) + const + { + return find(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find(const char_type* s, size_type pos, + size_type count) + const + { + return find(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find(const char_type* s, + size_type pos) + const + { + return find(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::rfind(basic_string_view v, + size_type pos) + const + { + if (empty()) { + return v.empty() ? 0u : npos; + } + if (v.empty()) { + return std::min(size() - 1, pos); + } + if (v.size() > size()) { + return npos; + } + + auto i = std::min(pos, (size() - v.size())); + while (i != npos) { + if (substr(i, v.size()) == v) { + return i; + } + --i; + } + + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::rfind(char_type c, + size_type pos) + const + { + return rfind(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::rfind(const char_type* s, size_type pos, + size_type count) + const + { + return rfind(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::rfind(const char_type* s, + size_type pos) + const + { + return rfind(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_of(basic_string_view v, + size_type pos) + const + { + const auto max_index = size(); + for (auto i = pos; i < max_index; ++i) { + if (is_one_of(m_str[i],v)) { + return i; + } + } + + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_of(char_type c, + size_type pos) + const + { + return find_first_of(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_of(const char_type* s, size_type pos, + size_type count) + const + { + return find_first_of(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_of(const char_type* s, + size_type pos) + const + { + return find_first_of(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_of(basic_string_view v, + size_type pos) + const + { + if (empty()) { + return npos; + } + const auto max_index = std::min(size() - 1, pos); + for (auto i = 0u; i <= max_index; ++i) { + const auto j = max_index - i; + + if (is_one_of(m_str[j],v)) { + return j; + } + } + + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_of(char_type c, + size_type pos) + const + { + return find_last_of(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_of(const char_type* s, size_type pos, + size_type count) + const + { + return find_last_of(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_of(const char_type* s, + size_type pos) + const + { + return find_last_of(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_not_of(basic_string_view v, + size_type pos) + const + { + const auto max_index = size(); + for (auto i = pos; i < max_index; ++i) { + if (!is_one_of(m_str[i],v)) { + return i; + } + } + + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_not_of(char_type c, + size_type pos) + const + { + return find_first_not_of(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_not_of(const char_type* s, + size_type pos, + size_type count) + const + { + return find_first_not_of(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_first_not_of(const char_type* s, + size_type pos) + const + { + return find_first_not_of(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_not_of(basic_string_view v, + size_type pos) + const + { + if (empty()) { + return npos; + } + const auto max_index = std::min(size() - 1, pos); + for (auto i = 0u; i <= max_index; ++i) { + const auto j = max_index - i; + + if (!is_one_of(m_str[j],v)) { + return j; + } + } + + return npos; + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_not_of(char_type c, + size_type pos) + const + { + return find_last_not_of(basic_string_view(&c, 1), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_not_of(const char_type* s, + size_type pos, + size_type count) + const + { + return find_last_not_of(basic_string_view(s, count), pos); + } + + template + inline typename basic_string_view::size_type + basic_string_view::find_last_not_of(const char_type* s, + size_type pos) + const + { + return find_last_not_of(basic_string_view(s), pos); + } + + //-------------------------------------------------------------------------- + // Iterator + //-------------------------------------------------------------------------- + + template + inline typename basic_string_view::const_iterator + basic_string_view::begin() + const noexcept + { + return m_str; + } + + template + inline typename basic_string_view::const_iterator + basic_string_view::cbegin() + const noexcept + { + return begin(); + } + + template + inline typename basic_string_view::const_iterator + basic_string_view::end() + const noexcept + { + return m_str + m_size; + } + + template + inline typename basic_string_view::const_iterator + basic_string_view::cend() + const noexcept + { + return cend(); + } + + template + inline typename basic_string_view::const_reverse_iterator + basic_string_view::rbegin() + const noexcept + { + return const_reverse_iterator{end()}; + } + + template + inline typename basic_string_view::const_reverse_iterator + basic_string_view::crbegin() + const noexcept + { + return rbegin(); + } + + template + inline typename basic_string_view::const_reverse_iterator + basic_string_view::rend() + const noexcept + { + return const_reverse_iterator{begin()}; + } + + template + inline typename basic_string_view::const_reverse_iterator + basic_string_view::crend() + const noexcept + { + return crend(); + } + + template + inline bool basic_string_view::is_one_of(CharT c, + basic_string_view str) + { + for (auto s : str) { + if (c == s) { + return true; + } + } + return false; + } + + //-------------------------------------------------------------------------- + // Public Functions + //-------------------------------------------------------------------------- + + template + std::basic_ostream& operator<<(std::basic_ostream& o, + const basic_string_view& str) + { + o.write(str.data(),str.size()); + return o; + } + + template + inline void swap(basic_string_view& lhs, + basic_string_view& rhs) + noexcept + { + lhs.swap(rhs); + } + + //-------------------------------------------------------------------------- + // Comparison Functions + //-------------------------------------------------------------------------- + + template + inline bool operator==(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) == 0; + } + + template + inline bool operator==(basic_string_view lhs, + const CharT* rhs) + noexcept + { + return lhs == basic_string_view(rhs); + } + + template + inline bool operator==(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) == rhs; + } + + template + inline bool operator==(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) == rhs; + } + + template + inline bool operator==(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs == basic_string_view(rhs); + } + + //-------------------------------------------------------------------------- + + template + inline bool operator!=(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) != 0; + } + + template + inline bool operator!=(const basic_string_view& lhs, + const CharT* rhs) + noexcept + { + return lhs != basic_string_view(rhs); + } + + template + inline bool operator!=(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) != rhs; + } + + template + inline bool operator!=(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) != rhs; + } + + template + inline bool operator!=(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs != basic_string_view(rhs); + } + //-------------------------------------------------------------------------- + + template + inline bool operator<(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) < 0; + } + + template + inline bool operator<(const basic_string_view& lhs, + const CharT* rhs) + noexcept + { + return lhs < basic_string_view(rhs); + } + + template + inline bool operator<(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) < rhs; + } + + template + inline bool operator<(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) < rhs; + } + + template + inline bool operator<(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs < basic_string_view(rhs); + } + + //-------------------------------------------------------------------------- + + template + inline bool operator>(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) > 0; + } + + template + inline bool operator>(const basic_string_view& lhs, + const CharT* rhs) + noexcept + { + return lhs > basic_string_view(rhs); + } + + template + inline bool operator>(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) > rhs; + } + + template + inline bool operator>(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) > rhs; + } + + template + inline bool operator>(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs > basic_string_view(rhs); + } + + //-------------------------------------------------------------------------- + + template + inline bool operator<=(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) <= 0; + } + + template + inline bool operator<=(const basic_string_view& lhs, + const CharT* rhs) + noexcept + { + return lhs <= basic_string_view(rhs); + } + + template + inline bool operator<=(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) <= rhs; + } + + template + inline bool operator<=(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) <= rhs; + } + + template + inline bool operator<=(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs <= basic_string_view(rhs); + } + + //-------------------------------------------------------------------------- + + template + inline bool operator>=(const basic_string_view& lhs, + const basic_string_view& rhs) + noexcept + { + return lhs.compare(rhs) >= 0; + } + + template + inline bool operator>=(const basic_string_view& lhs, + const CharT* rhs) + noexcept + { + return lhs >= basic_string_view(rhs); + } + + template + inline bool operator>=(const CharT* lhs, + const basic_string_view& rhs) + noexcept + { + return basic_string_view(lhs) >= rhs; + } + + template + inline bool operator>=(const std::basic_string& lhs, + const basic_string_view& rhs) + { + return basic_string_view(lhs) >= rhs; + } + + template + inline bool operator>=(const basic_string_view& lhs, + const std::basic_string& rhs) + { + return lhs >= basic_string_view(rhs); + } + +} // namespace bpstd + +#endif /* BPSTD_DETAIL_STRING_VIEW_INL */ + +#endif /* BPSTD_STRING_VIEW_HPP */ diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index 2225c53217..4849c8fde5 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -48,6 +48,7 @@ typedef struct Rules_t RulesSet; #include "modsecurity/variable_value.h" #include "modsecurity/collection/collection.h" #include "modsecurity/variable_origin.h" +#include "modsecurity/actions/action.h" #ifndef NO_LOGS @@ -102,6 +103,7 @@ class ModSecurity; class Transaction; class RulesSet; class RuleMessage; +class RuleWithActions; namespace actions { class Action; namespace disruptive { @@ -308,7 +310,7 @@ class TransactionSecMarkerManagement { m_marker.reset(); } - void addMarker(std::shared_ptr name) { + void addMarker(const std::shared_ptr &name) { m_marker = name; } @@ -316,8 +318,39 @@ class TransactionSecMarkerManagement { std::shared_ptr m_marker; }; +class TransactionRuleMessageManagement { + public: + explicit TransactionRuleMessageManagement(Transaction *t) + : m_transaction(t) { + messageNew(); + }; + + RuleMessage *messageGetLast(); + void messageNew(); + + void logMatchLastRuleOnTheChain(const RuleWithActions *rule); + + std::list messageGetAll(); + + void messageClear() { + m_rulesMessages.clear(); + } + + private: + /** + * This variable holds all the messages asked to be save by the utilization + * of the actions: `log_data' and `msg'. These should be included on the + * auditlogs. + */ + std::list m_rulesMessages; + + Transaction *m_transaction; +}; + + /** @ingroup ModSecurity_CPP_API */ -class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement { +class Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement, \ + public TransactionRuleMessageManagement { public: Transaction(ModSecurity *transaction, RulesSet *rules, void *logCbData); Transaction(ModSecurity *transaction, RulesSet *rules, char *id, @@ -397,7 +430,7 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa #ifndef NO_LOGS void debug(int, std::string) const; #endif - void serverLog(std::shared_ptr rm); + void serverLog(RuleMessage *rm); int getRuleEngineState() const; @@ -519,19 +552,12 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa int m_requestBodyAccess; /** - * The list m_auditLogModifier contains modifications to the `auditlogs' - * for this specific request, those modifications can happens via the - * utilization of the action: `ctl:auditLogParts=' + * m_auditLogParts contains auditlog parts for this specific request, + * it also holds the modifications can happens via the utilization of + * the action: `ctl:auditLogParts=' * */ - std::list< std::pair > m_auditLogModifier; - - /** - * This variable holds all the messages asked to be save by the utilization - * of the actions: `log_data' and `msg'. These should be included on the - * auditlogs. - */ - std::list m_rulesMessages; + int m_auditLogParts; /** * Holds the request body, in case of any. diff --git a/headers/modsecurity/variable_origin.h b/headers/modsecurity/variable_origin.h index 88079a7fae..dce5e4ff24 100644 --- a/headers/modsecurity/variable_origin.h +++ b/headers/modsecurity/variable_origin.h @@ -37,7 +37,7 @@ class VariableOrigin { : m_length(0), m_offset(0) { } - std::string toText() { + std::string toText() const { std::string offset = std::to_string(m_offset); std::string len = std::to_string(m_length); return "v" + offset + "," + len; diff --git a/headers/modsecurity/variable_value.h b/headers/modsecurity/variable_value.h index a3e8f92474..8077bb5df2 100644 --- a/headers/modsecurity/variable_value.h +++ b/headers/modsecurity/variable_value.h @@ -37,7 +37,7 @@ namespace modsecurity { class Collection; class VariableValue { public: - using Origins = std::list>; + using Origins = std::vector; explicit VariableValue(const std::string *key, const std::string *value = nullptr) @@ -56,22 +56,6 @@ class VariableValue { m_value(*value) { } - explicit VariableValue(const VariableValue *o) : - m_collection(o->m_collection), - m_key(o->m_key), - m_keyWithCollection(o->m_keyWithCollection), - m_value(o->m_value) - { - for (auto &i : o->m_orign) { - std::unique_ptr origin(new VariableOrigin()); - origin->m_offset = i->m_offset; - origin->m_length = i->m_length; - m_orign.push_back(std::move(origin)); - } - } - - VariableValue(const VariableValue &v) = delete; - const std::string& getKey() const { return m_key; @@ -98,7 +82,7 @@ class VariableValue { } - void addOrigin(std::unique_ptr origin) { + void addOrigin(VariableOrigin origin) { m_orign.push_back(std::move(origin)); } diff --git a/src/Makefile.am b/src/Makefile.am index e6496ccc40..7722ca12f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,21 +42,19 @@ pkginclude_HEADERS = \ ../headers/modsecurity/intervention.h \ ../headers/modsecurity/modsecurity.h \ ../headers/modsecurity/rule.h \ - ../headers/modsecurity/rule_marker.h \ - ../headers/modsecurity/rule_unconditional.h \ - ../headers/modsecurity/rule_with_actions.h \ - ../headers/modsecurity/rule_with_operator.h \ ../headers/modsecurity/rules.h \ ../headers/modsecurity/rule_message.h \ ../headers/modsecurity/rules_set.h \ ../headers/modsecurity/rules_set_phases.h \ ../headers/modsecurity/rules_set_properties.h \ ../headers/modsecurity/rules_exceptions.h \ + ../headers/modsecurity/string_view.hpp \ ../headers/modsecurity/transaction.h \ ../headers/modsecurity/variable_origin.h \ ../headers/modsecurity/variable_value.h + libmodsecurity_includesub_collection_HEADERS = \ ../headers/modsecurity/collection/collection.h \ ../headers/modsecurity/collection/collections.h @@ -286,6 +284,7 @@ libmodsecurity_la_SOURCES = \ debug_log/debug_log_writer.cc \ run_time_string.cc \ rule.cc \ + rules.cc \ rule_unconditional.cc \ rule_with_actions.cc \ rule_with_operator.cc \ diff --git a/src/actions/accuracy.cc b/src/actions/accuracy.cc index 58a26f376d..da59bbb4c3 100644 --- a/src/actions/accuracy.cc +++ b/src/actions/accuracy.cc @@ -13,15 +13,11 @@ * */ + #include "src/actions/accuracy.h" -#include #include -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - namespace modsecurity { namespace actions { @@ -29,9 +25,9 @@ namespace actions { bool Accuracy::init(std::string *error) { try { - m_accuracy = std::stoi(m_parser_payload); + m_accuracy = std::stoi(m_parserPayload); } catch (...) { - error->assign("Accuracy: The input \"" + m_parser_payload + "\" is " \ + error->assign("Accuracy: The input \"" + m_parserPayload + "\" is " \ "not a number."); return false; } @@ -39,11 +35,5 @@ bool Accuracy::init(std::string *error) { } -bool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->m_accuracy = m_accuracy; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/accuracy.h b/src/actions/accuracy.h index 761a0bcc3e..99b802ee83 100644 --- a/src/actions/accuracy.h +++ b/src/actions/accuracy.h @@ -13,29 +13,32 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_ACCURACY_H_ #define SRC_ACTIONS_ACCURACY_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Accuracy : public Action { +class Accuracy : public ActionTypeRuleMetaData { public: - explicit Accuracy(const std::string &action) - : Action(action, ConfigurationKind), + explicit Accuracy(const std::string &action) + : Action(action), m_accuracy(0) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; + void configure(RuleWithActions *rule) override { + rule->setAccuracy(m_accuracy); + } + private: int m_accuracy; }; diff --git a/src/actions/action.cc b/src/actions/action.cc index 8a2409d1a1..cf11ade86e 100644 --- a/src/actions/action.cc +++ b/src/actions/action.cc @@ -15,46 +15,10 @@ #include "modsecurity/actions/action.h" -#include -#include - -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "src/utils/string.h" - -#include "src/actions/block.h" -#include "src/actions/chain.h" -#include "src/actions/disruptive/deny.h" -#include "src/actions/disruptive/redirect.h" -#include "src/actions/data/status.h" -#include "src/actions/rule_id.h" -#include "src/actions/phase.h" -#include "src/actions/severity.h" -#include "src/actions/capture.h" -#include "src/actions/disruptive/pass.h" -#include "src/actions/log.h" -#include "src/actions/no_log.h" -#include "src/actions/no_audit_log.h" -#include "src/actions/multi_match.h" - - -#define IF_MATCH(a) \ - if (op.compare(1, std::strlen(#a), #a) == 0) namespace modsecurity { namespace actions { -std::string Action::evaluate(const std::string &value, - Transaction *transaction) { - return value; -} - - -bool Action::evaluate(RuleWithActions *rule, Transaction *transaction) { - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/action_allowed_in_sec_default_action.h b/src/actions/action_allowed_in_sec_default_action.h new file mode 100644 index 0000000000..1d23f08ec7 --- /dev/null +++ b/src/actions/action_allowed_in_sec_default_action.h @@ -0,0 +1,34 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "modsecurity/actions/action.h" + +#ifndef SRC_ACTIONS_ACTION_ALLOWED_IN_SEC_DEFAULT_ACTION_H_ +#define SRC_ACTIONS_ACTION_ALLOWED_IN_SEC_DEFAULT_ACTION_H_ + + +namespace modsecurity { +namespace actions { + + +class ActionAllowedAsSecDefaultAction : public virtual Action { + public: +}; + + +} // namespace actions +} // namespace modsecurity + +#endif // SRC_ACTIONS_ACTION_ALLOWED_IN_SEC_DEFAULT_ACTION_H_ diff --git a/src/actions/action_type_rule_metadata.h b/src/actions/action_type_rule_metadata.h new file mode 100644 index 0000000000..2470a4b87c --- /dev/null +++ b/src/actions/action_type_rule_metadata.h @@ -0,0 +1,47 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + + +#include "modsecurity/actions/action.h" +#include "src/rule_with_actions.h" + +#ifndef SRC_ACTIONS_ACTION_TYPE_CONFIGURE_H_ +#define SRC_ACTIONS_ACTION_TYPE_CONFIGURE_H_ + + +namespace modsecurity { +namespace actions { + + +class ActionTypeRuleMetaData : public virtual Action { + public: + /** + * + * Action that are executed while loading the configuration. For instance + * the rule ID or the rule phase. + * + */ + ActionTypeRuleMetaData() + : Action() + { }; + + virtual void configure(RuleWithActions *rule) = 0; +}; + + +} // namespace actions +} // namespace modsecurity + +#endif // SRC_ACTIONS_ACTION_TYPE_CONFIGURE_H_ diff --git a/src/actions/action_with_execution.h b/src/actions/action_with_execution.h new file mode 100644 index 0000000000..277b7d0d22 --- /dev/null +++ b/src/actions/action_with_execution.h @@ -0,0 +1,41 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + + +#include "modsecurity/actions/action.h" +#include "src/rule_with_actions.h" + +#ifndef SRC_ACTIONS_ACTION_WITH_EXECUTION_H_ +#define SRC_ACTIONS_ACTION_WITH_EXECUTION_H_ + + +namespace modsecurity { +namespace actions { + + +class ActionWithExecution : public virtual Action { + public: + ActionWithExecution() + : Action() + { }; + + virtual bool execute(Transaction *t) const noexcept = 0; +}; + + +} // namespace actions +} // namespace modsecurity + +#endif // SRC_ACTIONS_ACTION_WITH_EXECUTION_H_ diff --git a/src/actions/action_with_run_time_string.h b/src/actions/action_with_run_time_string.h new file mode 100644 index 0000000000..7b87bb853a --- /dev/null +++ b/src/actions/action_with_run_time_string.h @@ -0,0 +1,70 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include + +#include "modsecurity/actions/action.h" +#include "src/run_time_string.h" + +#ifndef SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_ +#define SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_ + + +namespace modsecurity { +namespace actions { + + +class ActionWithRunTimeString : public virtual Action { + public: + explicit ActionWithRunTimeString(std::unique_ptr string = nullptr) + : m_string(std::move(string)) + { } + + ActionWithRunTimeString(const ActionWithRunTimeString &a) + : m_string(a.m_string?std::unique_ptr(new RunTimeString(*a.m_string.get())):nullptr) + { } + + ActionWithRunTimeString& operator=(const ActionWithRunTimeString& a) { + m_string = std::unique_ptr(new RunTimeString(*a.m_string.get())); + return *this; + } + + virtual void populate(RuleWithActions *rule) { + if (m_string) { + m_string->populate(rule); + } + } + + std::string getEvaluatedRunTimeString(Transaction *transaction) const noexcept { + return (m_string == nullptr)?"":m_string->evaluate(transaction); + } + + bool hasRunTimeString() const noexcept { + return m_string != nullptr; + } + + virtual ActionWithRunTimeString* clone() = 0; + + private: + std::unique_ptr m_string; +}; + + +} // namespace actions +} // namespace modsecurity + +#endif // SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_ diff --git a/src/actions/audit_log.cc b/src/actions/audit_log.cc index e0af6a7431..362b3f796f 100644 --- a/src/actions/audit_log.cc +++ b/src/actions/audit_log.cc @@ -15,27 +15,10 @@ #include "src/actions/audit_log.h" -#include -#include -#include - -#include "modsecurity/transaction.h" -#include "modsecurity/rule_message.h" -#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { -bool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_noAuditLog = false; - ms_dbg_a(transaction, 9, "Saving transaction to logs"); - rm->m_saveMessage = true; - - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/audit_log.h b/src/actions/audit_log.h index c0b3b84924..d185153753 100644 --- a/src/actions/audit_log.h +++ b/src/actions/audit_log.h @@ -13,35 +13,36 @@ * */ -#include -#include -#include "modsecurity/actions/action.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + #ifndef SRC_ACTIONS_AUDIT_LOG_H_ #define SRC_ACTIONS_AUDIT_LOG_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; - namespace actions { -class AuditLog : public Action { +class AuditLog : public ActionTypeRuleMetaData, + public ActionAllowedAsSecDefaultAction { public: - explicit AuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + AuditLog() + : Action("auditLog") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + void configure(RuleWithActions *rule) override { + rule->setHasAuditLogAction(true); + } }; } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_AUDIT_LOG_H_ diff --git a/src/actions/block.cc b/src/actions/block.cc index df1a23ab0c..31b1a8b6d5 100644 --- a/src/actions/block.cc +++ b/src/actions/block.cc @@ -13,36 +13,13 @@ * */ -#include "src/actions/block.h" -#include -#include -#include +#include "src/actions/block.h" -#include "modsecurity/rules_set.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/intervention.h" -#include "src/actions/data/status.h" namespace modsecurity { namespace actions { -bool Block::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - ms_dbg_a(transaction, 8, "Marking request as disruptive."); - - for (auto &a : transaction->m_rules->m_defaultActions[rule->getPhase()]) { - if (a->isDisruptive() == false) { - continue; - } - a->evaluate(rule, transaction, rm); - } - - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/block.h b/src/actions/block.h index b5f33b479f..8800ea0511 100644 --- a/src/actions/block.h +++ b/src/actions/block.h @@ -13,35 +13,37 @@ * */ + #include #include -#include "modsecurity/actions/action.h" -#include "modsecurity/rule_message.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/action_allowed_in_sec_default_action.h" -#ifndef SRC_ACTIONS_DISRUPTIVE_BLOCK_H_ -#define SRC_ACTIONS_DISRUPTIVE_BLOCK_H_ -#ifdef __cplusplus -class Transaction; +#ifndef SRC_ACTIONS_BLOCK_H_ +#define SRC_ACTIONS_BLOCK_H_ -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { -class Block : public Action { +class Block : public ActionTypeRuleMetaData, + public ActionAllowedAsSecDefaultAction { public: - explicit Block(const std::string &action) : Action(action) { } + Block() + : Action("block") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + void configure(RuleWithActions *rule) override { + rule->setHasBlockAction(true); + } }; } // namespace actions } // namespace modsecurity -#endif -#endif // SRC_ACTIONS_DISRUPTIVE_BLOCK_H_ + +#endif // SRC_ACTIONS_BLOCK_H_ diff --git a/src/actions/capture.cc b/src/actions/capture.cc index 966b240df5..83abc16c32 100644 --- a/src/actions/capture.cc +++ b/src/actions/capture.cc @@ -13,29 +13,13 @@ * */ -#include "src/actions/capture.h" - -#include -#include -#include -#include "modsecurity/transaction.h" +#include "src/actions/capture.h" -#include "modsecurity/rule.h" -#include "src/operators/operator.h" -#include "src/operators/pm.h" -#include "src/operators/rx.h" -#include "src/operators/contains.h" -#include "src/operators/detect_sqli.h" namespace modsecurity { namespace actions { -bool Capture::evaluate(RuleWithActions *rule, Transaction *transaction) { - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/capture.h b/src/actions/capture.h index 841d1ecb14..041635a5ee 100644 --- a/src/actions/capture.h +++ b/src/actions/capture.h @@ -13,25 +13,28 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_CAPTURE_H_ #define SRC_ACTIONS_CAPTURE_H_ namespace modsecurity { -class RuleWithOperator; namespace actions { -class Capture : public Action { +class Capture : public ActionTypeRuleMetaData { public: - explicit Capture(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + Capture() + : Action("capture") { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + void configure(RuleWithActions *rule) override { + rule->setHasCaptureAction(true); + } }; diff --git a/src/actions/chain.cc b/src/actions/chain.cc index 06419c342e..8fe949190c 100644 --- a/src/actions/chain.cc +++ b/src/actions/chain.cc @@ -13,23 +13,13 @@ * */ -#include "src/actions/chain.h" -#include -#include +#include "src/actions/chain.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" namespace modsecurity { namespace actions { -bool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->setChained(true); - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/chain.h b/src/actions/chain.h index 6a1532d29b..f1b55f8920 100644 --- a/src/actions/chain.h +++ b/src/actions/chain.h @@ -13,33 +13,34 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_CHAIN_H_ #define SRC_ACTIONS_CHAIN_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; -class RuleWithOperator; - namespace actions { -class Chain : public Action { +class Chain : public ActionTypeRuleMetaData { public: - explicit Chain(const std::string &action) - : Action(action, ConfigurationKind) { } + Chain() + : Action("chain") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + void configure(RuleWithActions *rule) override { + rule->setHasChainAction(true); + } }; + } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_CHAIN_H_ diff --git a/src/actions/ctl/audit_log_parts.cc b/src/actions/ctl/audit_log_parts.cc index 2a8d7f0113..d06bd6bc51 100644 --- a/src/actions/ctl/audit_log_parts.cc +++ b/src/actions/ctl/audit_log_parts.cc @@ -13,13 +13,20 @@ * */ + #include "src/actions/ctl/audit_log_parts.h" -#include #include #include #include "modsecurity/transaction.h" +#include "modsecurity/audit_log.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + namespace modsecurity { namespace actions { @@ -27,20 +34,39 @@ namespace ctl { bool AuditLogParts::init(std::string *error) { - std::string what(m_parser_payload, 14, 1); - mParts = std::string(m_parser_payload, 15, m_parser_payload.length()-15); + std::string what(m_parserPayload, 14, 1); + std::string parts_str(m_parserPayload, 15, m_parserPayload.length()-15); + + if ((what != "-") && (what != "+")) { + error->assign("ctl:auditLogParts modificators expects add or " \ + "remove (+/-) in front of the modificator. Got: " + what); + return false; + } + + int flags = AuditLog::addParts(0, parts_str); + if (what == "+") { - mPartsAction = 0; + m_partsToModify = flags; } else { - mPartsAction = 1; + m_partsToModify = -1 * flags; } return true; } -bool AuditLogParts::evaluate(RuleWithActions *rule, Transaction *transaction) { - transaction->m_auditLogModifier.push_back( - std::make_pair(mPartsAction, mParts)); + +bool AuditLogParts::execute(Transaction *transaction) const noexcept { + ms_dbg_a(transaction, 7, "AuditLog parts before modification: " + + std::to_string(transaction->m_auditLogParts) + "."); + + if (m_partsToModify < 0) { + transaction->m_auditLogParts = \ + transaction->m_auditLogParts & ~(m_partsToModify * -1); + } else { + transaction->m_auditLogParts = \ + transaction->m_auditLogParts | m_partsToModify; + } + return true; } diff --git a/src/actions/ctl/audit_log_parts.h b/src/actions/ctl/audit_log_parts.h index 6638fa0fb5..f1a8de677f 100644 --- a/src/actions/ctl/audit_log_parts.h +++ b/src/actions/ctl/audit_log_parts.h @@ -13,32 +13,36 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_ #define SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_ + namespace modsecurity { namespace actions { namespace ctl { -class AuditLogParts : public Action { +class AuditLogParts : public ActionWithExecution { public: - explicit AuditLogParts(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - mPartsAction(0), - mParts("") { } + explicit AuditLogParts(const std::string &action) + : Action(action), + m_partsToModify(0) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; + bool execute(Transaction *transaction) const noexcept override; + protected: - int mPartsAction; - std::string mParts; + int m_partsToModify; }; @@ -46,4 +50,5 @@ class AuditLogParts : public Action { } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_ diff --git a/src/actions/ctl/request_body_access.cc b/src/actions/ctl/request_body_access.cc index 5f7edc250c..e95e270133 100644 --- a/src/actions/ctl/request_body_access.cc +++ b/src/actions/ctl/request_body_access.cc @@ -13,40 +13,44 @@ * */ + #include "src/actions/ctl/request_body_access.h" -#include #include #include "modsecurity/rules_set_properties.h" #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { bool RequestBodyAccess::init(std::string *error) { - std::string what(m_parser_payload, 18, m_parser_payload.size() - 18); + std::string what(m_parserPayload, 18, m_parserPayload.size() - 18); if (what == "true") { - m_request_body_access = true; + m_requestBodyAccess = true; } else if (what == "false") { - m_request_body_access = false; + m_requestBodyAccess = false; } else { error->assign("Internal error. Expected: true or false, got: " \ - + m_parser_payload); + + m_parserPayload); return false; } return true; } -bool RequestBodyAccess::evaluate(RuleWithActions *rule, Transaction *transaction) { - if (m_request_body_access) { - transaction->m_requestBodyAccess = RulesSetProperties::TrueConfigBoolean; + +bool RequestBodyAccess::execute(Transaction *transaction) const noexcept { + if (m_requestBodyAccess) { + transaction->m_requestBodyAccess = + RulesSetProperties::TrueConfigBoolean; } else { - transaction->m_requestBodyAccess = RulesSetProperties::FalseConfigBoolean; + transaction->m_requestBodyAccess = + RulesSetProperties::FalseConfigBoolean; } return true; diff --git a/src/actions/ctl/request_body_access.h b/src/actions/ctl/request_body_access.h index 4bbd8f6848..c1cdb5a243 100644 --- a/src/actions/ctl/request_body_access.h +++ b/src/actions/ctl/request_body_access.h @@ -13,30 +13,36 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_ #define SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RequestBodyAccess : public Action { +class RequestBodyAccess : public ActionWithExecution { public: - explicit RequestBodyAccess(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_request_body_access(false) { } + explicit RequestBodyAccess(const std::string &action) + : Action(action), + m_requestBodyAccess(false) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool m_request_body_access; + bool execute(Transaction *transaction) const noexcept override; + + private: + bool m_requestBodyAccess; }; @@ -44,4 +50,5 @@ class RequestBodyAccess : public Action { } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_ diff --git a/src/actions/ctl/request_body_processor_json.cc b/src/actions/ctl/request_body_processor_json.cc index a80c4edeae..65389955be 100644 --- a/src/actions/ctl/request_body_processor_json.cc +++ b/src/actions/ctl/request_body_processor_json.cc @@ -13,20 +13,20 @@ * */ + #include "src/actions/ctl/request_body_processor_json.h" -#include #include #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { -bool RequestBodyProcessorJSON::evaluate(RuleWithActions *rule, - Transaction *transaction) { +bool RequestBodyProcessorJSON::execute(Transaction *transaction) const noexcept { transaction->m_requestBodyProcessor = Transaction::JSONRequestBody; transaction->m_variableReqbodyProcessor.set("JSON", transaction->m_variableOffset); diff --git a/src/actions/ctl/request_body_processor_json.h b/src/actions/ctl/request_body_processor_json.h index 42a6372345..ac0dd41dea 100644 --- a/src/actions/ctl/request_body_processor_json.h +++ b/src/actions/ctl/request_body_processor_json.h @@ -13,25 +13,30 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_JSON_H_ #define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_JSON_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RequestBodyProcessorJSON : public Action { +class RequestBodyProcessorJSON : public ActionWithExecution { public: - explicit RequestBodyProcessorJSON(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit RequestBodyProcessorJSON(const std::string &action) + : Action(action) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; }; diff --git a/src/actions/ctl/request_body_processor_urlencoded.cc b/src/actions/ctl/request_body_processor_urlencoded.cc index 222970e701..9394937bce 100644 --- a/src/actions/ctl/request_body_processor_urlencoded.cc +++ b/src/actions/ctl/request_body_processor_urlencoded.cc @@ -13,20 +13,21 @@ * */ + #include "src/actions/ctl/request_body_processor_urlencoded.h" -#include #include #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { -bool RequestBodyProcessorURLENCODED::evaluate(RuleWithActions *rule, - Transaction *transaction) { +bool RequestBodyProcessorURLENCODED::execute( + Transaction *transaction) const noexcept { transaction->m_requestBodyType = Transaction::WWWFormUrlEncoded; transaction->m_variableReqbodyProcessor.set("URLENCODED", transaction->m_variableOffset); diff --git a/src/actions/ctl/request_body_processor_urlencoded.h b/src/actions/ctl/request_body_processor_urlencoded.h index 0564881535..28044d65a8 100644 --- a/src/actions/ctl/request_body_processor_urlencoded.h +++ b/src/actions/ctl/request_body_processor_urlencoded.h @@ -13,25 +13,30 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_URLENCODED_H_ #define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_URLENCODED_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RequestBodyProcessorURLENCODED : public Action { +class RequestBodyProcessorURLENCODED : public ActionWithExecution { public: - explicit RequestBodyProcessorURLENCODED(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit RequestBodyProcessorURLENCODED(const std::string &action) + : Action(action) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; }; diff --git a/src/actions/ctl/request_body_processor_xml.cc b/src/actions/ctl/request_body_processor_xml.cc index 4876c20bbb..ca281734a2 100644 --- a/src/actions/ctl/request_body_processor_xml.cc +++ b/src/actions/ctl/request_body_processor_xml.cc @@ -13,20 +13,20 @@ * */ + #include "src/actions/ctl/request_body_processor_xml.h" -#include #include #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { -bool RequestBodyProcessorXML::evaluate(RuleWithActions *rule, - Transaction *transaction) { +bool RequestBodyProcessorXML::execute(Transaction *transaction) const noexcept { transaction->m_requestBodyProcessor = Transaction::XMLRequestBody; transaction->m_variableReqbodyProcessor.set("XML", transaction->m_variableOffset); diff --git a/src/actions/ctl/request_body_processor_xml.h b/src/actions/ctl/request_body_processor_xml.h index 509c0f7437..46bb85a7fd 100644 --- a/src/actions/ctl/request_body_processor_xml.h +++ b/src/actions/ctl/request_body_processor_xml.h @@ -13,25 +13,30 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_XML_H_ #define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_XML_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RequestBodyProcessorXML : public Action { +class RequestBodyProcessorXML : public ActionWithExecution { public: - explicit RequestBodyProcessorXML(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit RequestBodyProcessorXML(const std::string &action) + : Action(action) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; }; diff --git a/src/actions/ctl/rule_engine.cc b/src/actions/ctl/rule_engine.cc index 10f1b2e899..81612af7b2 100644 --- a/src/actions/ctl/rule_engine.cc +++ b/src/actions/ctl/rule_engine.cc @@ -13,22 +13,23 @@ * */ + #include "src/actions/ctl/rule_engine.h" -#include #include #include "modsecurity/rules_set_properties.h" #include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { bool RuleEngine::init(std::string *error) { - std::string what(m_parser_payload, 11, m_parser_payload.size() - 11); + std::string what(m_parserPayload, 11, m_parserPayload.size() - 11); if (what == "on") { m_ruleEngine = RulesSetProperties::EnabledRuleEngine; @@ -38,14 +39,15 @@ bool RuleEngine::init(std::string *error) { m_ruleEngine = RulesSetProperties::DetectionOnlyRuleEngine; } else { error->assign("Internal error. Expected: On, Off or DetectionOnly; " \ - "got: " + m_parser_payload); + "got: " + m_parserPayload); return false; } return true; } -bool RuleEngine::evaluate(RuleWithActions *rule, Transaction *transaction) { + +bool RuleEngine::execute(Transaction *transaction) const noexcept { std::stringstream a; a << "Setting SecRuleEngine to "; a << modsecurity::RulesSetProperties::ruleEngineStateString(m_ruleEngine); diff --git a/src/actions/ctl/rule_engine.h b/src/actions/ctl/rule_engine.h index 304389bdc7..c8c87f4338 100644 --- a/src/actions/ctl/rule_engine.h +++ b/src/actions/ctl/rule_engine.h @@ -13,30 +13,35 @@ * */ + #include #include "modsecurity/rules_set_properties.h" #include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_RULE_ENGINE_H_ #define SRC_ACTIONS_CTL_RULE_ENGINE_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RuleEngine : public Action { +class RuleEngine : public ActionWithExecution { public: - explicit RuleEngine(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { } + explicit RuleEngine(const std::string &action) + : Action(action), + m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + + private: RulesSetProperties::RuleEngine m_ruleEngine; }; diff --git a/src/actions/ctl/rule_remove_by_id.cc b/src/actions/ctl/rule_remove_by_id.cc index 431a7a9c49..f6fb9b7bb0 100644 --- a/src/actions/ctl/rule_remove_by_id.cc +++ b/src/actions/ctl/rule_remove_by_id.cc @@ -13,21 +13,25 @@ * */ + #include "src/actions/ctl/rule_remove_by_id.h" -#include #include +#include +#include #include "modsecurity/transaction.h" + #include "src/utils/string.h" + namespace modsecurity { namespace actions { namespace ctl { bool RuleRemoveById::init(std::string *error) { - std::string what(m_parser_payload, 15, m_parser_payload.size() - 15); + std::string what(m_parserPayload, 15, m_parserPayload.size() - 15); bool added = false; std::vector toRemove = utils::string::ssplit(what, ' '); for (std::string &a : toRemove) { @@ -83,7 +87,8 @@ bool RuleRemoveById::init(std::string *error) { return false; } -bool RuleRemoveById::evaluate(RuleWithActions *rule, Transaction *transaction) { + +bool RuleRemoveById::execute(Transaction *transaction) const noexcept { for (auto &i : m_ids) { transaction->m_ruleRemoveById.push_back(i); } diff --git a/src/actions/ctl/rule_remove_by_id.h b/src/actions/ctl/rule_remove_by_id.h index 7af416a6c4..b4e06fb9ed 100644 --- a/src/actions/ctl/rule_remove_by_id.h +++ b/src/actions/ctl/rule_remove_by_id.h @@ -13,28 +13,36 @@ * */ + #include +#include +#include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_RULE_REMOVE_BY_ID_H_ #define SRC_ACTIONS_CTL_RULE_REMOVE_BY_ID_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RuleRemoveById : public Action { +class RuleRemoveById : public ActionWithExecution { public: - explicit RuleRemoveById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit RuleRemoveById(const std::string &action) + : Action(action) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + + private: std::list > m_ranges; std::list m_ids; }; diff --git a/src/actions/ctl/rule_remove_by_tag.cc b/src/actions/ctl/rule_remove_by_tag.cc index c6c9ffe037..0d491256c5 100644 --- a/src/actions/ctl/rule_remove_by_tag.cc +++ b/src/actions/ctl/rule_remove_by_tag.cc @@ -13,26 +13,28 @@ * */ + #include "src/actions/ctl/rule_remove_by_tag.h" -#include #include #include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { namespace ctl { bool RuleRemoveByTag::init(std::string *error) { - std::string what(m_parser_payload, 16, m_parser_payload.size() - 16); + std::string what(m_parserPayload, 16, m_parserPayload.size() - 16); m_tag = what; return true; } -bool RuleRemoveByTag::evaluate(RuleWithActions *rule, Transaction *transaction) { + +bool RuleRemoveByTag::execute(Transaction *transaction) const noexcept { transaction->m_ruleRemoveByTag.push_back(m_tag); return true; } diff --git a/src/actions/ctl/rule_remove_by_tag.h b/src/actions/ctl/rule_remove_by_tag.h index bd38ec0303..3461b636d7 100644 --- a/src/actions/ctl/rule_remove_by_tag.h +++ b/src/actions/ctl/rule_remove_by_tag.h @@ -13,29 +13,35 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_RULE_REMOVE_BY_TAG_H_ #define SRC_ACTIONS_CTL_RULE_REMOVE_BY_TAG_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RuleRemoveByTag : public Action { +class RuleRemoveByTag : public ActionWithExecution { public: - explicit RuleRemoveByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_tag("") { } + explicit RuleRemoveByTag(const std::string &action) + : Action(action), + m_tag("") + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + + private: std::string m_tag; }; diff --git a/src/actions/ctl/rule_remove_target_by_id.cc b/src/actions/ctl/rule_remove_target_by_id.cc index 233a0ae0da..def0ad7d4a 100644 --- a/src/actions/ctl/rule_remove_target_by_id.cc +++ b/src/actions/ctl/rule_remove_target_by_id.cc @@ -13,14 +13,15 @@ * */ + #include "src/actions/ctl/rule_remove_target_by_id.h" -#include #include #include #include #include "modsecurity/transaction.h" + #include "src/utils/string.h" @@ -30,7 +31,7 @@ namespace ctl { bool RuleRemoveTargetById::init(std::string *error) { - std::string what(m_parser_payload, 21, m_parser_payload.size() - 21); + std::string what(m_parserPayload, 21, m_parserPayload.size() - 21); std::vector param = utils::string::split(what, ';'); if (param.size() < 2) { @@ -51,7 +52,8 @@ bool RuleRemoveTargetById::init(std::string *error) { return true; } -bool RuleRemoveTargetById::evaluate(RuleWithActions *rule, Transaction *transaction) { + +bool RuleRemoveTargetById::execute(Transaction *transaction) const noexcept { transaction->m_ruleRemoveTargetById.push_back( std::make_pair(m_id, m_target)); return true; diff --git a/src/actions/ctl/rule_remove_target_by_id.h b/src/actions/ctl/rule_remove_target_by_id.h index e001c288e4..7dfec0f1c8 100644 --- a/src/actions/ctl/rule_remove_target_by_id.h +++ b/src/actions/ctl/rule_remove_target_by_id.h @@ -13,30 +13,36 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_ID_H_ #define SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_ID_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RuleRemoveTargetById : public Action { +class RuleRemoveTargetById : public ActionWithExecution { public: - explicit RuleRemoveTargetById(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + explicit RuleRemoveTargetById(const std::string &action) + : Action(action), m_id(0), - m_target("") { } + m_target("") + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + + private: int m_id; std::string m_target; }; diff --git a/src/actions/ctl/rule_remove_target_by_tag.cc b/src/actions/ctl/rule_remove_target_by_tag.cc index 25ec2ca85a..6f30df6561 100644 --- a/src/actions/ctl/rule_remove_target_by_tag.cc +++ b/src/actions/ctl/rule_remove_target_by_tag.cc @@ -13,14 +13,15 @@ * */ + #include "src/actions/ctl/rule_remove_target_by_tag.h" -#include #include #include #include #include "modsecurity/transaction.h" + #include "src/utils/string.h" @@ -30,7 +31,7 @@ namespace ctl { bool RuleRemoveTargetByTag::init(std::string *error) { - std::string what(m_parser_payload, 22, m_parser_payload.size() - 22); + std::string what(m_parserPayload, 22, m_parserPayload.size() - 22); std::vector param = utils::string::split(what, ';'); if (param.size() < 2) { @@ -44,7 +45,8 @@ bool RuleRemoveTargetByTag::init(std::string *error) { return true; } -bool RuleRemoveTargetByTag::evaluate(RuleWithActions *rule, Transaction *transaction) { + +bool RuleRemoveTargetByTag::execute(Transaction *transaction) const noexcept { transaction->m_ruleRemoveTargetByTag.push_back( std::make_pair(m_tag, m_target)); return true; diff --git a/src/actions/ctl/rule_remove_target_by_tag.h b/src/actions/ctl/rule_remove_target_by_tag.h index 2a23a34e07..eadc4e0fa2 100644 --- a/src/actions/ctl/rule_remove_target_by_tag.h +++ b/src/actions/ctl/rule_remove_target_by_tag.h @@ -13,28 +13,34 @@ * */ + #include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/action_with_execution.h" #ifndef SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_ #define SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_ + namespace modsecurity { namespace actions { namespace ctl { -class RuleRemoveTargetByTag : public Action { +class RuleRemoveTargetByTag : public ActionWithExecution { public: - explicit RuleRemoveTargetByTag(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit RuleRemoveTargetByTag(const std::string &action) + : Action(action) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + + private: std::string m_tag; std::string m_target; }; @@ -44,4 +50,5 @@ class RuleRemoveTargetByTag : public Action { } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_ diff --git a/src/actions/data/status.cc b/src/actions/data/status.cc index 1317b1d3ff..93213316af 100644 --- a/src/actions/data/status.cc +++ b/src/actions/data/status.cc @@ -13,11 +13,10 @@ * */ + #include "src/actions/data/status.h" -#include #include -#include #include "modsecurity/transaction.h" @@ -26,11 +25,12 @@ namespace modsecurity { namespace actions { namespace data { + bool Status::init(std::string *error) { try { - m_status = std::stoi(m_parser_payload); + m_status = std::stoi(m_parserPayload); } catch (...) { - error->assign("Not a valid number: " + m_parser_payload); + error->assign("Not a valid number: " + m_parserPayload); return false; } @@ -38,8 +38,7 @@ bool Status::init(std::string *error) { } -bool Status::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Status::execute(Transaction *transaction) const noexcept { transaction->m_it.status = m_status; return true; } diff --git a/src/actions/data/status.h b/src/actions/data/status.h index 214cbcffae..b5d51ba773 100644 --- a/src/actions/data/status.h +++ b/src/actions/data/status.h @@ -13,33 +13,37 @@ * */ + #include -#include #include "modsecurity/actions/action.h" -#include "modsecurity/rule_message.h" +#include "modsecurity/transaction.h" + +#include "src/actions/action_allowed_in_sec_default_action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_DATA_STATUS_H_ #define SRC_ACTIONS_DATA_STATUS_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; namespace actions { namespace data { -class Status : public Action { +class Status : public ActionAllowedAsSecDefaultAction, public ActionWithExecution { public: - explicit Status(const std::string &action) : Action(action, 2), - m_status(0) { } + explicit Status(const std::string &action) + : Action(action), + m_status(0) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool execute(Transaction *transaction) const noexcept override; + + private: int m_status; }; @@ -47,6 +51,6 @@ class Status : public Action { } // namespace data } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_DATA_STATUS_H_ diff --git a/src/actions/disruptive/allow.cc b/src/actions/disruptive/allow.cc index 3a360b5538..c644ee7460 100644 --- a/src/actions/disruptive/allow.cc +++ b/src/actions/disruptive/allow.cc @@ -13,16 +13,19 @@ * */ + #include "src/actions/disruptive/allow.h" -#include #include -#include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + #include "src/utils/string.h" -#include "modsecurity/modsecurity.h" namespace modsecurity { @@ -31,7 +34,7 @@ namespace disruptive { bool Allow::init(std::string *error) { - std::string a = utils::string::tolower(m_parser_payload); + std::string a = utils::string::tolower(m_parserPayload); if (a == "phase") { m_allowType = PhaseAllowType; @@ -49,7 +52,7 @@ bool Allow::init(std::string *error) { } -bool Allow::evaluate(RuleWithActions *rule, Transaction *transaction) { +bool Allow::execute(Transaction *transaction) const noexcept { ms_dbg_a(transaction, 4, "Dropping the evaluation of upcoming rules " \ "in favor of an `allow' action of type: " \ + allowTypeToName(m_allowType)); diff --git a/src/actions/disruptive/allow.h b/src/actions/disruptive/allow.h index de79b20515..e8dd14e79f 100644 --- a/src/actions/disruptive/allow.h +++ b/src/actions/disruptive/allow.h @@ -13,20 +13,21 @@ * */ + #include #include "modsecurity/actions/action.h" +#include "modsecurity/transaction.h" + +#include "src/actions/disruptive/disruptive_action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_DISRUPTIVE_ALLOW_H_ #define SRC_ACTIONS_DISRUPTIVE_ALLOW_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; -class RuleWithOperator; - namespace actions { namespace disruptive { @@ -51,17 +52,18 @@ enum AllowType : int { }; -class Allow : public Action { +class Allow : public ActionDisruptive, public ActionWithExecution { public: - explicit Allow(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_allowType(NoneAllowType) { } - + explicit Allow(const std::string &action) + : Action(action), + m_allowType(NoneAllowType) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool isDisruptive() override { return true; } + bool execute(Transaction *transaction) const noexcept override; + + private: AllowType m_allowType; static std::string allowTypeToName(AllowType a) { @@ -83,6 +85,6 @@ class Allow : public Action { } // namespace disruptive } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_DISRUPTIVE_ALLOW_H_ diff --git a/src/actions/disruptive/deny.cc b/src/actions/disruptive/deny.cc index 40572edecd..44e17621b1 100644 --- a/src/actions/disruptive/deny.cc +++ b/src/actions/disruptive/deny.cc @@ -13,23 +13,26 @@ * */ + #include "src/actions/disruptive/deny.h" -#include -#include #include -#include -#include #include "modsecurity/transaction.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" +#include "modsecurity/rule_message.h" + namespace modsecurity { namespace actions { namespace disruptive { -bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Deny::execute(Transaction *transaction) const noexcept { ms_dbg_a(transaction, 8, "Running action deny"); if (transaction->m_it.status == 200) { @@ -38,9 +41,10 @@ bool Deny::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + transaction->messageGetLast()->log( + RuleMessage::LogMessageInfo::ClientLogMessageInfo) + .c_str()); return true; } diff --git a/src/actions/disruptive/deny.h b/src/actions/disruptive/deny.h index 4e72ba174e..21381f4981 100644 --- a/src/actions/disruptive/deny.h +++ b/src/actions/disruptive/deny.h @@ -13,29 +13,32 @@ * */ + #include -#include -#include "modsecurity/rules_set.h" #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule_message.h" + +#include "src/actions/disruptive/disruptive_action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_DISRUPTIVE_DENY_H_ #define SRC_ACTIONS_DISRUPTIVE_DENY_H_ + namespace modsecurity { namespace actions { namespace disruptive { -class Deny : public Action { +class Deny : public ActionDisruptive, public ActionWithExecution { public: - explicit Deny(const std::string &action) : Action(action) { } + Deny() + : Action("deny") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; - bool isDisruptive() override { return true; } + bool execute(Transaction *transaction) const noexcept override; }; @@ -43,4 +46,5 @@ class Deny : public Action { } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_DISRUPTIVE_DENY_H_ diff --git a/src/actions/disruptive/disruptive_action.h b/src/actions/disruptive/disruptive_action.h new file mode 100644 index 0000000000..125ca1460a --- /dev/null +++ b/src/actions/disruptive/disruptive_action.h @@ -0,0 +1,42 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + + +#include + +#include "modsecurity/actions/action.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + + +#ifndef SRC_ACTIONS_DISRUPTIVE_DISRUPTIVE_ACTION_H_ +#define SRC_ACTIONS_DISRUPTIVE_DISRUPTIVE_ACTION_H_ + + +namespace modsecurity { +namespace actions { +namespace disruptive { + + +class ActionDisruptive : public ActionAllowedAsSecDefaultAction { + public: +}; + + +} // namespace disruptive +} // namespace actions +} // namespace modsecurity + + +#endif // SRC_ACTIONS_DISRUPTIVE_DISRUPTIVE_ACTION_H_ diff --git a/src/actions/disruptive/drop.cc b/src/actions/disruptive/drop.cc index 097bd56826..a4f1864a98 100644 --- a/src/actions/disruptive/drop.cc +++ b/src/actions/disruptive/drop.cc @@ -13,27 +13,26 @@ * */ + #include "src/actions/disruptive/drop.h" -#include -#include #include -#include -#include -#include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "src/utils/string.h" -#include "modsecurity/modsecurity.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" +#include "modsecurity/rule_message.h" + namespace modsecurity { namespace actions { namespace disruptive { -bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Drop::execute(Transaction *transaction) const noexcept { ms_dbg_a(transaction, 8, "Running action drop " \ "[executing deny instead of drop.]"); @@ -43,9 +42,11 @@ bool Drop::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; + transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + transaction->messageGetLast()->log( + RuleMessage::LogMessageInfo::ClientLogMessageInfo) + .c_str()); return true; } diff --git a/src/actions/disruptive/drop.h b/src/actions/disruptive/drop.h index 2da823c8b0..840bf83010 100644 --- a/src/actions/disruptive/drop.h +++ b/src/actions/disruptive/drop.h @@ -13,28 +13,32 @@ * */ + #include -#include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule_message.h" + +#include "src/actions/disruptive/disruptive_action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_DISRUPTIVE_DROP_H_ #define SRC_ACTIONS_DISRUPTIVE_DROP_H_ + namespace modsecurity { namespace actions { namespace disruptive { -class Drop : public Action { +class Drop : public ActionDisruptive, public ActionWithExecution { public: - explicit Drop(const std::string &action) : Action(action) { } + Drop() + : Action("drop") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; - bool isDisruptive() override { return true; } + bool execute(Transaction *transaction) const noexcept override; }; diff --git a/src/actions/disruptive/pass.cc b/src/actions/disruptive/pass.cc index 4b4c8fad65..84941334b0 100644 --- a/src/actions/disruptive/pass.cc +++ b/src/actions/disruptive/pass.cc @@ -13,24 +13,25 @@ * */ + #include "src/actions/disruptive/pass.h" -#include #include -#include -#include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_message.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + namespace modsecurity { namespace actions { namespace disruptive { -bool Pass::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { +bool Pass::execute(Transaction *transaction) const noexcept { intervention::free(&transaction->m_it); intervention::reset(&transaction->m_it); diff --git a/src/actions/disruptive/pass.h b/src/actions/disruptive/pass.h index dc1f6a583e..023aa2108c 100644 --- a/src/actions/disruptive/pass.h +++ b/src/actions/disruptive/pass.h @@ -13,27 +13,32 @@ * */ + #include -#include #include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +#include "src/actions/disruptive/disruptive_action.h" +#include "src/actions/action_with_execution.h" + + #ifndef SRC_ACTIONS_DISRUPTIVE_PASS_H_ #define SRC_ACTIONS_DISRUPTIVE_PASS_H_ + namespace modsecurity { namespace actions { namespace disruptive { -class Pass : public Action { +class Pass : public ActionDisruptive, public ActionWithExecution { public: - explicit Pass(const std::string &action) : Action(action) { } + Pass() + : Action("pass") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; - bool isDisruptive() override { return true; } + bool execute(Transaction *transaction) const noexcept override; }; diff --git a/src/actions/disruptive/redirect.cc b/src/actions/disruptive/redirect.cc index 07ac262576..fd41938647 100644 --- a/src/actions/disruptive/redirect.cc +++ b/src/actions/disruptive/redirect.cc @@ -13,33 +13,31 @@ * */ + #include "src/actions/disruptive/redirect.h" -#include -#include #include -#include #include "modsecurity/transaction.h" -#include "src/utils/string.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" +#include "modsecurity/rule_message.h" + namespace modsecurity { namespace actions { namespace disruptive { -bool Redirect::init(std::string *error) { - m_status = 302; - return true; -} - - -bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - std::string m_urlExpanded(m_string->evaluate(transaction)); +bool Redirect::execute(Transaction *transaction) const noexcept { + std::string m_urlExpanded(getEvaluatedRunTimeString(transaction)); /* if it was changed before, lets keep it. */ if (transaction->m_it.status == 200 - || (!(transaction->m_it.status <= 307 && transaction->m_it.status >= 301))) { + || (!(transaction->m_it.status <= 307 + && transaction->m_it.status >= 301))) { transaction->m_it.status = m_status; } @@ -47,9 +45,11 @@ bool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction, transaction->m_it.url = strdup(m_urlExpanded.c_str()); transaction->m_it.disruptive = true; intervention::freeLog(&transaction->m_it); - rm->m_isDisruptive = true; + transaction->m_it.log = strdup( - rm->log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str()); + transaction->messageGetLast()->log( + RuleMessage::LogMessageInfo::ClientLogMessageInfo) + .c_str()); return true; } diff --git a/src/actions/disruptive/redirect.h b/src/actions/disruptive/redirect.h index 6988954161..a4094b633c 100644 --- a/src/actions/disruptive/redirect.h +++ b/src/actions/disruptive/redirect.h @@ -13,53 +13,62 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "modsecurity/rule_message.h" +#include "modsecurity/transaction.h" + +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/disruptive/disruptive_action.h" #include "src/run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_ #define SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; - namespace actions { namespace disruptive { -class Redirect : public Action { +class Redirect : public ActionWithRunTimeString, public ActionDisruptive, + public ActionWithExecution { public: - explicit Redirect(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_status(0), - m_string(nullptr) { } + explicit Redirect(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("redirect"), + m_status(302) + { } + - explicit Redirect(std::unique_ptr z) - : Action("redirert", RunTimeOnlyIfMatchKind), - m_status(0), - m_string(std::move(z)) { } + explicit Redirect(const Redirect &action) + : ActionWithRunTimeString(action), + ActionDisruptive(action), + Action(action), + m_status(action.m_status) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; - bool init(std::string *error) override; - bool isDisruptive() override { return true; } + + bool execute(Transaction *transaction) const noexcept override; + + + ActionWithRunTimeString *clone() override { + return new Redirect(*this); + } private: int m_status; - std::unique_ptr m_string; }; } // namespace disruptive } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_ diff --git a/src/actions/exec.cc b/src/actions/exec.cc index 93cc5ff2bf..5047846faa 100644 --- a/src/actions/exec.cc +++ b/src/actions/exec.cc @@ -13,15 +13,18 @@ * */ + #include "src/actions/exec.h" -#include #include -#include "modsecurity/rules_set.h" -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + #include "src/utils/system.h" #include "src/engine/lua.h" @@ -33,7 +36,7 @@ namespace actions { bool Exec::init(std::string *error) { std::string err; - m_script = utils::find_resource(m_parser_payload, "", &err); + m_script = utils::find_resource(m_parserPayload, "", &err); if (m_script.size() == 0) { error->assign("exec: Script not found: " + err); @@ -49,7 +52,7 @@ bool Exec::init(std::string *error) { } -bool Exec::evaluate(RuleWithActions *rule, Transaction *t) { +bool Exec::execute(Transaction *t) const noexcept { ms_dbg_a(t, 8, "Running script... " + m_script); m_lua.run(t); return true; diff --git a/src/actions/exec.h b/src/actions/exec.h index 42537d038e..6398ea9dad 100644 --- a/src/actions/exec.h +++ b/src/actions/exec.h @@ -13,30 +13,32 @@ * */ + #include #include "modsecurity/actions/action.h" #include "src/engine/lua.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_EXEC_H_ #define SRC_ACTIONS_EXEC_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Exec : public Action { +class Exec : public ActionWithExecution { public: - explicit Exec(const std::string &action) + explicit Exec(const std::string &action) : Action(action), - m_script("") { } + m_script("") + { } ~Exec() { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; bool init(std::string *error) override; private: diff --git a/src/actions/expire_var.h b/src/actions/expire_var.h new file mode 100644 index 0000000000..415fb14611 --- /dev/null +++ b/src/actions/expire_var.h @@ -0,0 +1,54 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + + +#include +#include +#include + +#include "modsecurity/actions/action.h" +#include "modsecurity/transaction.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + + +#ifndef SRC_ACTIONS_EXPIRE_VAR_H_ +#define SRC_ACTIONS_EXPIRE_VAR_H_ + + +namespace modsecurity { +namespace actions { + + +class ExpireVar : public ActionWithExecution { + public: + explicit ExpireVar(const std::string &action) + : Action(action) + { } + + ~ExpireVar() { } + + bool execute(Transaction *transaction) const noexcept override { return true; }; + bool init(std::string *error) override { return true; }; + + private: +}; + + +} // namespace actions +} // namespace modsecurity + + +#endif // SRC_ACTIONS_EXPIRE_VAR_H_ diff --git a/src/actions/init_col.cc b/src/actions/init_col.cc index 246084503d..fb4b48b84a 100644 --- a/src/actions/init_col.cc +++ b/src/actions/init_col.cc @@ -13,14 +13,17 @@ * */ + #include "src/actions/init_col.h" -#include #include -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" namespace modsecurity { @@ -28,9 +31,9 @@ namespace actions { bool InitCol::init(std::string *error) { - int posEquals = m_parser_payload.find("="); + int posEquals = m_parserPayload.find("="); - if (m_parser_payload.size() < 2) { + if (m_parserPayload.size() < 2) { error->assign("Something wrong with initcol format: too small"); return false; } @@ -40,7 +43,7 @@ bool InitCol::init(std::string *error) { return false; } - m_collection_key = std::string(m_parser_payload, 0, posEquals); + m_collection_key = std::string(m_parserPayload, 0, posEquals); if (m_collection_key != "ip" && m_collection_key != "global" && @@ -54,8 +57,8 @@ bool InitCol::init(std::string *error) { } -bool InitCol::evaluate(RuleWithActions *rule, Transaction *t) { - std::string collectionName(m_string->evaluate(t)); +bool InitCol::execute(Transaction *t) const noexcept { + std::string collectionName(getEvaluatedRunTimeString(t)); if (m_collection_key == "ip") { t->m_collections.m_ip_collection_key = collectionName; diff --git a/src/actions/init_col.h b/src/actions/init_col.h index a7086204d6..58a34de8c5 100644 --- a/src/actions/init_col.h +++ b/src/actions/init_col.h @@ -13,36 +13,50 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_INIT_COL_H_ #define SRC_ACTIONS_INIT_COL_H_ -class Transaction; namespace modsecurity { class Transaction; namespace actions { -class InitCol : public Action { +class InitCol : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit InitCol(const std::string &action) : Action(action) { } + InitCol( + const std::string &action, + std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action(action) + { } - InitCol(const std::string &action, std::unique_ptr z) - : Action(action, RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + InitCol(const InitCol &action) + : ActionWithRunTimeString(action), + Action(action), + m_collection_key(action.m_collection_key) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; + + bool execute(Transaction *transaction) const noexcept override; + + ActionWithRunTimeString *clone() override { + return new InitCol(*this); + } + private: std::string m_collection_key; - std::unique_ptr m_string; }; diff --git a/src/actions/log.cc b/src/actions/log.cc index 320c0bf4bc..3d0b5ae703 100644 --- a/src/actions/log.cc +++ b/src/actions/log.cc @@ -13,28 +13,13 @@ * */ -#include "src/actions/log.h" -#include -#include -#include +#include "src/actions/log.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "src/operators/operator.h" -#include "modsecurity/rule_message.h" namespace modsecurity { namespace actions { -bool Log::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - ms_dbg_a(transaction, 9, "Saving transaction to logs"); - rm->m_saveMessage = true; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/log.h b/src/actions/log.h index 07726ad9a1..caa968da81 100644 --- a/src/actions/log.h +++ b/src/actions/log.h @@ -13,30 +13,36 @@ * */ -#include -#include #include "modsecurity/actions/action.h" +#include "src/actions/action_allowed_in_sec_default_action.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/rule_with_actions.h" + + #ifndef SRC_ACTIONS_LOG_H_ #define SRC_ACTIONS_LOG_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Log : public Action { +class Log : public ActionTypeRuleMetaData, + public ActionAllowedAsSecDefaultAction { public: - explicit Log(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + Log() + : Action("log") + { } + + void configure(RuleWithActions *rule) override { + rule->setHasLogAction(true); + } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; }; + } // namespace actions } // namespace modsecurity diff --git a/src/actions/log_data.cc b/src/actions/log_data.cc index 359dd299fe..ed8fa44bc6 100644 --- a/src/actions/log_data.cc +++ b/src/actions/log_data.cc @@ -13,34 +13,24 @@ * */ + #include "src/actions/log_data.h" -#include #include -#include -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" #include "modsecurity/rule_message.h" namespace modsecurity { namespace actions { - -bool LogData::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_data = data(transaction); - +bool LogData::execute(Transaction *transaction) const noexcept { + transaction->messageGetLast()->m_data = + getEvaluatedRunTimeString(transaction); return true; } -std::string LogData::data(Transaction *transaction) { - std::string a(m_string->evaluate(transaction)); - return a; -} - } // namespace actions } // namespace modsecurity diff --git a/src/actions/log_data.h b/src/actions/log_data.h index 486d826bc2..3aacd7f46f 100644 --- a/src/actions/log_data.h +++ b/src/actions/log_data.h @@ -13,38 +13,40 @@ * */ -#include -#include -#include #include "modsecurity/actions/action.h" + +#include "src/actions/action_with_run_time_string.h" #include "src/run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_LOG_DATA_H_ #define SRC_ACTIONS_LOG_DATA_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class LogData : public Action { +class LogData : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit LogData(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit LogData(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("logdata") + { } - explicit LogData(std::unique_ptr z) - : Action("logdata", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit LogData(const LogData &data) + : ActionWithRunTimeString(data), + Action(data) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool execute(Transaction *transaction) const noexcept override; - std::string data(Transaction *Transaction); + ActionWithRunTimeString *clone() override { + return new LogData(*this); + } - std::unique_ptr m_string; }; diff --git a/src/actions/maturity.cc b/src/actions/maturity.cc index b601208d9f..ee12200f84 100644 --- a/src/actions/maturity.cc +++ b/src/actions/maturity.cc @@ -13,15 +13,11 @@ * */ + #include "src/actions/maturity.h" -#include #include -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - namespace modsecurity { namespace actions { @@ -29,9 +25,9 @@ namespace actions { bool Maturity::init(std::string *error) { try { - m_maturity = std::stoi(m_parser_payload); + m_maturity = std::stoi(m_parserPayload); } catch (...) { - error->assign("Maturity: The input \"" + m_parser_payload + "\" is " \ + error->assign("Maturity: The input \"" + m_parserPayload + "\" is " \ "not a number."); return false; } @@ -39,11 +35,5 @@ bool Maturity::init(std::string *error) { } -bool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->m_maturity = m_maturity; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/maturity.h b/src/actions/maturity.h index 4fa5a5eda5..729476eb74 100644 --- a/src/actions/maturity.h +++ b/src/actions/maturity.h @@ -13,9 +13,11 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_MATURITY_H_ #define SRC_ACTIONS_MATURITY_H_ @@ -27,15 +29,18 @@ class Transaction; namespace actions { -class Maturity : public Action { +class Maturity : public ActionTypeRuleMetaData { public: - explicit Maturity(const std::string &action) - : Action(action, ConfigurationKind), + explicit Maturity(const std::string &action) + : Action(action), m_maturity(0) { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; + void configure(RuleWithActions *rule) override { + rule->setMaturity(m_maturity); + } + private: int m_maturity; }; diff --git a/src/actions/msg.cc b/src/actions/msg.cc index c553b1d655..157e710488 100644 --- a/src/actions/msg.cc +++ b/src/actions/msg.cc @@ -13,16 +13,19 @@ * */ + #include "src/actions/msg.h" -#include #include -#include -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_message.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + +#include "src/run_time_string.h" /* * Description: Assigns a custom message to the rule or chain in which it @@ -46,21 +49,14 @@ namespace modsecurity { namespace actions { -bool Msg::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - std::string msg = data(transaction); - rm->m_message = msg; +bool Msg::execute(Transaction *transaction) const noexcept { + std::string msg = getEvaluatedRunTimeString(transaction); + transaction->messageGetLast()->m_message = msg; ms_dbg_a(transaction, 9, "Saving msg: " + msg); return true; } -std::string Msg::data(Transaction *t) { - std::string a(m_string->evaluate(t)); - return a; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/msg.h b/src/actions/msg.h index 8f6ad06fda..5379258acb 100644 --- a/src/actions/msg.h +++ b/src/actions/msg.h @@ -13,13 +13,16 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" #include "modsecurity/rule_message.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_MSG_H_ #define SRC_ACTIONS_MSG_H_ @@ -31,20 +34,23 @@ class Transaction; namespace actions { -class Msg : public Action { +class Msg : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit Msg(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + explicit Msg(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("msg") + { }; - explicit Msg(std::unique_ptr z) - : Action("msg", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit Msg(const Msg &action) + : ActionWithRunTimeString(action), + Action(action) + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + bool execute(Transaction *transaction) const noexcept override; - std::string data(Transaction *Transaction); - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new Msg(*this); + } }; diff --git a/src/actions/multi_match.cc b/src/actions/multi_match.cc index 71189c2c0c..cf39e15021 100644 --- a/src/actions/multi_match.cc +++ b/src/actions/multi_match.cc @@ -13,22 +13,13 @@ * */ -#include "src/actions/multi_match.h" -#include -#include +#include "src/actions/multi_match.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" namespace modsecurity { namespace actions { -bool MultiMatch::evaluate(RuleWithActions *rule, Transaction *transaction) { - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/multi_match.h b/src/actions/multi_match.h index abab94f8ce..f8a7269459 100644 --- a/src/actions/multi_match.h +++ b/src/actions/multi_match.h @@ -13,33 +13,34 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_MULTI_MATCH_H_ #define SRC_ACTIONS_MULTI_MATCH_H_ -#ifdef __cplusplus -class Transaction; - namespace modsecurity { -class Transaction; -class RuleWithOperator; - namespace actions { -class MultiMatch : public Action { +class MultiMatch : public ActionTypeRuleMetaData { public: - explicit MultiMatch(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + MultiMatch() + : Action("multiMatch") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + + void configure(RuleWithActions *rule) override { + rule->setHasMultimatchAction(true); + } }; + } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_MULTI_MATCH_H_ diff --git a/src/actions/no_audit_log.cc b/src/actions/no_audit_log.cc index ef5d8bb234..a8387d181b 100644 --- a/src/actions/no_audit_log.cc +++ b/src/actions/no_audit_log.cc @@ -13,27 +13,13 @@ * */ -#include "src/actions/no_audit_log.h" -#include -#include +#include "src/actions/no_audit_log.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_message.h" namespace modsecurity { namespace actions { -bool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_noAuditLog = true; - rm->m_saveMessage = false; - - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/no_audit_log.h b/src/actions/no_audit_log.h index fbcac6d688..8b0252bb7c 100644 --- a/src/actions/no_audit_log.h +++ b/src/actions/no_audit_log.h @@ -13,34 +13,36 @@ * */ -#include -#include #include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + + #ifndef SRC_ACTIONS_NO_AUDIT_LOG_H_ #define SRC_ACTIONS_NO_AUDIT_LOG_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; - namespace actions { -class NoAuditLog : public Action { +class NoAuditLog : public ActionTypeRuleMetaData, + public ActionAllowedAsSecDefaultAction { public: - explicit NoAuditLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + NoAuditLog() + : Action("noAuditLog") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + void configure(RuleWithActions *rule) override { + rule->setHasNoAuditLogAction(true); + } }; + } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_NO_AUDIT_LOG_H_ diff --git a/src/actions/no_log.cc b/src/actions/no_log.cc index 4b28240610..5375201e1f 100644 --- a/src/actions/no_log.cc +++ b/src/actions/no_log.cc @@ -13,28 +13,13 @@ * */ -#include "src/actions/no_log.h" - -#include -#include -#include -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "src/operators/operator.h" -#include "modsecurity/rule_message.h" +#include "src/actions/no_log.h" namespace modsecurity { namespace actions { -bool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - rm->m_saveMessage = false; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/no_log.h b/src/actions/no_log.h index 78e1892db6..126458d91c 100644 --- a/src/actions/no_log.h +++ b/src/actions/no_log.h @@ -13,30 +13,34 @@ * */ -#include -#include #include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + + #ifndef SRC_ACTIONS_NO_LOG_H_ #define SRC_ACTIONS_NO_LOG_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class NoLog : public Action { +class NoLog : public ActionTypeRuleMetaData, + public ActionAllowedAsSecDefaultAction { public: - explicit NoLog(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind) { } + NoLog() + : Action("noLog") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; + void configure(RuleWithActions *rule) override { + rule->setHasNoLogAction(true); + } }; + } // namespace actions } // namespace modsecurity diff --git a/src/actions/phase.cc b/src/actions/phase.cc index d82cbe027f..fe772bf38c 100644 --- a/src/actions/phase.cc +++ b/src/actions/phase.cc @@ -15,12 +15,10 @@ #include "src/actions/phase.h" -#include #include #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/modsecurity.h" + #include "src/utils/string.h" @@ -28,11 +26,11 @@ namespace modsecurity { namespace actions { bool Phase::init(std::string *error) { - std::string a = utils::string::tolower(m_parser_payload); + std::string a = utils::string::tolower(m_parserPayload); m_phase = -1; try { - m_phase = std::stoi(m_parser_payload); + m_phase = std::stoi(m_parserPayload); if (m_phase == 0) { m_phase = modsecurity::Phases::ConnectionPhase; m_secRulesPhase = 0; @@ -52,7 +50,7 @@ bool Phase::init(std::string *error) { m_phase = modsecurity::Phases::LoggingPhase; m_secRulesPhase = 5; } else { - error->assign("Unknown phase: " + m_parser_payload); + error->assign("Unknown phase: " + m_parserPayload); return false; } } catch (...) { @@ -72,10 +70,5 @@ bool Phase::init(std::string *error) { } -bool Phase::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->setPhase(m_phase); - return true; -} - } // namespace actions } // namespace modsecurity diff --git a/src/actions/phase.h b/src/actions/phase.h index c85842e5bb..7b122c98b6 100644 --- a/src/actions/phase.h +++ b/src/actions/phase.h @@ -13,38 +13,48 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_PHASE_H_ #define SRC_ACTIONS_PHASE_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; -class RuleWithOperator; - namespace actions { -class Phase : public Action { +class Phase : public ActionTypeRuleMetaData { public: - explicit Phase(const std::string &action) : Action(action, ConfigurationKind), + explicit Phase(const std::string &action) + : Action(action), m_phase(0), m_secRulesPhase(0) { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + void configure(RuleWithActions *rule) override { + rule->setPhase(m_phase); + } + + int getSecRulePhase() { + return m_secRulesPhase; + } + + int getPhase() { + return m_phase; + } + + private: int m_phase; int m_secRulesPhase; }; + } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_PHASE_H_ diff --git a/src/actions/rev.cc b/src/actions/rev.cc index 7d886b9624..49e1c1b5aa 100644 --- a/src/actions/rev.cc +++ b/src/actions/rev.cc @@ -13,28 +13,18 @@ * */ + #include "src/actions/rev.h" -#include #include -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" - namespace modsecurity { namespace actions { bool Rev::init(std::string *error) { - m_rev = m_parser_payload; - return true; -} - - -bool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->m_rev = m_rev; + m_revision = m_parserPayload; return true; } diff --git a/src/actions/rev.h b/src/actions/rev.h index feb1012d24..b577bd21e6 100644 --- a/src/actions/rev.h +++ b/src/actions/rev.h @@ -13,29 +13,35 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_REV_H_ #define SRC_ACTIONS_REV_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Rev : public Action { +class Rev : public ActionTypeRuleMetaData { public: - explicit Rev(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Rev(const std::string &action) + : Action(action), + m_revision("") + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; bool init(std::string *error) override; + void configure(RuleWithActions *rule) override { + rule->setRevision(m_revision); + } + private: - std::string m_rev; + std::string m_revision; }; diff --git a/src/actions/rule_id.cc b/src/actions/rule_id.cc index a5b646128c..7cce70e4e1 100644 --- a/src/actions/rule_id.cc +++ b/src/actions/rule_id.cc @@ -13,20 +13,18 @@ * */ + #include "src/actions/rule_id.h" -#include #include -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" namespace modsecurity { namespace actions { bool RuleId::init(std::string *error) { - std::string a = m_parser_payload; + std::string a = m_parserPayload; try { m_ruleId = std::stod(a); @@ -48,11 +46,5 @@ bool RuleId::init(std::string *error) { } -bool RuleId::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->m_ruleId = m_ruleId; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/rule_id.h b/src/actions/rule_id.h index 0a6b380718..8813c7c514 100644 --- a/src/actions/rule_id.h +++ b/src/actions/rule_id.h @@ -13,38 +13,40 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_RULE_ID_H_ #define SRC_ACTIONS_RULE_ID_H_ -#ifdef __cplusplus -class Transaction; namespace modsecurity { -class Transaction; -class RuleWithOperator; - namespace actions { -class RuleId : public Action { +class RuleId : public ActionTypeRuleMetaData { public: - explicit RuleId(const std::string &action) - : Action(action, ConfigurationKind), - m_ruleId(0) { } + explicit RuleId(const std::string &action) + : Action(action), + m_ruleId(0) + { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + + void configure(RuleWithActions *rule) override { + rule->setId(m_ruleId); + } private: double m_ruleId; }; + } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_RULE_ID_H_ diff --git a/src/actions/set_env.cc b/src/actions/set_env.cc index 7541916380..f802954c3f 100644 --- a/src/actions/set_env.cc +++ b/src/actions/set_env.cc @@ -13,26 +13,27 @@ * */ + #include "src/actions/set_env.h" -#include #include #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "src/utils/string.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" -namespace modsecurity { -namespace actions { +#include "src/run_time_string.h" -bool SetENV::init(std::string *error) { - return true; -} +namespace modsecurity { +namespace actions { -bool SetENV::evaluate(RuleWithActions *rule, Transaction *t) { - std::string colNameExpanded(m_string->evaluate(t)); +bool SetENV::execute(Transaction *t) const noexcept { + std::string colNameExpanded(getEvaluatedRunTimeString(t)); ms_dbg_a(t, 8, "Setting envoriment variable: " + colNameExpanded + "."); diff --git a/src/actions/set_env.h b/src/actions/set_env.h index fcfc411f99..d60a11da59 100644 --- a/src/actions/set_env.h +++ b/src/actions/set_env.h @@ -13,12 +13,15 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SET_ENV_H_ #define SRC_ACTIONS_SET_ENV_H_ @@ -30,20 +33,23 @@ class Transaction; namespace actions { -class SetENV : public Action { +class SetENV : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit SetENV(const std::string &_action) - : Action(_action) { } + explicit SetENV(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("setenv") + { }; - explicit SetENV(std::unique_ptr z) - : Action("setenv", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit SetENV(const SetENV &action) + : ActionWithRunTimeString(action), + Action(action) + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; + bool execute(Transaction *transaction) const noexcept override; - private: - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new SetENV(*this); + } }; diff --git a/src/actions/set_rsc.cc b/src/actions/set_rsc.cc index 34db37b213..75c35e05c0 100644 --- a/src/actions/set_rsc.cc +++ b/src/actions/set_rsc.cc @@ -13,26 +13,25 @@ * */ + #include "src/actions/set_rsc.h" -#include #include #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { -bool SetRSC::init(std::string *error) { - return true; -} - - -bool SetRSC::evaluate(RuleWithActions *rule, Transaction *t) { - std::string colNameExpanded(m_string->evaluate(t)); +bool SetRSC::execute(Transaction *t) const noexcept { + std::string colNameExpanded(getEvaluatedRunTimeString(t)); ms_dbg_a(t, 8, "RESOURCE initiated with value: \'" + colNameExpanded + "\'."); @@ -42,5 +41,6 @@ bool SetRSC::evaluate(RuleWithActions *rule, Transaction *t) { return true; } + } // namespace actions } // namespace modsecurity diff --git a/src/actions/set_rsc.h b/src/actions/set_rsc.h index 013e066286..058f536524 100644 --- a/src/actions/set_rsc.h +++ b/src/actions/set_rsc.h @@ -13,12 +13,15 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SET_RSC_H_ #define SRC_ACTIONS_SET_RSC_H_ @@ -30,20 +33,23 @@ class Transaction; namespace actions { -class SetRSC : public Action { +class SetRSC : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit SetRSC(const std::string &_action) - : Action(_action) { } + explicit SetRSC(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("setsrc") + { }; - explicit SetRSC(std::unique_ptr z) - : Action("setsrc", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit SetRSC(const SetRSC &action) + : ActionWithRunTimeString(action), + Action(action) + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; + bool execute(Transaction *transaction) const noexcept override; - private: - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new SetRSC(*this); + } }; diff --git a/src/actions/set_sid.cc b/src/actions/set_sid.cc index e4c531115f..820edb4e97 100644 --- a/src/actions/set_sid.cc +++ b/src/actions/set_sid.cc @@ -13,26 +13,25 @@ * */ + #include "src/actions/set_sid.h" -#include #include #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { -bool SetSID::init(std::string *error) { - return true; -} - - -bool SetSID::evaluate(RuleWithActions *rule, Transaction *t) { - std::string colNameExpanded(m_string->evaluate(t)); +bool SetSID::execute(Transaction *t) const noexcept { + std::string colNameExpanded(getEvaluatedRunTimeString(t)); ms_dbg_a(t, 8, "Session ID initiated with value: \'" + colNameExpanded + "\'."); @@ -42,5 +41,6 @@ bool SetSID::evaluate(RuleWithActions *rule, Transaction *t) { return true; } + } // namespace actions } // namespace modsecurity diff --git a/src/actions/set_sid.h b/src/actions/set_sid.h index c8353854b7..2928a18a48 100644 --- a/src/actions/set_sid.h +++ b/src/actions/set_sid.h @@ -13,12 +13,15 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SET_SID_H_ #define SRC_ACTIONS_SET_SID_H_ @@ -30,20 +33,23 @@ class Transaction; namespace actions { -class SetSID : public Action { +class SetSID : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit SetSID(const std::string &_action) - : Action(_action) { } + explicit SetSID(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("setsid") + { }; - explicit SetSID(std::unique_ptr z) - : Action("setsid", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + SetSID(const SetSID &action) + : ActionWithRunTimeString(action), + Action(action) + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; + bool execute(Transaction *transaction) const noexcept override; - private: - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new SetSID(*this); + } }; diff --git a/src/actions/set_uid.cc b/src/actions/set_uid.cc index 90de7e47ff..7069a1cabb 100644 --- a/src/actions/set_uid.cc +++ b/src/actions/set_uid.cc @@ -13,26 +13,25 @@ * */ + #include "src/actions/set_uid.h" -#include #include #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { -bool SetUID::init(std::string *error) { - return true; -} - - -bool SetUID::evaluate(RuleWithActions *rule, Transaction *t) { - std::string colNameExpanded(m_string->evaluate(t)); +bool SetUID::execute(Transaction *t) const noexcept { + std::string colNameExpanded(getEvaluatedRunTimeString(t)); ms_dbg_a(t, 8, "User collection initiated with value: \'" + colNameExpanded + "\'."); @@ -42,5 +41,6 @@ bool SetUID::evaluate(RuleWithActions *rule, Transaction *t) { return true; } + } // namespace actions } // namespace modsecurity diff --git a/src/actions/set_uid.h b/src/actions/set_uid.h index b2f341a688..4a7c363a3b 100644 --- a/src/actions/set_uid.h +++ b/src/actions/set_uid.h @@ -13,12 +13,15 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SET_UID_H_ #define SRC_ACTIONS_SET_UID_H_ @@ -30,20 +33,23 @@ class Transaction; namespace actions { -class SetUID : public Action { +class SetUID : public ActionWithRunTimeString, public ActionWithExecution { public: - explicit SetUID(const std::string &_action) - : Action(_action) { } + explicit SetUID(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("setuid") + { }; - explicit SetUID(std::unique_ptr z) - : Action("setuid", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit SetUID(const SetUID &action) + : ActionWithRunTimeString(action), + Action(action) + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; - bool init(std::string *error) override; + bool execute(Transaction *transaction) const noexcept override; - private: - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new SetUID(*this); + } }; diff --git a/src/actions/set_var.cc b/src/actions/set_var.cc index c9f7f6653a..e650981e2e 100644 --- a/src/actions/set_var.cc +++ b/src/actions/set_var.cc @@ -13,23 +13,25 @@ * */ + #include "src/actions/set_var.h" -#include #include -#include -#include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "src/utils/string.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + #include "src/variables/global.h" #include "src/variables/ip.h" #include "src/variables/resource.h" #include "src/variables/session.h" #include "src/variables/tx.h" #include "src/variables/user.h" -#include "src/variables/variable.h" + namespace modsecurity { namespace actions { @@ -40,12 +42,12 @@ bool SetVar::init(std::string *error) { } -bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) { +bool SetVar::execute(Transaction *t) const noexcept { std::string targetValue; std::string resolvedPre; - if (m_string) { - resolvedPre = m_string->evaluate(t, rule); + if (hasRunTimeString()) { + resolvedPre = getEvaluatedRunTimeString(t); } std::string m_variableNameExpanded; @@ -64,17 +66,17 @@ bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) { variables::User_DynamicElement *user = dynamic_cast< variables::User_DynamicElement *> (v); if (tx) { - m_variableNameExpanded = tx->m_string->evaluate(t, rule); + m_variableNameExpanded = tx->evaluateRunTimeString(t); } else if (session) { - m_variableNameExpanded = session->m_string->evaluate(t, rule); + m_variableNameExpanded = session->evaluateRunTimeString(t); } else if (ip) { - m_variableNameExpanded = ip->m_string->evaluate(t, rule); + m_variableNameExpanded = ip->evaluateRunTimeString(t); } else if (resource) { - m_variableNameExpanded = resource->m_string->evaluate(t, rule); + m_variableNameExpanded = resource->evaluateRunTimeString(t); } else if (global) { - m_variableNameExpanded = global->m_string->evaluate(t, rule); + m_variableNameExpanded = global->evaluateRunTimeString(t); } else if (user) { - m_variableNameExpanded = user->m_string->evaluate(t, rule); + m_variableNameExpanded = user->evaluateRunTimeString(t); } else { m_variableNameExpanded = m_variable->m_name; } @@ -111,16 +113,12 @@ bool SetVar::evaluate(RuleWithActions *rule, Transaction *t) { } try { - std::vector l; - RuleWithOperator *rr = dynamic_cast(rule); - m_variable->evaluate(t, rr, &l); + std::vector> l; + m_variable->evaluate(t, &l); if (l.size() == 0) { value = 0; } else { value = stoi(l[0]->getValue()); - for (auto &i : l) { - delete i; - } } } catch (...) { value = 0; diff --git a/src/actions/set_var.h b/src/actions/set_var.h index 22905a8cc5..3e1f29b794 100644 --- a/src/actions/set_var.h +++ b/src/actions/set_var.h @@ -13,22 +13,27 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "modsecurity/transaction.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" +#include "src/rule_with_operator.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SET_VAR_H_ #define SRC_ACTIONS_SET_VAR_H_ -namespace modsecurity { -class Transaction; -class RuleWithOperator; +namespace modsecurity { namespace actions { + enum SetVarOperation { /* Set variable to something */ setOperation, @@ -42,31 +47,75 @@ enum SetVarOperation { unsetOperation, }; -class SetVar : public Action { + +class SetVar : public ActionWithRunTimeString, public ActionWithExecution { public: SetVar(SetVarOperation operation, std::unique_ptr variable, std::unique_ptr predicate) - : Action("setvar"), + : ActionWithRunTimeString(std::move(predicate)), m_operation(operation), m_variable(std::move(variable)), - m_string(std::move(predicate)) { } + Action("setvar") + { } + SetVar(SetVarOperation operation, std::unique_ptr variable) - : Action("setvar"), + : ActionWithRunTimeString(), + Action("setvar"), m_operation(operation), - m_variable(std::move(variable)) { } + m_variable(std::move(variable)) + { } + - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + SetVar(const SetVar &var) + : ActionWithRunTimeString(var), + Action(var), + m_operation(var.m_operation), + m_variable(var.m_variable) { + variables::RuleVariable *rv = dynamic_cast( + m_variable.get()); + if (rv != nullptr) { + auto nrv = rv->clone(); + rv = dynamic_cast(nrv); + rv->populate(nullptr); + m_variable = std::unique_ptr(nrv); + } + } + + + bool execute(Transaction *transaction) const noexcept override; bool init(std::string *error) override; + void populate(RuleWithActions *rule) override { + ActionWithRunTimeString::populate(rule); + variables::RuleVariable *rulev = + dynamic_cast( + m_variable.get()); + + if (rulev != nullptr) { + rulev->populate(rule); + } + variables::VariableWithRunTimeString *rulev2 = + dynamic_cast( + m_variable.get()); + + if (rulev2 != nullptr) { + rulev2->populate(rule); + } + } + + ActionWithRunTimeString *clone() override { + return new SetVar(*this); + } + private: SetVarOperation m_operation; - std::unique_ptr m_variable; - std::unique_ptr m_string; + std::shared_ptr m_variable; }; + } // namespace actions } // namespace modsecurity diff --git a/src/actions/severity.cc b/src/actions/severity.cc index f7db6bbdbf..99f574be38 100644 --- a/src/actions/severity.cc +++ b/src/actions/severity.cc @@ -13,18 +13,18 @@ * */ + #include "src/actions/severity.h" -#include #include -#include +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ #include "modsecurity/rules_set.h" -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" + #include "src/utils/string.h" -#include "modsecurity/rule_message.h" namespace modsecurity { @@ -32,7 +32,7 @@ namespace actions { bool Severity::init(std::string *error) { - std::string a = utils::string::tolower(m_parser_payload); + std::string a = utils::string::tolower(m_parserPayload); if (a == "emergency") { m_severity = 0; return true; @@ -71,21 +71,5 @@ bool Severity::init(std::string *error) { } -bool Severity::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - ms_dbg_a(transaction, 9, "This rule severity is: " + \ - std::to_string(this->m_severity) + " current transaction is: " + \ - std::to_string(transaction->m_highestSeverityAction)); - - rm->m_severity = m_severity; - - if (transaction->m_highestSeverityAction > this->m_severity) { - transaction->m_highestSeverityAction = this->m_severity; - } - - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/severity.h b/src/actions/severity.h index b9cd812007..d40d102fda 100644 --- a/src/actions/severity.h +++ b/src/actions/severity.h @@ -13,38 +13,41 @@ * */ + #include #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_SEVERITY_H_ #define SRC_ACTIONS_SEVERITY_H_ -#ifdef __cplusplus namespace modsecurity { -class Transaction; - namespace actions { -class Severity : public Action { +class Severity : public ActionTypeRuleMetaData { public: - explicit Severity(const std::string &action) + explicit Severity(const std::string &action) : Action(action), - m_severity(0) { } + m_severity(0) + { } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; bool init(std::string *error) override; + void configure(RuleWithActions *rule) override { + rule->setSeverity(m_severity); + } + + private: int m_severity; }; } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_SEVERITY_H_ diff --git a/src/actions/skip.cc b/src/actions/skip.cc index 1f7d208118..994e9e91df 100644 --- a/src/actions/skip.cc +++ b/src/actions/skip.cc @@ -13,14 +13,18 @@ * */ + #include "src/actions/skip.h" -#include #include -#include "modsecurity/rules_set.h" -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + namespace modsecurity { namespace actions { @@ -28,9 +32,9 @@ namespace actions { bool Skip::init(std::string *error) { try { - m_skip_next = std::stoi(m_parser_payload); + m_skip_next = std::stoi(m_parserPayload); } catch (...) { - error->assign("Skip: The input \"" + m_parser_payload + "\" is " \ + error->assign("Skip: The input \"" + m_parserPayload + "\" is " \ "not a number."); return false; } @@ -38,7 +42,7 @@ bool Skip::init(std::string *error) { } -bool Skip::evaluate(RuleWithActions *rule, Transaction *transaction) { +bool Skip::execute(Transaction *transaction) const noexcept { ms_dbg_a(transaction, 5, "Skipping the next " + \ std::to_string(m_skip_next) + " rules."); diff --git a/src/actions/skip.h b/src/actions/skip.h index 97d2c50f78..6d362eb5c2 100644 --- a/src/actions/skip.h +++ b/src/actions/skip.h @@ -13,9 +13,12 @@ * */ + #include #include "modsecurity/actions/action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SKIP_H_ #define SRC_ACTIONS_SKIP_H_ @@ -27,15 +30,16 @@ class Transaction; namespace actions { -class Skip : public Action { +class Skip : public ActionWithExecution { public: - explicit Skip(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), + explicit Skip(const std::string &action) + : Action(action), m_skip_next(0) { } bool init(std::string *error) override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + bool execute(Transaction *transaction) const noexcept override; + private: int m_skip_next; }; diff --git a/src/actions/skip_after.cc b/src/actions/skip_after.cc index dce03d499c..61daf11535 100644 --- a/src/actions/skip_after.cc +++ b/src/actions/skip_after.cc @@ -13,21 +13,24 @@ * */ + #include "src/actions/skip_after.h" -#include #include -#include "modsecurity/rules_set.h" -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { -bool SkipAfter::evaluate(RuleWithActions *rule, Transaction *transaction) { +bool SkipAfter::execute(Transaction *transaction) const noexcept { ms_dbg_a(transaction, 5, "Setting skipAfter for: " + *m_skipName); transaction->addMarker(m_skipName); return true; diff --git a/src/actions/skip_after.h b/src/actions/skip_after.h index 8a2148d8ed..eee6e8263f 100644 --- a/src/actions/skip_after.h +++ b/src/actions/skip_after.h @@ -13,34 +13,39 @@ * */ + #include #include #include "modsecurity/actions/action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_SKIP_AFTER_H_ #define SRC_ACTIONS_SKIP_AFTER_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class SkipAfter : public Action { +class SkipAfter : public ActionWithExecution { public: - explicit SkipAfter(const std::string &action) - : Action(action, RunTimeOnlyIfMatchKind), - m_skipName(std::make_shared(m_parser_payload)) { } + explicit SkipAfter(const std::string &action) + : Action(action), + m_skipName(std::make_shared(m_parserPayload)) + { } + + bool execute(Transaction *transaction) const noexcept override; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; private: - std::shared_ptr m_skipName; + // FIXME: This should be a regular pointer instead of a shared pointer. + std::shared_ptr m_skipName; }; } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_SKIP_AFTER_H_ diff --git a/src/actions/tag.cc b/src/actions/tag.cc index 3ec06cd126..a880d483f5 100644 --- a/src/actions/tag.cc +++ b/src/actions/tag.cc @@ -13,16 +13,18 @@ * */ + #include "src/actions/tag.h" -#include #include -#include -#include "modsecurity/actions/action.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" -#include "modsecurity/rule_message.h" +/** + * FIXME: rules_set.h inclusion is here due to ms_dbg_a. + * It should be removed. + */ +#include "modsecurity/rules_set.h" + /** * Description: Assigns a tag (category) to a rule or a chain. @@ -50,19 +52,8 @@ namespace modsecurity { namespace actions { -std::string Tag::getName(Transaction *transaction) { - std::string tag(m_string->evaluate(transaction)); - return tag; -} - - -bool Tag::evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) { - std::string tag = getName(transaction); - ms_dbg_a(transaction, 9, "Rule tag: " + tag); - - rm->m_tags.push_back(tag); - +bool Tag::execute(Transaction *transaction) const noexcept { + ms_dbg_a(transaction, 9, "Rule tag: " + getTagName(transaction)); return true; } diff --git a/src/actions/tag.h b/src/actions/tag.h index 45d77892ff..e11605acc6 100644 --- a/src/actions/tag.h +++ b/src/actions/tag.h @@ -13,36 +13,48 @@ * */ + #include #include #include #include "modsecurity/actions/action.h" -#include "src/run_time_string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/action_allowed_in_sec_default_action.h" +#include "src/actions/action_with_execution.h" + #ifndef SRC_ACTIONS_TAG_H_ #define SRC_ACTIONS_TAG_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Tag : public Action { +class Tag : public ActionWithRunTimeString, + public ActionAllowedAsSecDefaultAction, public ActionWithExecution { public: - explicit Tag(std::unique_ptr z) - : Action("tag", RunTimeOnlyIfMatchKind), - m_string(std::move(z)) { } + explicit Tag(std::unique_ptr runTimeString) + : ActionWithRunTimeString(std::move(runTimeString)), + Action("tag") + { } + + explicit Tag(const Tag &action) + : ActionWithRunTimeString(action), + Action(action) + { } + + bool execute(Transaction *transaction) const noexcept override; - std::string getName(Transaction *transaction); + inline std::string getTagName(Transaction *transaction) const { + return getEvaluatedRunTimeString(transaction); + } - bool evaluate(RuleWithActions *rule, Transaction *transaction, - std::shared_ptr rm) override; - protected: - std::unique_ptr m_string; + ActionWithRunTimeString *clone() override { + return new Tag(*this); + } }; diff --git a/src/actions/transformations/base64_decode.cc b/src/actions/transformations/base64_decode.cc index e72fefea49..eda000c1ac 100644 --- a/src/actions/transformations/base64_decode.cc +++ b/src/actions/transformations/base64_decode.cc @@ -13,17 +13,13 @@ * */ + #include "src/actions/transformations/base64_decode.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" @@ -32,11 +28,12 @@ namespace actions { namespace transformations { -std::string Base64Decode::evaluate(const std::string &value, - Transaction *transaction) { +void Base64Decode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + std::string value(in.c_str(), in.size()); std::string ret = Utils::Base64::decode(value); - - return ret; + out.assign(ret.c_str(), ret.size()); } diff --git a/src/actions/transformations/base64_decode.h b/src/actions/transformations/base64_decode.h index 6676a99e67..bfaa5275b3 100644 --- a/src/actions/transformations/base64_decode.h +++ b/src/actions/transformations/base64_decode.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Base64Decode : public Transformation { public: - explicit Base64Decode(const std::string &action) : Transformation(action) { } + Base64Decode() + : Action("t:base64Decode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_ diff --git a/src/actions/transformations/base64_decode_ext.cc b/src/actions/transformations/base64_decode_ext.cc index 3ea9887c47..a267ccac7d 100644 --- a/src/actions/transformations/base64_decode_ext.cc +++ b/src/actions/transformations/base64_decode_ext.cc @@ -13,17 +13,13 @@ * */ + #include "src/actions/transformations/base64_decode_ext.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" @@ -32,11 +28,11 @@ namespace actions { namespace transformations { -std::string Base64DecodeExt::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::decode_forgiven(value); - - return ret; +void Base64DecodeExt::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + std::string ret = Utils::Base64::decode_forgiven(in.c_str()); + out.assign(ret.c_str(), ret.size()); } diff --git a/src/actions/transformations/base64_decode_ext.h b/src/actions/transformations/base64_decode_ext.h index 595e31f259..c08c2c7f23 100644 --- a/src/actions/transformations/base64_decode_ext.h +++ b/src/actions/transformations/base64_decode_ext.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Base64DecodeExt : public Transformation { public: - explicit Base64DecodeExt(const std::string &action) : Transformation(action) { } + Base64DecodeExt() + : Action("t:base64DecodeExt") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_ diff --git a/src/actions/transformations/base64_encode.cc b/src/actions/transformations/base64_encode.cc index ffc2465a09..6a3d740abb 100644 --- a/src/actions/transformations/base64_encode.cc +++ b/src/actions/transformations/base64_encode.cc @@ -13,17 +13,13 @@ * */ + #include "src/actions/transformations/base64_encode.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" #include "src/utils/base64.h" @@ -32,11 +28,12 @@ namespace actions { namespace transformations { -std::string Base64Encode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Base64::encode(value); - - return ret; +void Base64Encode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + std::string ret = Utils::Base64::encode( + std::string(in.c_str(), in.size())); + out.assign(ret.c_str(), ret.size()); } diff --git a/src/actions/transformations/base64_encode.h b/src/actions/transformations/base64_encode.h index a5dfd0bae0..c953187868 100644 --- a/src/actions/transformations/base64_encode.h +++ b/src/actions/transformations/base64_encode.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Base64Encode : public Transformation { public: - explicit Base64Encode(const std::string &action) : Transformation(action) { } + Base64Encode() + : Action("t:base64Encode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_ diff --git a/src/actions/transformations/cmd_line.cc b/src/actions/transformations/cmd_line.cc index 8fd73e814e..edf0befc71 100644 --- a/src/actions/transformations/cmd_line.cc +++ b/src/actions/transformations/cmd_line.cc @@ -15,15 +15,10 @@ #include "src/actions/transformations/cmd_line.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -31,12 +26,12 @@ namespace actions { namespace transformations { -std::string CmdLine::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void CmdLine::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int space = 0; - for (auto& a : value) { + for (auto& a : in) { switch (a) { /* remove some characters */ case '"': @@ -53,7 +48,7 @@ std::string CmdLine::evaluate(const std::string &value, case '\r': case '\n': if (space == 0) { - ret.append(" "); + out.append(" "); space++; } break; @@ -62,22 +57,20 @@ std::string CmdLine::evaluate(const std::string &value, case '/': case '(': if (space) { - ret.pop_back(); + out.pop_back(); } space = 0; - ret.append(&a, 1); + out.append(&a, 1); break; /* copy normal characters */ default : char b = std::tolower(a); - ret.append(&b, 1); + out.append(&b, 1); space = 0; break; } } - - return ret; } diff --git a/src/actions/transformations/cmd_line.h b/src/actions/transformations/cmd_line.h index 81baf84811..0c92edd0a0 100644 --- a/src/actions/transformations/cmd_line.h +++ b/src/actions/transformations/cmd_line.h @@ -13,35 +13,40 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class CmdLine : public Transformation { public: - explicit CmdLine(const std::string &action) - : Transformation(action) { } + CmdLine() + : Action("t:cmdLine") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_ diff --git a/src/actions/transformations/compress_whitespace.cc b/src/actions/transformations/compress_whitespace.cc index 3a0518d79c..319367bf0d 100644 --- a/src/actions/transformations/compress_whitespace.cc +++ b/src/actions/transformations/compress_whitespace.cc @@ -13,54 +13,45 @@ * */ + #include "src/actions/transformations/compress_whitespace.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -CompressWhitespace::CompressWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string CompressWhitespace::evaluate(const std::string &value, - Transaction *transaction) { - std::string a; +void CompressWhitespace::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int inWhiteSpace = 0; - int i = 0; + size_t i = 0; + out.reserve(in.size()); - while (i < value.size()) { - if (isspace(value[i])) { + while (i < in.size()) { + if (isspace(in[i])) { if (inWhiteSpace) { i++; continue; } else { inWhiteSpace = 1; - a.append(" ", 1); + out.append(" ", 1); } } else { inWhiteSpace = 0; - a.append(&value.at(i), 1); + out.append(&in.at(i), 1); } i++; } - - return a; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/compress_whitespace.h b/src/actions/transformations/compress_whitespace.h index d8b193703e..ba4c56f285 100644 --- a/src/actions/transformations/compress_whitespace.h +++ b/src/actions/transformations/compress_whitespace.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class CompressWhitespace : public Transformation { public: + CompressWhitespace() + : Action("t:compressWhitespace") + { } - explicit CompressWhitespace(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_ diff --git a/src/actions/transformations/css_decode.cc b/src/actions/transformations/css_decode.cc index 4b23618f1a..afaaa2d0b0 100644 --- a/src/actions/transformations/css_decode.cc +++ b/src/actions/transformations/css_decode.cc @@ -13,19 +13,14 @@ * */ -#include "src/actions/transformations/css_decode.h" -#include +#include "src/actions/transformations/css_decode.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" @@ -34,20 +29,22 @@ namespace actions { namespace transformations { -std::string CssDecode::evaluate(const std::string &value, - Transaction *transaction) { +void CssDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + size_t s = in.size(); char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; + malloc(sizeof(char) * s + 1)); + memcpy(tmp, in.c_str(), s + 1); + tmp[s] = '\0'; - CssDecode::css_decode_inplace(reinterpret_cast(tmp), - value.size()); + size_t r = CssDecode::css_decode_inplace( + reinterpret_cast(tmp), + s); - std::string ret(tmp, 0, value.size()); + out.assign(tmp, r); free(tmp); - return ret; } diff --git a/src/actions/transformations/css_decode.h b/src/actions/transformations/css_decode.h index 5d41e04d5b..c584ee5b5c 100644 --- a/src/actions/transformations/css_decode.h +++ b/src/actions/transformations/css_decode.h @@ -13,30 +13,37 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { class CssDecode : public Transformation { public: - explicit CssDecode(const std::string &action) - : Transformation(action) { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + CssDecode() + : Action("t:cssDecode") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; - static int css_decode_inplace(unsigned char *input, int64_t input_len); + private: + static int css_decode_inplace(unsigned char *input, + int64_t input_len); }; @@ -44,6 +51,5 @@ class CssDecode : public Transformation { } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_ diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index e32a42d062..3bbcf9d27a 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -13,29 +13,21 @@ * */ + #include "src/actions/transformations/escape_seq_decode.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" + namespace modsecurity { namespace actions { namespace transformations { -EscapeSeqDecode::EscapeSeqDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, int input_len) { @@ -140,21 +132,17 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, } -std::string EscapeSeqDecode::evaluate(const std::string &value, - Transaction *transaction) { - +void EscapeSeqDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *tmp = (unsigned char *) malloc(sizeof(char) - * value.size() + 1); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; + * in.size() + 1); + memcpy(tmp, in.c_str(), in.size() + 1); + tmp[in.size()] = '\0'; - int size = ansi_c_sequences_decode_inplace(tmp, value.size()); - - std::string ret(""); - ret.assign(reinterpret_cast(tmp), size); + int size = ansi_c_sequences_decode_inplace(tmp, in.size()); + out.assign(reinterpret_cast(tmp), size); free(tmp); - - return ret; } } // namespace transformations diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index 654548aa85..9dd4f29608 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -13,35 +13,43 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class EscapeSeqDecode : public Transformation { public: + EscapeSeqDecode() + : Action("t:escapeSeqDecode") + { } - explicit EscapeSeqDecode(const std::string &action) ; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); + private: + static int ansi_c_sequences_decode_inplace(unsigned char *input, + int input_len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_ diff --git a/src/actions/transformations/hex_decode.cc b/src/actions/transformations/hex_decode.cc index bc72228fc6..b90bf1a0e7 100644 --- a/src/actions/transformations/hex_decode.cc +++ b/src/actions/transformations/hex_decode.cc @@ -13,46 +13,43 @@ * */ + #include "src/actions/transformations/hex_decode.h" -#include #include -#include -#include -#include -#include -#include #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + +#include "modsecurity/modsecurity.h" +#include "modsecurity/transaction.h" + #include "src/utils/string.h" + namespace modsecurity { namespace actions { namespace transformations { -std::string HexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void HexDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; int size = 0; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - size = inplace(input, value.length()); + size = inplace(input, in.length()); - ret.assign(reinterpret_cast(input), size); + out.assign(reinterpret_cast(input), size); free(input); - - return ret; } diff --git a/src/actions/transformations/hex_decode.h b/src/actions/transformations/hex_decode.h index 8f8aa2ebb2..4af8bfc962 100644 --- a/src/actions/transformations/hex_decode.h +++ b/src/actions/transformations/hex_decode.h @@ -13,35 +13,42 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class HexDecode : public Transformation { public: - explicit HexDecode(const std::string &action) : Transformation(action) { } + HexDecode() + : Action("t:hexDecode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + private: static int inplace(unsigned char *data, int len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_ diff --git a/src/actions/transformations/hex_encode.cc b/src/actions/transformations/hex_encode.cc index 912c6f2760..b1676f2241 100644 --- a/src/actions/transformations/hex_encode.cc +++ b/src/actions/transformations/hex_encode.cc @@ -13,41 +13,33 @@ * */ + #include "src/actions/transformations/hex_encode.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -HexEncode::HexEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string HexEncode::evaluate(const std::string &value, - Transaction *transaction) { +void HexEncode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { std::stringstream result; - for (std::size_t i=0; i < value.length(); i++) { - unsigned int ii = (unsigned char)(value[i]); + for (std::size_t i=0; i < in.length(); i++) { + int ii = reinterpret_cast(in[i]); result << std::setw(2) << std::setfill('0') << std::hex << ii; } - return result.str(); + out.assign(result.str().c_str()); } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/hex_encode.h b/src/actions/transformations/hex_encode.h index b76e2672fd..545bf046e7 100644 --- a/src/actions/transformations/hex_encode.h +++ b/src/actions/transformations/hex_encode.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class HexEncode : public Transformation { public: + HexEncode() + : Action("t:hexEncode") + { } - explicit HexEncode(const std::string &action); - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_ diff --git a/src/actions/transformations/html_entity_decode.cc b/src/actions/transformations/html_entity_decode.cc index 48257e76ef..6e922ff0b8 100644 --- a/src/actions/transformations/html_entity_decode.cc +++ b/src/actions/transformations/html_entity_decode.cc @@ -13,19 +13,15 @@ * */ -#include "src/actions/transformations/html_entity_decode.h" -#include +#include "src/actions/transformations/html_entity_decode.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + +#include "src/utils/string.h" namespace modsecurity { @@ -33,26 +29,24 @@ namespace actions { namespace transformations { -std::string HtmlEntityDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void HtmlEntityDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - size_t i = inplace(input, value.length()); + size_t i = inplace(input, in.length()); - ret.assign(reinterpret_cast(input), i); + out.assign(reinterpret_cast(input), i); free(input); - - return ret; } diff --git a/src/actions/transformations/html_entity_decode.h b/src/actions/transformations/html_entity_decode.h index eaf5ae0b31..5413dd0754 100644 --- a/src/actions/transformations/html_entity_decode.h +++ b/src/actions/transformations/html_entity_decode.h @@ -13,32 +13,35 @@ * */ + #include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" -#include "src/utils/string.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { class HtmlEntityDecode : public Transformation { public: - explicit HtmlEntityDecode(const std::string &action) - : Transformation(action) { } + HtmlEntityDecode() + : Action("t:htmlEntityDecode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + private: static int inplace(unsigned char *input, uint64_t input_len); }; @@ -47,6 +50,5 @@ class HtmlEntityDecode : public Transformation { } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_ diff --git a/src/actions/transformations/js_decode.cc b/src/actions/transformations/js_decode.cc index 89f33b9f0f..e659457c08 100644 --- a/src/actions/transformations/js_decode.cc +++ b/src/actions/transformations/js_decode.cc @@ -13,19 +13,14 @@ * */ -#include "src/actions/transformations/js_decode.h" -#include +#include "src/actions/transformations/js_decode.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" @@ -34,26 +29,24 @@ namespace actions { namespace transformations { -std::string JsDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void JsDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - size_t i = inplace(input, value.length()); + size_t i = inplace(input, in.length()); - ret.assign(reinterpret_cast(input), i); + out.assign(reinterpret_cast(input), i); free(input); - - return ret; } diff --git a/src/actions/transformations/js_decode.h b/src/actions/transformations/js_decode.h index e680aebca3..b0c15cda51 100644 --- a/src/actions/transformations/js_decode.h +++ b/src/actions/transformations/js_decode.h @@ -13,35 +13,42 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class JsDecode : public Transformation { public: - explicit JsDecode(const std::string &action) - : Transformation(action) { } + JsDecode() + : Action("t:jsDecode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + + private: static int inplace(unsigned char *input, uint64_t input_len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_ diff --git a/src/actions/transformations/length.cc b/src/actions/transformations/length.cc index e27cd41b86..7aaeadcf66 100644 --- a/src/actions/transformations/length.cc +++ b/src/actions/transformations/length.cc @@ -13,32 +13,24 @@ * */ + #include "src/actions/transformations/length.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -Length::Length(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string Length::evaluate(const std::string &value, - Transaction *transaction) { - return std::to_string(value.size()); +void Length::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out.assign(std::to_string(in.size()).c_str()); } } // namespace transformations diff --git a/src/actions/transformations/length.h b/src/actions/transformations/length.h index 7974b5c105..38227be756 100644 --- a/src/actions/transformations/length.h +++ b/src/actions/transformations/length.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Length : public Transformation { public: + Length() + : Action("t:length") + { }; - explicit Length(const std::string &action); - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_ diff --git a/src/actions/transformations/lower_case.cc b/src/actions/transformations/lower_case.cc index fcf3ba79df..1fb39c29f2 100644 --- a/src/actions/transformations/lower_case.cc +++ b/src/actions/transformations/lower_case.cc @@ -13,35 +13,28 @@ * */ + #include "src/actions/transformations/lower_case.h" #include #include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" + namespace modsecurity { namespace actions { namespace transformations { -LowerCase::LowerCase(const std::string &a) - : Transformation(a) { +void LowerCase::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out.resize(in.size()); + std::transform(in.begin(), in.end(), out.begin(), ::tolower); } -std::string LowerCase::evaluate(const std::string &val, - Transaction *transaction) { - std::locale loc; - std::string value(val); - - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::tolower(value[i], loc); - } - - return value; -} } // namespace transformations } // namespace actions diff --git a/src/actions/transformations/lower_case.h b/src/actions/transformations/lower_case.h index 12eee32114..b072a0379d 100644 --- a/src/actions/transformations/lower_case.h +++ b/src/actions/transformations/lower_case.h @@ -13,34 +13,39 @@ * */ + #include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ -#ifdef __cplusplus namespace modsecurity { -class Transaction; namespace actions { namespace transformations { class LowerCase : public Transformation { public: - explicit LowerCase(const std::string &action); - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + LowerCase() + : Action("t:lowerCase") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_ diff --git a/src/actions/transformations/md5.cc b/src/actions/transformations/md5.cc index 8becdb2681..4e833fa5e8 100644 --- a/src/actions/transformations/md5.cc +++ b/src/actions/transformations/md5.cc @@ -13,17 +13,14 @@ * */ + #include "src/actions/transformations/md5.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/md5.h" namespace modsecurity { @@ -31,11 +28,12 @@ namespace actions { namespace transformations { -std::string Md5::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret = Utils::Md5::digest(value); +void Md5::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + std::string ret = Utils::Md5::digest(std::string(in.c_str(), in.size())); - return ret; + out.assign(ret.c_str(), ret.size()); } diff --git a/src/actions/transformations/md5.h b/src/actions/transformations/md5.h index 1742b8b541..7cae8fe15c 100644 --- a/src/actions/transformations/md5.h +++ b/src/actions/transformations/md5.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ #define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Md5 : public Transformation { public: - explicit Md5(const std::string &action) : Transformation(action) { } + Md5() + : Action("t:md5") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_ diff --git a/src/actions/transformations/none.cc b/src/actions/transformations/none.cc index 79ab0b844b..425c371db0 100644 --- a/src/actions/transformations/none.cc +++ b/src/actions/transformations/none.cc @@ -13,17 +13,13 @@ * */ + #include "src/actions/transformations/none.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -31,10 +27,9 @@ namespace actions { namespace transformations { -std::string None::evaluate(const std::string &value, - Transaction *transaction) { - return value; -} +void None::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { } } // namespace transformations diff --git a/src/actions/transformations/none.h b/src/actions/transformations/none.h index 00bf37a76b..30a22d90ff 100644 --- a/src/actions/transformations/none.h +++ b/src/actions/transformations/none.h @@ -13,35 +13,40 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class None : public Transformation { public: - explicit None(const std::string &action) - : Transformation(action) - { m_isNone = true; } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + None() + : + Action("t:none") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_ diff --git a/src/actions/transformations/normalise_path.cc b/src/actions/transformations/normalise_path.cc index ad76a22a46..fee87f3b35 100644 --- a/src/actions/transformations/normalise_path.cc +++ b/src/actions/transformations/normalise_path.cc @@ -13,47 +13,36 @@ * */ -#include "src/actions/transformations/normalise_path.h" -#include +#include "src/actions/transformations/normalise_path.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -NormalisePath::NormalisePath(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} -std::string NormalisePath::evaluate(const std::string &value, - Transaction *transaction) { +void NormalisePath::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int changed = 0; char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; + malloc(sizeof(char) * in.size() + 1)); + memcpy(tmp, in.c_str(), in.size() + 1); + tmp[in.size()] = '\0'; int i = normalize_path_inplace((unsigned char *)tmp, - value.size(), 0, &changed); + in.size(), 0, &changed); std::string ret(""); - ret.assign(tmp, i); + out.assign(tmp, i); free(tmp); - - return ret; } diff --git a/src/actions/transformations/normalise_path.h b/src/actions/transformations/normalise_path.h index 3c98d7f95d..3015637e21 100644 --- a/src/actions/transformations/normalise_path.h +++ b/src/actions/transformations/normalise_path.h @@ -13,37 +13,42 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class NormalisePath : public Transformation { public: + NormalisePath() + : Action("t:normalisePath") + { } - explicit NormalisePath(const std::string &action); - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; static int normalize_path_inplace(unsigned char *input, int input_len, int win, int *changed); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_ diff --git a/src/actions/transformations/normalise_path_win.cc b/src/actions/transformations/normalise_path_win.cc index 8970e8b968..5f8b0c76e3 100644 --- a/src/actions/transformations/normalise_path_win.cc +++ b/src/actions/transformations/normalise_path_win.cc @@ -13,19 +13,16 @@ * */ + #include "src/actions/transformations/normalise_path_win.h" #include - -#include #include -#include -#include -#include -#include + +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/actions/transformations/normalise_path.h" @@ -34,24 +31,23 @@ namespace actions { namespace transformations { -std::string NormalisePathWin::evaluate(const std::string &value, - Transaction *transaction) { +void NormalisePathWin::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int changed; char *tmp = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; + malloc(sizeof(char) * in.size() + 1)); + memcpy(tmp, in.c_str(), in.size() + 1); + tmp[in.size()] = '\0'; int i = NormalisePath::normalize_path_inplace( reinterpret_cast(tmp), - value.size(), 1, &changed); + in.size(), 1, &changed); std::string ret(""); - ret.assign(tmp, i); + out.assign(tmp, i); free(tmp); - - return ret; } diff --git a/src/actions/transformations/normalise_path_win.h b/src/actions/transformations/normalise_path_win.h index 61ce0ca0b1..e919a87e0c 100644 --- a/src/actions/transformations/normalise_path_win.h +++ b/src/actions/transformations/normalise_path_win.h @@ -13,30 +13,36 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ #define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_ namespace modsecurity { -class Transaction; - namespace actions { namespace transformations { + class NormalisePathWin : public Transformation { public: - explicit NormalisePathWin(const std::string &action) - : Transformation(action) { } + NormalisePathWin() + : Action("t:normalisePathWin") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/parity_even_7bit.cc b/src/actions/transformations/parity_even_7bit.cc index 357fe7594c..ce7a313cd2 100644 --- a/src/actions/transformations/parity_even_7bit.cc +++ b/src/actions/transformations/parity_even_7bit.cc @@ -13,18 +13,13 @@ * */ + #include "src/actions/transformations/parity_even_7bit.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -32,28 +27,27 @@ namespace actions { namespace transformations { -std::string ParityEven7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void ParityEven7bit::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - std::memcpy(input, value.c_str(), value.length()+1); + std::memcpy(input, in.c_str(), in.length()+1); - inplace(input, value.length()); + inplace(input, in.length()); - ret.assign(reinterpret_cast(input), value.length()); + out.assign(reinterpret_cast(input), in.length()); free(input); - - return ret; } + bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) { uint64_t i; @@ -76,7 +70,6 @@ bool ParityEven7bit::inplace(unsigned char *input, uint64_t input_len) { } - } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/parity_even_7bit.h b/src/actions/transformations/parity_even_7bit.h index 7ec5f2aabe..d73b6d7a61 100644 --- a/src/actions/transformations/parity_even_7bit.h +++ b/src/actions/transformations/parity_even_7bit.h @@ -13,33 +13,42 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class ParityEven7bit : public Transformation { public: - explicit ParityEven7bit(const std::string &action) : Transformation(action) { } + ParityEven7bit() + : Action("t:parityEven7bit") + { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + + private: static bool inplace(unsigned char *input, uint64_t input_len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_ diff --git a/src/actions/transformations/parity_odd_7bit.cc b/src/actions/transformations/parity_odd_7bit.cc index fbd6c8fcc2..735f3e93e7 100644 --- a/src/actions/transformations/parity_odd_7bit.cc +++ b/src/actions/transformations/parity_odd_7bit.cc @@ -13,18 +13,13 @@ * */ + #include "src/actions/transformations/parity_odd_7bit.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -32,28 +27,27 @@ namespace actions { namespace transformations { -std::string ParityOdd7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void ParityOdd7bit::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - inplace(input, value.length()); + inplace(input, in.length()); - ret.assign(reinterpret_cast(input), value.length()); + out.assign(reinterpret_cast(input), in.length()); free(input); - - return ret; } + bool ParityOdd7bit::inplace(unsigned char *input, uint64_t input_len) { uint64_t i; diff --git a/src/actions/transformations/parity_odd_7bit.h b/src/actions/transformations/parity_odd_7bit.h index 9af53722aa..3442e1add5 100644 --- a/src/actions/transformations/parity_odd_7bit.h +++ b/src/actions/transformations/parity_odd_7bit.h @@ -13,33 +13,43 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class ParityOdd7bit : public Transformation { public: - explicit ParityOdd7bit(const std::string &action) : Transformation(action) { } + ParityOdd7bit() + : Action("t:parityOdd7bit") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; - std::string evaluate(const std::string &exp, Transaction *transaction) override; + private: static bool inplace(unsigned char *input, uint64_t input_len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif + #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_ diff --git a/src/actions/transformations/parity_zero_7bit.cc b/src/actions/transformations/parity_zero_7bit.cc index 93a0f974e2..6ddd8ef312 100644 --- a/src/actions/transformations/parity_zero_7bit.cc +++ b/src/actions/transformations/parity_zero_7bit.cc @@ -13,18 +13,13 @@ * */ + #include "src/actions/transformations/parity_zero_7bit.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -32,26 +27,24 @@ namespace actions { namespace transformations { -std::string ParityZero7bit::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void ParityZero7bit::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - inplace(input, value.length()); + inplace(input, in.length()); - ret.assign(reinterpret_cast(input), value.length()); + out.assign(reinterpret_cast(input), in.length()); free(input); - - return ret; } diff --git a/src/actions/transformations/parity_zero_7bit.h b/src/actions/transformations/parity_zero_7bit.h index 5e30dd5d0d..e0bd4b7606 100644 --- a/src/actions/transformations/parity_zero_7bit.h +++ b/src/actions/transformations/parity_zero_7bit.h @@ -13,33 +13,42 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class ParityZero7bit : public Transformation { public: - explicit ParityZero7bit(const std::string &action) : Transformation(action) { } + ParityZero7bit() + : Action("t:parityZero7bit") + { } - std::string evaluate(const std::string &exp, Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + + private: static bool inplace(unsigned char *input, uint64_t input_len); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_ diff --git a/src/actions/transformations/remove_comments.cc b/src/actions/transformations/remove_comments.cc index 4bce61b55e..4fcdcac5e8 100644 --- a/src/actions/transformations/remove_comments.cc +++ b/src/actions/transformations/remove_comments.cc @@ -13,18 +13,13 @@ * */ + #include "src/actions/transformations/remove_comments.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -32,21 +27,21 @@ namespace actions { namespace transformations { -std::string RemoveComments::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void RemoveComments::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - uint64_t input_len = value.size(); + uint64_t input_len = in.size(); uint64_t i, j, incomment; i = j = incomment = 0; @@ -100,10 +95,8 @@ std::string RemoveComments::evaluate(const std::string &value, input[j++] = ' '; } - ret.assign(reinterpret_cast(input), j); + out.assign(reinterpret_cast(input), j); free(input); - - return ret; } diff --git a/src/actions/transformations/remove_comments.h b/src/actions/transformations/remove_comments.h index 46ad2a7e92..fca978e4b8 100644 --- a/src/actions/transformations/remove_comments.h +++ b/src/actions/transformations/remove_comments.h @@ -13,28 +13,32 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { class RemoveComments : public Transformation { public: - explicit RemoveComments(const std::string &action) : Transformation(action) { } + RemoveComments() + : Action("t:removeComments") { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override;; }; @@ -42,6 +46,5 @@ class RemoveComments : public Transformation { } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_ diff --git a/src/actions/transformations/remove_comments_char.cc b/src/actions/transformations/remove_comments_char.cc index 68bd28c314..132a2f178d 100644 --- a/src/actions/transformations/remove_comments_char.cc +++ b/src/actions/transformations/remove_comments_char.cc @@ -13,65 +13,58 @@ * */ + #include "src/actions/transformations/remove_comments_char.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -RemoveCommentsChar::RemoveCommentsChar(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} -std::string RemoveCommentsChar::evaluate(const std::string &val, - Transaction *transaction) { +void RemoveCommentsChar::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int64_t i; - std::string value(val); + out = in; i = 0; - while (i < value.size()) { - if (value.at(i) == '/' - && (i+1 < value.size()) && value.at(i+1) == '*') { - value.erase(i, 2); - } else if (value.at(i) == '*' - && (i+1 < value.size()) && value.at(i+1) == '/') { - value.erase(i, 2); - } else if (value.at(i) == '<' - && (i+1 < value.size()) - && value.at(i+1) == '!' - && (i+2 < value.size()) - && value.at(i+2) == '-' - && (i+3 < value.size()) - && value.at(i+3) == '-') { - value.erase(i, 4); - } else if (value.at(i) == '-' - && (i+1 < value.size()) && value.at(i+1) == '-' - && (i+2 < value.size()) && value.at(i+2) == '>') { - value.erase(i, 3); - } else if (value.at(i) == '-' - && (i+1 < value.size()) && value.at(i+1) == '-') { - value.erase(i, 2); - } else if (value.at(i) == '#') { - value.erase(i, 1); + while (i < out.size()) { + if (out.at(i) == '/' + && (i+1 < out.size()) && out.at(i+1) == '*') { + out.erase(i, 2); + } else if (out.at(i) == '*' + && (i+1 < out.size()) && out.at(i+1) == '/') { + out.erase(i, 2); + } else if (out.at(i) == '<' + && (i+1 < out.size()) + && out.at(i+1) == '!' + && (i+2 < out.size()) + && out.at(i+2) == '-' + && (i+3 < out.size()) + && out.at(i+3) == '-') { + out.erase(i, 4); + } else if (out.at(i) == '-' + && (i+1 < out.size()) && out.at(i+1) == '-' + && (i+2 < out.size()) && out.at(i+2) == '>') { + out.erase(i, 3); + } else if (out.at(i) == '-' + && (i+1 < out.size()) && out.at(i+1) == '-') { + out.erase(i, 2); + } else if (out.at(i) == '#') { + out.erase(i, 1); } else { i++; } } - return value; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/remove_comments_char.h b/src/actions/transformations/remove_comments_char.h index 03091ceb2e..97d1099c34 100644 --- a/src/actions/transformations/remove_comments_char.h +++ b/src/actions/transformations/remove_comments_char.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class RemoveCommentsChar : public Transformation { public: - explicit RemoveCommentsChar(const std::string &action); + RemoveCommentsChar() + : Action("t:removeCommentsChar") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_ diff --git a/src/actions/transformations/remove_nulls.cc b/src/actions/transformations/remove_nulls.cc index 991956d001..1f6c4f73dc 100644 --- a/src/actions/transformations/remove_nulls.cc +++ b/src/actions/transformations/remove_nulls.cc @@ -13,19 +13,13 @@ * */ -#include "src/actions/transformations/remove_nulls.h" -#include +#include "src/actions/transformations/remove_nulls.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -33,21 +27,20 @@ namespace actions { namespace transformations { -std::string RemoveNulls::evaluate(const std::string &val, - Transaction *transaction) { +void RemoveNulls::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int64_t i; - std::string value(val); + out = in; i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value.erase(i, 1); + while (i < out.size()) { + if (out.at(i) == '\0') { + out.erase(i, 1); } else { i++; } } - - return value; } diff --git a/src/actions/transformations/remove_nulls.h b/src/actions/transformations/remove_nulls.h index 6d5a082037..664fdb1476 100644 --- a/src/actions/transformations/remove_nulls.h +++ b/src/actions/transformations/remove_nulls.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class RemoveNulls : public Transformation { public: - explicit RemoveNulls(const std::string &action) - : Transformation(action) { } + RemoveNulls() + : Action("t:removeNulls") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_ diff --git a/src/actions/transformations/remove_whitespace.cc b/src/actions/transformations/remove_whitespace.cc index a3687cc3a1..3e665057e7 100644 --- a/src/actions/transformations/remove_whitespace.cc +++ b/src/actions/transformations/remove_whitespace.cc @@ -13,40 +13,33 @@ * */ + #include "src/actions/transformations/remove_whitespace.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#define NBSP 160 // non breaking space char +#include "src/utils/string.h" + namespace modsecurity { namespace actions { namespace transformations { -RemoveWhitespace::RemoveWhitespace(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string RemoveWhitespace::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); +void RemoveWhitespace::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out = in; int64_t i = 0; // loop through all the chars - while (i < value.size()) { + while (i < out.size()) { // remove whitespaces and non breaking spaces (NBSP) - if (isspace(value[i]) || (value[i] == NBSP)) { - value.erase(i, 1); + if (isspace(out[i]) || (out[i] == NBSP)) { + out.erase(i, 1); } else { /* if the space is not a whitespace char, increment counter counter should not be incremented if a character is erased because @@ -54,10 +47,9 @@ std::string RemoveWhitespace::evaluate(const std::string &val, i++; } } - - return value; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/remove_whitespace.h b/src/actions/transformations/remove_whitespace.h index c2968ddc68..e4a388f640 100644 --- a/src/actions/transformations/remove_whitespace.h +++ b/src/actions/transformations/remove_whitespace.h @@ -13,33 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class RemoveWhitespace : public Transformation { public: - explicit RemoveWhitespace(const std::string &action); + RemoveWhitespace() + : Action("t:removeWhitespace") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_ diff --git a/src/actions/transformations/replace_comments.cc b/src/actions/transformations/replace_comments.cc index 6f0250cb0c..220a551fe8 100644 --- a/src/actions/transformations/replace_comments.cc +++ b/src/actions/transformations/replace_comments.cc @@ -13,42 +13,34 @@ * */ + #include "src/actions/transformations/replace_comments.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -ReplaceComments::ReplaceComments(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} -std::string ReplaceComments::evaluate(const std::string &value, - Transaction *transaction) { +void ReplaceComments::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { uint64_t i, j, incomment; char *input = reinterpret_cast( - malloc(sizeof(char) * value.size() + 1)); - memcpy(input, value.c_str(), value.size() + 1); - input[value.size()] = '\0'; + malloc(sizeof(char) * in.size() + 1)); + memcpy(input, in.c_str(), in.size() + 1); + input[in.size()] = '\0'; i = j = incomment = 0; - while (i < value.size()) { + while (i < in.size()) { if (incomment == 0) { - if ((input[i] == '/') && (i + 1 < value.size()) + if ((input[i] == '/') && (i + 1 < in.size()) && (input[i + 1] == '*')) { incomment = 1; i += 2; @@ -58,7 +50,7 @@ std::string ReplaceComments::evaluate(const std::string &value, j++; } } else { - if ((input[i] == '*') && (i + 1 < value.size()) + if ((input[i] == '*') && (i + 1 < in.size()) && (input[i + 1] == '/')) { incomment = 0; i += 2; @@ -74,13 +66,9 @@ std::string ReplaceComments::evaluate(const std::string &value, input[j++] = ' '; } - - std::string resp; - resp.append(reinterpret_cast(input), j); + out.append(reinterpret_cast(input), j); free(input); - - return resp; } } // namespace transformations diff --git a/src/actions/transformations/replace_comments.h b/src/actions/transformations/replace_comments.h index a2c06a4c49..024f6a20d1 100644 --- a/src/actions/transformations/replace_comments.h +++ b/src/actions/transformations/replace_comments.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class ReplaceComments : public Transformation { public: + ReplaceComments() + : Action("t:removeComments") + { } - explicit ReplaceComments(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_ diff --git a/src/actions/transformations/replace_nulls.cc b/src/actions/transformations/replace_nulls.cc index 7f20d0dadf..97b0ae24dc 100644 --- a/src/actions/transformations/replace_nulls.cc +++ b/src/actions/transformations/replace_nulls.cc @@ -13,46 +13,38 @@ * */ + #include "src/actions/transformations/replace_nulls.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" namespace modsecurity { namespace actions { namespace transformations { -ReplaceNulls::ReplaceNulls(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} -std::string ReplaceNulls::evaluate(const std::string &val, - Transaction *transaction) { +void ReplaceNulls::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int64_t i; - std::string value(val); + out = in; i = 0; - while (i < value.size()) { - if (value.at(i) == '\0') { - value.erase(i, 1); - value.insert(i, " ", 1); + while (i < out.size()) { + if (out.at(i) == '\0') { + out.erase(i, 1); + out.insert(i, " ", 1); } else { i++; } } - - return value; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/replace_nulls.h b/src/actions/transformations/replace_nulls.h index 7af92643f1..d16250049c 100644 --- a/src/actions/transformations/replace_nulls.h +++ b/src/actions/transformations/replace_nulls.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ #define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class ReplaceNulls : public Transformation { public: + ReplaceNulls() + : Action("t:replaceNulls") + { } - explicit ReplaceNulls(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_ diff --git a/src/actions/transformations/sha1.cc b/src/actions/transformations/sha1.cc index 0c30512acc..2460103291 100644 --- a/src/actions/transformations/sha1.cc +++ b/src/actions/transformations/sha1.cc @@ -13,17 +13,14 @@ * */ + #include "src/actions/transformations/sha1.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/sha1.h" @@ -31,17 +28,17 @@ namespace modsecurity { namespace actions { namespace transformations { -Sha1::Sha1(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} -std::string Sha1::evaluate(const std::string &value, - Transaction *transaction) { +void Sha1::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + auto a = Utils::Sha1::digest( + std::string(in.c_str(), in.size())); - return Utils::Sha1::digest(value); + out.assign(a.c_str(), a.size()); } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/sha1.h b/src/actions/transformations/sha1.h index 87e5aaa1e3..1437e6c910 100644 --- a/src/actions/transformations/sha1.h +++ b/src/actions/transformations/sha1.h @@ -13,32 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Sha1 : public Transformation { public: - explicit Sha1(const std::string &action) ; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + Sha1() + : Action("t:sha1") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_ diff --git a/src/actions/transformations/sql_hex_decode.cc b/src/actions/transformations/sql_hex_decode.cc index b33deac735..20676c34b4 100644 --- a/src/actions/transformations/sql_hex_decode.cc +++ b/src/actions/transformations/sql_hex_decode.cc @@ -13,18 +13,14 @@ * */ + #include "src/actions/transformations/sql_hex_decode.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" @@ -32,36 +28,26 @@ namespace modsecurity { namespace actions { namespace transformations { -#ifndef VALID_HEX -#define VALID_HEX(X) (((X >= '0') && (X <= '9')) \ - || ((X >= 'a') && (X <= 'f')) \ - || ((X >= 'A') && (X <= 'F'))) -#endif -#ifndef ISODIGIT -#define ISODIGIT(X) ((X >= '0') && (X <= '7')) -#endif - -std::string SqlHexDecode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; + +void SqlHexDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; int size = 0; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - size = inplace(input, value.length()); + size = inplace(input, in.length()); - ret.assign(reinterpret_cast(input), size); + out.assign(reinterpret_cast(input), size); free(input); - - return ret; } diff --git a/src/actions/transformations/sql_hex_decode.h b/src/actions/transformations/sql_hex_decode.h index 4ef5a63e48..fc6e979a1b 100644 --- a/src/actions/transformations/sql_hex_decode.h +++ b/src/actions/transformations/sql_hex_decode.h @@ -13,28 +13,34 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ -#ifdef __cplusplus namespace modsecurity { -class Transaction; - namespace actions { namespace transformations { + class SqlHexDecode : public Transformation { public: - explicit SqlHexDecode(const std::string &action) : Transformation(action) { } + SqlHexDecode() + : Action("t:sqlHexDecode") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + private: static int inplace(unsigned char *data, int len); static int mytolower(int ch) { @@ -45,10 +51,10 @@ class SqlHexDecode : public Transformation { } }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_ diff --git a/src/actions/transformations/transformation.cc b/src/actions/transformations/transformation.cc index fae80ee62d..cb4c78adb1 100644 --- a/src/actions/transformations/transformation.cc +++ b/src/actions/transformations/transformation.cc @@ -13,15 +13,14 @@ * */ -#include "src/actions/transformations/transformation.h" -#include +#include "src/actions/transformations/transformation.h" -#include #include #include "modsecurity/transaction.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/base64_decode_ext.h" #include "src/actions/transformations/base64_decode.h" #include "src/actions/transformations/base64_encode.h" @@ -60,65 +59,103 @@ #include "src/actions/transformations/utf8_to_unicode.h" -#define IF_MATCH(b) \ - if (a.compare(2, std::strlen(#b), #b) == 0) - - namespace modsecurity { namespace actions { namespace transformations { -std::string Transformation::evaluate(const std::string &value, - Transaction *transaction) { - return value; -} +class TransformationDoesNotExist : public std::exception { + public: + explicit TransformationDoesNotExist(const char *name) + : m_transformation(name) + { } + + explicit TransformationDoesNotExist(const std::string& name) + : m_transformation(name) + { } + + virtual ~TransformationDoesNotExist() throw (){} -Transformation* Transformation::instantiate(std::string a) { - IF_MATCH(base64DecodeExt) { return new Base64DecodeExt(a); } - IF_MATCH(base64Decode) { return new Base64Decode(a); } - IF_MATCH(base64Encode) { return new Base64Encode(a); } - IF_MATCH(cmd_line) { return new CmdLine(a); } - IF_MATCH(compress_whitespace) { return new CompressWhitespace(a); } - IF_MATCH(cssDecode) { return new CssDecode(a); } - IF_MATCH(escapeSeqDecode) { return new EscapeSeqDecode(a); } - IF_MATCH(hexDecode) { return new HexDecode(a); } - IF_MATCH(hexEncode) { return new HexEncode(a); } - IF_MATCH(htmlEntityDecode) { return new HtmlEntityDecode(a); } - IF_MATCH(jsDecode) { return new JsDecode(a); } - IF_MATCH(length) { return new Length(a); } - IF_MATCH(lowercase) { return new LowerCase(a); } - IF_MATCH(md5) { return new Md5(a); } - IF_MATCH(none) { return new None(a); } - IF_MATCH(normalizePathWin) { return new NormalisePathWin(a); } - IF_MATCH(normalisePathWin) { return new NormalisePathWin(a); } - IF_MATCH(normalizePath) { return new NormalisePath(a); } - IF_MATCH(normalisePath) { return new NormalisePath(a); } - IF_MATCH(parityEven7bit) { return new ParityEven7bit(a); } - IF_MATCH(parityOdd7bit) { return new ParityOdd7bit(a); } - IF_MATCH(parityZero7bit) { return new ParityZero7bit(a); } - IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); } - IF_MATCH(removeComments) { return new RemoveComments(a); } - IF_MATCH(removeNulls) { return new RemoveNulls(a); } - IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); } - IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); } - IF_MATCH(replaceComments) { return new ReplaceComments(a); } - IF_MATCH(replaceNulls) { return new ReplaceNulls(a); } - IF_MATCH(sha1) { return new Sha1(a); } - IF_MATCH(sqlHexDecode) { return new SqlHexDecode(a); } - IF_MATCH(transformation) { return new Transformation(a); } - IF_MATCH(trimLeft) { return new TrimLeft(a); } - IF_MATCH(trimRight) { return new TrimRight(a); } - IF_MATCH(trim) { return new Trim(a); } - IF_MATCH(uppercase) { return new UpperCase(a); } - IF_MATCH(urlDecodeUni) { return new UrlDecodeUni(a); } - IF_MATCH(urlDecode) { return new UrlDecode(a); } - IF_MATCH(urlEncode) { return new UrlEncode(a); } - IF_MATCH(utf8toUnicode) { return new Utf8ToUnicode(a); } - - return new Transformation(a); + virtual const char* what() const throw() { + return strdup(std::string("Transformation not found: " + m_transformation + \ + ". Make sure that the new transformation is registered at: " + \ + "transformation.cc").c_str()); + } + + private: + std::string m_transformation; +}; + + +Transformation* Transformation::instantiate( + const std::string &transformationName) { + /** + * + * FIXME: Once part of ModSecurity, the transformation needs to register + * here. That is necessary to load transformations from external + * resources such as Python and Lua, not to mention the + * unit/regression framework. + * + * Today this registration is manual; as seen below, the idea is to + * have those automatically generated. To avoid transformations not + * to be listed. + */ + + std::string name(transformationName); + name.erase(std::remove(name.begin(), name.end(), '_'), name.end()); + + if (match(name, "t:base64DecodeExt")) { return new Base64DecodeExt(); } + if (match(name, "t:base64Decode")) { return new Base64Decode(); } + if (match(name, "t:base64Encode")) { return new Base64Encode(); } + if (match(name, "t:cmdLine")) { return new CmdLine(); } + if (match(name, "t:compressWhitespace")) { + return new CompressWhitespace(); + } + if (match(name, "t:cssDecode")) { return new CssDecode(); } + if (match(name, "t:escapeSeqDecode")) { return new EscapeSeqDecode(); } + if (match(name, "t:hexDecode")) { return new HexDecode(); } + if (match(name, "t:hexEncode")) { return new HexEncode(); } + if (match(name, "t:htmlEntityDecode")) { return new HtmlEntityDecode(); } + if (match(name, "t:jsDecode")) { return new JsDecode(); } + if (match(name, "t:length")) { return new Length(); } + if (match(name, "t:lowercase")) { return new LowerCase(); } + if (match(name, "t:md5")) { return new Md5(); } + if (match(name, "t:none")) { return new None(); } + if (match(name, "t:normalizePathWin")) { return new NormalisePathWin(); } + if (match(name, "t:normalisePathWin")) { return new NormalisePathWin(); } + if (match(name, "t:normalizePath")) { return new NormalisePath(); } + if (match(name, "t:normalisePath")) { return new NormalisePath(); } + if (match(name, "t:parityEven7bit")) { return new ParityEven7bit(); } + if (match(name, "t:parityOdd7bit")) { return new ParityOdd7bit(); } + if (match(name, "t:parityZero7bit")) { return new ParityZero7bit(); } + if (match(name, "t:removeCommentsChar")) { + return new RemoveCommentsChar(); + } + if (match(name, "t:removeComments")) { return new RemoveComments(); } + if (match(name, "t:removeNulls")) { return new RemoveNulls(); } + if (match(name, "t:removeWhitespace")) { return new RemoveWhitespace(); } + if (match(name, "t:compressWhitespace")) { + return new CompressWhitespace(); + } + if (match(name, "t:replaceComments")) { return new ReplaceComments(); } + if (match(name, "t:replaceNulls")) { return new ReplaceNulls(); } + if (match(name, "t:sha1")) { return new Sha1(); } + if (match(name, "t:sqlHexDecode")) { return new SqlHexDecode(); } + if (match(name, "t:trimLeft")) { return new TrimLeft(); } + if (match(name, "t:trimRight")) { return new TrimRight(); } + if (match(name, "t:trim")) { return new Trim(); } + if (match(name, "t:uppercase")) { return new UpperCase(); } + if (match(name, "t:urlDecodeUni")) { return new UrlDecodeUni(); } + if (match(name, "t:urlDecode")) { return new UrlDecode(); } + if (match(name, "t:urlEncode")) { return new UrlEncode(); } + if (match(name, "t:utf8toUnicode")) { return new Utf8ToUnicode(); } + + throw TransformationDoesNotExist(name); + + return nullptr; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/transformation.h b/src/actions/transformations/transformation.h index 57f20416a9..e614d3b487 100644 --- a/src/actions/transformations/transformation.h +++ b/src/actions/transformations/transformation.h @@ -13,34 +13,47 @@ * */ + +#include #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" +#include "src/actions/action_allowed_in_sec_default_action.h" + + #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_ namespace modsecurity { -class Transaction; - namespace actions { namespace transformations { -class Transformation : public Action { - public: - explicit Transformation(const std::string& _action) - : Action(_action, RunTimeBeforeMatchAttemptKind) { } - explicit Transformation(const std::string& _action, int kind) - : Action(_action, kind) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - static Transformation* instantiate(std::string a); +class Transformation : public ActionAllowedAsSecDefaultAction { + public: + virtual void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept = 0; + + virtual ~Transformation() + { } + + static Transformation* instantiate(const std::string &name); + + private: + static bool match(const std::string &a, const std::string &b) noexcept { + return ((a.size() == b.size()) + && std::equal(a.begin(), a.end(), b.begin(), + [](const char & c1, const char & c2) { + return (c1 == c2 || std::toupper(c1) == std::toupper(c2)); + })); + } }; + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/trim.cc b/src/actions/transformations/trim.cc index 4954237aa0..983c74a8fd 100644 --- a/src/actions/transformations/trim.cc +++ b/src/actions/transformations/trim.cc @@ -13,55 +13,45 @@ * */ + #include "src/actions/transformations/trim.h" -#include -#include -#include #include -#include -#include +#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" + namespace modsecurity { namespace actions { namespace transformations { -std::string *Trim::ltrim(std::string *s) { +void Trim::ltrim(ModSecString *s) { s->erase(s->begin(), std::find_if(s->begin(), s->end(), std::not1(std::ptr_fun(std::isspace)))); - return s; } -std::string *Trim::rtrim(std::string *s) { +void Trim::rtrim(ModSecString *s) { s->erase(std::find_if(s->rbegin(), s->rend(), std::not1(std::ptr_fun(std::isspace))).base(), s->end()); - return s; } -std::string *Trim::trim(std::string *s) { - return ltrim(rtrim(s)); +void Trim::trim(ModSecString *s) { + rtrim(s); + ltrim(s); } -Trim::Trim(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - -std::string -Trim::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->trim(&value); -} +void Trim::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out = in; + trim(&out); +}; } // namespace transformations diff --git a/src/actions/transformations/trim.h b/src/actions/transformations/trim.h index 4deebb4fcb..ff90918237 100644 --- a/src/actions/transformations/trim.h +++ b/src/actions/transformations/trim.h @@ -13,38 +13,48 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class Trim : public Transformation { public: - - explicit Trim(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string *ltrim(std::string *s); - std::string *rtrim(std::string *s); - std::string *trim(std::string *s); + Trim() + : Action("t:trim") + { } + + explicit Trim(const std::string &trim) + : Action(trim) + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + + protected: + void ltrim(ModSecString *s); + void rtrim(ModSecString *s); + void trim(ModSecString *s); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_ diff --git a/src/actions/transformations/trim_left.cc b/src/actions/transformations/trim_left.cc index 9116e3c857..9ad9487e7d 100644 --- a/src/actions/transformations/trim_left.cc +++ b/src/actions/transformations/trim_left.cc @@ -13,36 +13,28 @@ * */ + #include "src/actions/transformations/trim_left.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/actions/transformations/trim.h" -#include "modsecurity/actions/action.h" namespace modsecurity { namespace actions { namespace transformations { +void TrimLeft::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out = in; + ltrim(&out); +}; -TrimLeft::TrimLeft(const std::string &action) - : Trim(action) { - this->action_kind = 1; -} - -std::string TrimLeft::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *ltrim(&value); -} } // namespace transformations } // namespace actions diff --git a/src/actions/transformations/trim_left.h b/src/actions/transformations/trim_left.h index e7799208dd..ba731f603b 100644 --- a/src/actions/transformations/trim_left.h +++ b/src/actions/transformations/trim_left.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" + #include "src/actions/transformations/trim.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class TrimLeft : public Trim { public: - explicit TrimLeft(const std::string &action) ; + TrimLeft() + : Action("t:trimLeft") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_ diff --git a/src/actions/transformations/trim_right.cc b/src/actions/transformations/trim_right.cc index bb7cac0828..21bd85dc9b 100644 --- a/src/actions/transformations/trim_right.cc +++ b/src/actions/transformations/trim_right.cc @@ -13,34 +13,27 @@ * */ + #include "src/actions/transformations/trim_right.h" -#include #include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" + namespace modsecurity { namespace actions { namespace transformations { -TrimRight::TrimRight(const std::string &action) - : Trim(action) { - this->action_kind = 1; -} +void TrimRight::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + out = in; + rtrim(&out); +}; -std::string TrimRight::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); - return *this->rtrim(&value); -} } // namespace transformations } // namespace actions diff --git a/src/actions/transformations/trim_right.h b/src/actions/transformations/trim_right.h index 8c10092875..3799e6bcd6 100644 --- a/src/actions/transformations/trim_right.h +++ b/src/actions/transformations/trim_right.h @@ -13,34 +13,39 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" -#include "src/actions/transformations/transformation.h" + #include "src/actions/transformations/trim.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ #define SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class TrimRight : public Trim { public: - explicit TrimRight(const std::string &action) ; + TrimRight() + : Action("t:trimRight") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_ diff --git a/src/actions/transformations/upper_case.cc b/src/actions/transformations/upper_case.cc index 0ae77c0e90..431d4b590b 100644 --- a/src/actions/transformations/upper_case.cc +++ b/src/actions/transformations/upper_case.cc @@ -13,36 +13,31 @@ * */ + #include "src/actions/transformations/upper_case.h" -#include #include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" -#include "modsecurity/actions/action.h" + namespace modsecurity { namespace actions { namespace transformations { -UpperCase::UpperCase(const std::string &a) - : Transformation(a) { -} - -std::string UpperCase::evaluate(const std::string &val, - Transaction *transaction) { - std::string value(val); +void UpperCase::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { std::locale loc; - - for (std::string::size_type i=0; i < value.length(); ++i) { - value[i] = std::toupper(value[i], loc); + out.reserve(in.size()); + for (std::string::size_type i=0; i < in.size(); ++i) { + out += std::toupper(in[i], loc); } - - return value; } + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/transformations/upper_case.h b/src/actions/transformations/upper_case.h index 542df2832b..9082cb77a0 100644 --- a/src/actions/transformations/upper_case.h +++ b/src/actions/transformations/upper_case.h @@ -13,35 +13,39 @@ * */ + #include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ -#ifdef __cplusplus namespace modsecurity { -class Transaction; namespace actions { namespace transformations { class UpperCase : public Transformation { public: - explicit UpperCase(const std::string &action) ; + UpperCase() + : Action("t:upperCase") + { } - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_ diff --git a/src/actions/transformations/url_decode.cc b/src/actions/transformations/url_decode.cc index c533b7e883..4ec251fd7e 100644 --- a/src/actions/transformations/url_decode.cc +++ b/src/actions/transformations/url_decode.cc @@ -13,49 +13,38 @@ * */ + #include "src/actions/transformations/url_decode.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/decode.h" + namespace modsecurity { namespace actions { namespace transformations { -UrlDecode::UrlDecode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - -std::string UrlDecode::evaluate(const std::string &value, - Transaction *transaction) { - unsigned char *val = NULL; +void UrlDecode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { + unsigned char *val(NULL); int invalid_count = 0; int changed; - val = (unsigned char *) malloc(sizeof(char) * value.size() + 1); - memcpy(val, value.c_str(), value.size() + 1); - val[value.size()] = '\0'; + val = (unsigned char *) malloc(sizeof(char) * in.size() + 1); + memcpy(val, in.c_str(), in.size() + 1); + val[in.size()] = '\0'; - int size = utils::urldecode_nonstrict_inplace(val, value.size(), + int size = utils::urldecode_nonstrict_inplace(val, in.size(), &invalid_count, &changed); - std::string out; - out.append((const char *)val, size); free(val); - - return out; } diff --git a/src/actions/transformations/url_decode.h b/src/actions/transformations/url_decode.h index 9e39045b77..938bb005e9 100644 --- a/src/actions/transformations/url_decode.h +++ b/src/actions/transformations/url_decode.h @@ -13,36 +13,39 @@ * */ + #include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { class UrlDecode : public Transformation { public: + UrlDecode() + : Action("t:urlDecode") + { } - explicit UrlDecode(const std::string &action) ; - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_ diff --git a/src/actions/transformations/url_decode_uni.cc b/src/actions/transformations/url_decode_uni.cc index 9533125012..377c13297d 100644 --- a/src/actions/transformations/url_decode_uni.cc +++ b/src/actions/transformations/url_decode_uni.cc @@ -13,24 +13,16 @@ * */ -#include "src/actions/transformations/url_decode_uni.h" -#include +#include "src/actions/transformations/url_decode_uni.h" -#include #include -#include -#include -#include -#include -#include -#include "modsecurity/rules_set_properties.h" -#include "modsecurity/rules_set.h" +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" +#include "modsecurity/rules_set.h" + #include "src/utils/string.h" -#include "src/utils/system.h" namespace modsecurity { @@ -38,26 +30,24 @@ namespace actions { namespace transformations { -std::string UrlDecodeUni::evaluate(const std::string &value, - Transaction *t) { - std::string ret; +void UrlDecodeUni::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memcpy(input, in.c_str(), in.length()+1); - size_t i = inplace(input, value.length(), t); + size_t i = inplace(input, in.length(), t); - ret.assign(reinterpret_cast(input), i); + out.assign(reinterpret_cast(input), i); free(input); - - return ret; } @@ -66,7 +56,7 @@ std::string UrlDecodeUni::evaluate(const std::string &value, * IMP1 Assumes NUL-terminated */ int UrlDecodeUni::inplace(unsigned char *input, uint64_t input_len, - Transaction *t) { + const Transaction *t) { unsigned char *d = input; int64_t i, count, fact, j, xv; int Code, hmap = -1; diff --git a/src/actions/transformations/url_decode_uni.h b/src/actions/transformations/url_decode_uni.h index b04aef893a..5f053fef8d 100644 --- a/src/actions/transformations/url_decode_uni.h +++ b/src/actions/transformations/url_decode_uni.h @@ -13,35 +13,43 @@ * */ + #include -#include "modsecurity/rules_set_properties.h" +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ -#ifdef __cplusplus namespace modsecurity { -class Transaction; namespace actions { namespace transformations { + class UrlDecodeUni : public Transformation { public: - explicit UrlDecodeUni(const std::string &action) : Transformation(action) { } + UrlDecodeUni() + : Action("t:urlDecodeUni") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; - std::string evaluate(const std::string &exp, Transaction *transaction) override; + private: static int inplace(unsigned char *input, uint64_t input_len, - Transaction *transaction); + const Transaction *transaction); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_ diff --git a/src/actions/transformations/url_encode.cc b/src/actions/transformations/url_encode.cc index 23a8f16753..139e2aa354 100644 --- a/src/actions/transformations/url_encode.cc +++ b/src/actions/transformations/url_encode.cc @@ -13,30 +13,23 @@ * */ + #include "src/actions/transformations/url_encode.h" -#include #include -#include -#include -#include -#include + +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" + namespace modsecurity { namespace actions { namespace transformations { -UrlEncode::UrlEncode(const std::string &action) - : Transformation(action) { - this->action_kind = 1; -} - - std::string UrlEncode::url_enc(const char *input, unsigned int input_len, int *changed) { char *rval, *d; @@ -87,13 +80,13 @@ std::string UrlEncode::url_enc(const char *input, } -std::string UrlEncode::evaluate(const std::string &value, - Transaction *transaction) { +void UrlEncode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { int changed; - std::string ret = url_enc(value.c_str(), value.size(), &changed); - - return ret; + std::string ret = url_enc(in.c_str(), in.size(), &changed); + out.assign(ret.c_str(), ret.size()); } diff --git a/src/actions/transformations/url_encode.h b/src/actions/transformations/url_encode.h index 438301f73c..d6e342b1a8 100644 --- a/src/actions/transformations/url_encode.h +++ b/src/actions/transformations/url_encode.h @@ -13,37 +13,43 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ -#ifdef __cplusplus -namespace modsecurity { -class Transaction; +namespace modsecurity { namespace actions { namespace transformations { + class UrlEncode : public Transformation { public: + UrlEncode() + : Action("t:urlEncode") + { } - explicit UrlEncode(const std::string &action) ; + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; - std::string evaluate(const std::string &exp, - Transaction *transaction) override; - - std::string url_enc(const char *input, + private: + static std::string url_enc(const char *input, unsigned int input_len, int *changed); }; + } // namespace transformations } // namespace actions } // namespace modsecurity -#endif #endif // SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_ diff --git a/src/actions/transformations/utf8_to_unicode.cc b/src/actions/transformations/utf8_to_unicode.cc index 38d9a2b784..ad5f314e21 100644 --- a/src/actions/transformations/utf8_to_unicode.cc +++ b/src/actions/transformations/utf8_to_unicode.cc @@ -13,18 +13,14 @@ * */ + #include "src/actions/transformations/utf8_to_unicode.h" -#include #include -#include -#include -#include -#include -#include +#include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" -#include "src/actions/transformations/transformation.h" + #include "src/utils/string.h" @@ -33,31 +29,30 @@ namespace actions { namespace transformations { -std::string Utf8ToUnicode::evaluate(const std::string &value, - Transaction *transaction) { - std::string ret; +void Utf8ToUnicode::execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept { unsigned char *input; int changed = 0; - char *out; + char *out2; input = reinterpret_cast - (malloc(sizeof(char) * value.length()+1)); + (malloc(sizeof(char) * in.length()+1)); if (input == NULL) { - return ""; + return; } - memcpy(input, value.c_str(), value.length()+1); + memset(input, '\0', in.length()+1); + memcpy(input, in.c_str(), in.length()+1); - out = inplace(input, value.size() + 1, &changed); - free(input); - if (out != NULL) { - ret.assign(reinterpret_cast(out), - strlen(reinterpret_cast(out))); - free(out); + out2 = inplace(input, in.size() + 1, &changed); + if (out2 != NULL) { + out.assign(reinterpret_cast(out2), + strlen(reinterpret_cast(out2))); + free(out2); } - - return ret; + free(input); } @@ -71,8 +66,8 @@ char *Utf8ToUnicode::inplace(unsigned char *input, unsigned char unicode[8]; *changed = 0; - /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */ - /* Max size per character should fit in 4 bytes */ + /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 */ + /* octets. Max size per character should fit in 4 bytes */ len = input_len * 4 + 1; data = reinterpret_cast(malloc(sizeof(char) * len)); if (data == NULL) { diff --git a/src/actions/transformations/utf8_to_unicode.h b/src/actions/transformations/utf8_to_unicode.h index c76bb0a285..468d6dbfd9 100644 --- a/src/actions/transformations/utf8_to_unicode.h +++ b/src/actions/transformations/utf8_to_unicode.h @@ -13,37 +13,48 @@ * */ + #include +#include "modsecurity/modsecurity.h" #include "modsecurity/actions/action.h" + #include "src/actions/transformations/transformation.h" + #ifndef SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ #define SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_ -#define UNICODE_ERROR_CHARACTERS_MISSING -1 -#define UNICODE_ERROR_INVALID_ENCODING -2 -#define UNICODE_ERROR_OVERLONG_CHARACTER -3 -#define UNICODE_ERROR_RESTRICTED_CHARACTER -4 -#define UNICODE_ERROR_DECODING_ERROR -5 namespace modsecurity { -class Transaction; - namespace actions { namespace transformations { + class Utf8ToUnicode : public Transformation { public: - explicit Utf8ToUnicode(const std::string &action) : Transformation(action) { } - - std::string evaluate(const std::string &exp, - Transaction *transaction) override; + Utf8ToUnicode() + : Action("t:utf8toUnicode") + { } + + void execute(const Transaction *t, + const ModSecString &in, + ModSecString &out) noexcept override; + + private: + enum UnicodeError { + UNICODE_ERROR_CHARACTERS_MISSING = -1, + UNICODE_ERROR_INVALID_ENCODING = -2, + UNICODE_ERROR_OVERLONG_CHARACTER = -3, + UNICODE_ERROR_RESTRICTED_CHARACTER = -4, + UNICODE_ERROR_DECODING_ERROR = -5 + }; static char *inplace(unsigned char *input, uint64_t input_len, int *changed); }; + } // namespace transformations } // namespace actions } // namespace modsecurity diff --git a/src/actions/ver.cc b/src/actions/ver.cc index 5b4fd13bcf..5fa44344b5 100644 --- a/src/actions/ver.cc +++ b/src/actions/ver.cc @@ -13,25 +13,13 @@ * */ -#include "src/actions/ver.h" - -#include -#include -#include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" -#include "modsecurity/rule.h" +#include "src/actions/ver.h" namespace modsecurity { namespace actions { -bool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) { - rule->m_ver = m_parser_payload; - return true; -} - - } // namespace actions } // namespace modsecurity diff --git a/src/actions/ver.h b/src/actions/ver.h index 0108188ae3..d442080005 100644 --- a/src/actions/ver.h +++ b/src/actions/ver.h @@ -13,28 +13,33 @@ * */ + #include -#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" + #ifndef SRC_ACTIONS_VER_H_ #define SRC_ACTIONS_VER_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { -class Ver : public Action { +class Ver : public ActionTypeRuleMetaData { public: - explicit Ver(const std::string &action) : Action(action, ConfigurationKind) { } + explicit Ver(const std::string &action) + : Action(action), + m_version("") + { }; - bool evaluate(RuleWithActions *rule, Transaction *transaction) override; + void configure(RuleWithActions *rule) override { + rule->setVersion(m_version); + } private: - std::string m_ver; + std::string m_version; }; diff --git a/src/actions/xmlns.cc b/src/actions/xmlns.cc index 7b90361bd7..512bc62157 100644 --- a/src/actions/xmlns.cc +++ b/src/actions/xmlns.cc @@ -13,13 +13,13 @@ * */ + #include "src/actions/xmlns.h" -#include #include #include "modsecurity/actions/action.h" -#include "modsecurity/transaction.h" + namespace modsecurity { namespace actions { @@ -29,13 +29,13 @@ bool XmlNS::init(std::string *error) { size_t pos; std::string http = "http://"; - pos = m_parser_payload.find("="); + pos = m_parserPayload.find("="); if (pos == std::string::npos) { error->assign("XMLS: Bad format, missing equals sign."); return false; } - m_scope = std::string(m_parser_payload, 0, pos); - m_href = std::string(m_parser_payload, pos+1, m_parser_payload.size()); + m_scope = std::string(m_parserPayload, 0, pos); + m_href = std::string(m_parserPayload, pos+1, m_parserPayload.size()); if (m_href.empty() || m_scope.empty()) { error->assign("XMLS: XMLNS is invalid. Expecting a " \ diff --git a/src/actions/xmlns.h b/src/actions/xmlns.h index 9dda7900bf..d86872bfaa 100644 --- a/src/actions/xmlns.h +++ b/src/actions/xmlns.h @@ -13,6 +13,7 @@ * */ + #include #include "modsecurity/actions/action.h" @@ -20,23 +21,20 @@ #ifndef SRC_ACTIONS_XMLNS_H_ #define SRC_ACTIONS_XMLNS_H_ -class Transaction; namespace modsecurity { -class Transaction; namespace actions { class XmlNS : public Action { public: - explicit XmlNS(const std::string &action) : Action(action) { } - - bool evaluate(RuleWithActions *rule, Transaction *transaction) override { - return true; - } + explicit XmlNS(const std::string &action) + : Action(action) + { } bool init(std::string *error) override; + private: std::string m_scope; std::string m_href; }; @@ -45,4 +43,5 @@ class XmlNS : public Action { } // namespace actions } // namespace modsecurity + #endif // SRC_ACTIONS_XMLNS_H_ diff --git a/src/anchored_set_variable.cc b/src/anchored_set_variable.cc index 1282af6213..d74d246710 100644 --- a/src/anchored_set_variable.cc +++ b/src/anchored_set_variable.cc @@ -36,44 +36,59 @@ AnchoredSetVariable::AnchoredSetVariable(Transaction *t, } -AnchoredSetVariable::~AnchoredSetVariable() { - unset(); -} - - void AnchoredSetVariable::unset() { - for (const auto& x : *this) { - VariableValue *var = x.second; - delete var; - } clear(); } void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset, size_t len) { - std::unique_ptr origin(new VariableOrigin()); - std::string *v = new std::string(value); - VariableValue *var = new VariableValue(&m_name, &key, v); - delete v; + auto var = std::make_shared(&m_name, &key, &value); - origin->m_offset = offset; - origin->m_length = len; + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = len; var->addOrigin(std::move(origin)); - emplace(key, var); + emplace(key, std::move(var)); } void AnchoredSetVariable::set(const std::string &key, const std::string &value, size_t offset) { - std::unique_ptr origin(new VariableOrigin()); - std::string *v = new std::string(value); - VariableValue *var = new VariableValue(&m_name, &key, v); - delete v; + auto var = std::make_shared(&m_name, &key, &value); + + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = value.size(); + + var->addOrigin(std::move(origin)); + emplace(key, std::move(var)); +} + + +void AnchoredSetVariable::set(const std::string &key, + const bpstd::string_view &value, size_t offset) { + std::string v(value.c_str()); + auto var = std::make_shared(&m_name, &key, &v); + + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = value.size(); + + var->addOrigin(std::move(origin)); + emplace(key, var); +} + + +void AnchoredSetVariable::set(const std::string &key, + const char *value, size_t offset) { + std::string v(value); + auto var = std::make_shared(&m_name, &key, &v); - origin->m_offset = offset; - origin->m_length = value.size(); + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = strlen(value); var->addOrigin(std::move(origin)); emplace(key, var); @@ -81,19 +96,19 @@ void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::resolve( - std::vector *l) { + std::vector> *l) { for (const auto& x : *this) { - l->insert(l->begin(), new VariableValue(x.second)); + l->insert(l->begin(), x.second); } } void AnchoredSetVariable::resolve( - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) { for (const auto& x : *this) { if (!ke.toOmit(x.first)) { - l->insert(l->begin(), new VariableValue(x.second)); + l->insert(l->begin(), x.second); } else { ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first + " from target value."); @@ -103,10 +118,10 @@ void AnchoredSetVariable::resolve( void AnchoredSetVariable::resolve(const std::string &key, - std::vector *l) { + std::vector> *l) { auto range = this->equal_range(key); for (auto it = range.first; it != range.second; ++it) { - l->push_back(new VariableValue(it->second)); + l->push_back(it->second); } } @@ -124,19 +139,19 @@ std::unique_ptr AnchoredSetVariable::resolveFirst( void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, - std::vector *l) { + std::vector> *l) { for (const auto& x : *this) { int ret = Utils::regex_search(x.first, *r); if (ret <= 0) { continue; } - l->insert(l->begin(), new VariableValue(x.second)); + l->insert(l->begin(), x.second); } } void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) { for (const auto& x : *this) { int ret = Utils::regex_search(x.first, *r); @@ -144,7 +159,7 @@ void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, continue; } if (!ke.toOmit(x.first)) { - l->insert(l->begin(), new VariableValue(x.second)); + l->insert(l->begin(), x.second); } else { ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first + " from target value."); diff --git a/src/anchored_variable.cc b/src/anchored_variable.cc index 35be6d38fb..741a53f923 100644 --- a/src/anchored_variable.cc +++ b/src/anchored_variable.cc @@ -23,6 +23,7 @@ #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" #include "src/utils/regex.h" +#include "modsecurity/string_view.hpp" namespace modsecurity { @@ -31,22 +32,11 @@ AnchoredVariable::AnchoredVariable(Transaction *t, const std::string &name) : m_transaction(t), m_offset(0), - m_name(""), + m_name(name), m_value(""), - m_var(NULL) { - m_name.append(name); - m_var = new VariableValue(&m_name); + m_var(&name) { } - -AnchoredVariable::~AnchoredVariable() { - if (m_var) { - delete (m_var); - m_var = NULL; - } -} - - void AnchoredVariable::unset() { m_value.clear(); } @@ -54,69 +44,86 @@ void AnchoredVariable::unset() { void AnchoredVariable::set(const std::string &a, size_t offset, size_t offsetLen) { - std::unique_ptr origin(new VariableOrigin()); m_offset = offset; m_value.assign(a.c_str(), a.size()); - origin->m_offset = offset; - origin->m_length = offsetLen; - m_var->addOrigin(std::move(origin)); + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = offsetLen; + m_var.addOrigin(std::move(origin)); } void AnchoredVariable::set(const std::string &a, size_t offset) { - std::unique_ptr origin(new VariableOrigin()); + m_offset = offset; + m_value.assign(a.c_str(), a.size()); + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = m_value.size(); + m_var.addOrigin(std::move(origin)); +} + + +void AnchoredVariable::set(const char *a, size_t offset) { + VariableOrigin origin; + + m_offset = offset; + m_value.assign(a, strlen(a)); + origin.m_offset = offset; + origin.m_length = m_value.size(); + m_var.addOrigin(std::move(origin)); +} + + +void AnchoredVariable::set(const bpstd::string_view &a, size_t offset) { + VariableOrigin origin; m_offset = offset; m_value.assign(a.c_str(), a.size()); - origin->m_offset = offset; - origin->m_length = m_value.size(); - m_var->addOrigin(std::move(origin)); + origin.m_offset = offset; + origin.m_length = m_value.size(); + + m_var.addOrigin(std::move(origin)); } void AnchoredVariable::append(const std::string &a, size_t offset, bool spaceSeparator) { - std::unique_ptr origin( - new VariableOrigin()); - if (spaceSeparator && !m_value.empty()) { m_value.append(" " + a); } else { m_value.append(a); } m_offset = offset; - origin->m_offset = offset; - origin->m_length = a.size(); - m_var->addOrigin(std::move(origin)); + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = a.size(); + m_var.addOrigin(std::move(origin)); } void AnchoredVariable::append(const std::string &a, size_t offset, bool spaceSeparator, int size) { - std::unique_ptr origin( - new VariableOrigin()); - if (spaceSeparator && !m_value.empty()) { m_value.append(" " + a); } else { m_value.append(a); } m_offset = offset; - origin->m_offset = offset; - origin->m_length = size; - m_var->addOrigin(std::move(origin)); + VariableOrigin origin; + origin.m_offset = offset; + origin.m_length = size; + m_var.addOrigin(std::move(origin)); } -void AnchoredVariable::evaluate(std::vector *l) { +void AnchoredVariable::evaluate(std::vector> *l) { if (m_name.empty()) { return; } - m_var->setValue(m_value); - VariableValue *m_var2 = new VariableValue(m_var); - l->push_back(m_var2); + m_var.setValue(m_value); + l->push_back(std::make_shared(m_var)); } diff --git a/src/audit_log/audit_log.cc b/src/audit_log/audit_log.cc index f65d38b6f6..d6105b532a 100644 --- a/src/audit_log/audit_log.cc +++ b/src/audit_log/audit_log.cc @@ -266,14 +266,13 @@ bool AuditLog::init(std::string *error) { } -bool AuditLog::isRelevant(int status) { +bool AuditLog::isRelevant(int status) const noexcept { std::string sstatus = std::to_string(status); if (m_relevant.empty()) { return false; } - if (sstatus.empty()) { return true; } @@ -283,50 +282,34 @@ bool AuditLog::isRelevant(int status) { } -bool AuditLog::saveIfRelevant(Transaction *transaction) { - return saveIfRelevant(transaction, -1); -} - - -bool AuditLog::saveIfRelevant(Transaction *transaction, int parts) { - bool saveAnyway = false; +bool AuditLog::saveIfRelevant(Transaction *transaction) const noexcept { if (m_status == OffAuditLogStatus || m_status == NotSetLogStatus) { ms_dbg_a(transaction, 5, "Audit log engine was not set."); - return true; - } - - for (RuleMessage &i : transaction->m_rulesMessages) { - if (i.m_noAuditLog == false) { - saveAnyway = true; - break; - } + return false; } if ((m_status == RelevantOnlyAuditLogStatus - && this->isRelevant(transaction->m_httpCodeReturned) == false) - && saveAnyway == false) { + && isRelevant(transaction->m_httpCodeReturned) == false)) { ms_dbg_a(transaction, 9, "Return code `" + std::to_string(transaction->m_httpCodeReturned) + "'" \ " is not interesting to audit logs, relevant code(s): `" + m_relevant + "'."); - return false; } - if (parts == -1) { - parts = m_parts; - } ms_dbg_a(transaction, 5, "Saving this request as part " \ "of the audit logs."); + if (m_writer == NULL) { ms_dbg_a(transaction, 1, "Internal error, audit log writer is null"); - } else { - std::string error; - bool a = m_writer->write(transaction, parts, &error); - if (a == false) { - ms_dbg_a(transaction, 1, "Cannot save the audit log: " + error); - return false; - } + return false; + } + + std::string error; + bool a = m_writer->write(transaction, transaction->m_auditLogParts, &error); + if (a == false) { + ms_dbg_a(transaction, 1, "Cannot save the audit log: " + error); + return false; } return true; diff --git a/src/collection/backend/in_memory-per_process.cc b/src/collection/backend/in_memory-per_process.cc index 717f998216..229eb1ca18 100644 --- a/src/collection/backend/in_memory-per_process.cc +++ b/src/collection/backend/in_memory-per_process.cc @@ -86,17 +86,17 @@ void InMemoryPerProcess::del(const std::string& key) { void InMemoryPerProcess::resolveSingleMatch(const std::string& var, - std::vector *l) { + std::vector> *l) { auto range = this->equal_range(var); for (auto it = range.first; it != range.second; ++it) { - l->push_back(new VariableValue(&m_name, &it->first, &it->second)); + l->push_back(std::make_shared(&m_name, &it->first, &it->second)); } } void InMemoryPerProcess::resolveMultiMatches(const std::string& var, - std::vector *l, variables::KeyExclusions &ke) { + std::vector> *l, variables::KeyExclusions &ke) { size_t keySize = var.size(); l->reserve(15); @@ -105,8 +105,7 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var, if (ke.toOmit(i.first)) { continue; } - l->insert(l->begin(), new VariableValue(&m_name, &i.first, - &i.second)); + l->insert(l->begin(), std::make_shared(&m_name, &i.first, &i.second)); } } else { auto range = this->equal_range(var); @@ -114,15 +113,14 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var, if (ke.toOmit(var)) { continue; } - l->insert(l->begin(), new VariableValue(&m_name, &var, - &it->second)); + l->insert(l->begin(), std::make_shared(&m_name, &var, &it->second)); } } } void InMemoryPerProcess::resolveRegularExpression(const std::string& var, - std::vector *l, variables::KeyExclusions &ke) { + std::vector> *l, variables::KeyExclusions &ke) { //if (var.find(":") == std::string::npos) { // return; @@ -155,7 +153,7 @@ void InMemoryPerProcess::resolveRegularExpression(const std::string& var, if (ke.toOmit(x.first)) { continue; } - l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second)); + l->insert(l->begin(), std::make_shared(&m_name, &x.first, &x.second)); } } diff --git a/src/collection/backend/in_memory-per_process.h b/src/collection/backend/in_memory-per_process.h index 0550fbc7b0..8955667bbb 100644 --- a/src/collection/backend/in_memory-per_process.h +++ b/src/collection/backend/in_memory-per_process.h @@ -87,12 +87,12 @@ class InMemoryPerProcess : std::unique_ptr resolveFirst(const std::string& var) override; void resolveSingleMatch(const std::string& var, - std::vector *l) override; + std::vector> *l) override; void resolveMultiMatches(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) override; void resolveRegularExpression(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) override; private: diff --git a/src/collection/backend/lmdb.cc b/src/collection/backend/lmdb.cc index 55afb1c548..8470028f08 100644 --- a/src/collection/backend/lmdb.cc +++ b/src/collection/backend/lmdb.cc @@ -262,7 +262,7 @@ bool LMDB::storeOrUpdateFirst(const std::string &key, void LMDB::resolveSingleMatch(const std::string& var, - std::vector *l) { + std::vector> *l) { int rc; MDB_txn *txn; MDB_dbi dbi; @@ -287,11 +287,10 @@ void LMDB::resolveSingleMatch(const std::string& var, mdb_cursor_open(txn, dbi, &cursor); while ((rc = mdb_cursor_get(cursor, &mdb_key, &mdb_value_ret, MDB_NEXT_DUP)) == 0) { - std::string *a = new std::string( + std::string a( reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); - VariableValue *v = new VariableValue(&var, a); - l->push_back(v); + l->emplace_back(&var, &a); } mdb_cursor_close(cursor); @@ -466,7 +465,7 @@ void LMDB::del(const std::string& key) { void LMDB::resolveMultiMatches(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) { MDB_val key, data; MDB_txn *txn = NULL; @@ -496,7 +495,7 @@ void LMDB::resolveMultiMatches(const std::string& var, if (keySize == 0) { while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { - l->insert(l->begin(), new VariableValue( + l->insert(l->begin(), std::make_shared( &m_name, new std::string(reinterpret_cast(key.mv_data), key.mv_size), @@ -507,7 +506,7 @@ void LMDB::resolveMultiMatches(const std::string& var, while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { char *a = reinterpret_cast(key.mv_data); if (strncmp(var.c_str(), a, keySize) == 0) { - l->insert(l->begin(), new VariableValue( + l->insert(l->begin(), std::make_shared( &m_name, new std::string(reinterpret_cast(key.mv_data), key.mv_size), @@ -528,7 +527,7 @@ void LMDB::resolveMultiMatches(const std::string& var, void LMDB::resolveRegularExpression(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) { MDB_val key, data; MDB_txn *txn = NULL; diff --git a/src/collection/backend/lmdb.h b/src/collection/backend/lmdb.h index d31a8d9560..f0044acb94 100644 --- a/src/collection/backend/lmdb.h +++ b/src/collection/backend/lmdb.h @@ -66,12 +66,12 @@ class LMDB : std::unique_ptr resolveFirst(const std::string& var) override; void resolveSingleMatch(const std::string& var, - std::vector *l) override; + std::vector> *l) override; void resolveMultiMatches(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) override; void resolveRegularExpression(const std::string& var, - std::vector *l, + std::vector> *l, variables::KeyExclusions &ke) override; private: diff --git a/src/engine/lua.cc b/src/engine/lua.cc index f9c1f0a933..065e8c112b 100644 --- a/src/engine/lua.cc +++ b/src/engine/lua.cc @@ -65,8 +65,7 @@ bool Lua::isCompatible(const std::string &script, Lua *l, std::string *error) { bool Lua::load(const std::string &script, std::string *err) { #ifdef WITH_LUA - lua_State *L = NULL; - L = luaL_newstate(); + lua_State *L = luaL_newstate(); luaL_openlibs(L); m_scriptName = script; @@ -122,7 +121,7 @@ const char *Lua::blob_reader(lua_State *L, void *ud, size_t *size) { #endif -int Lua::run(Transaction *t, const std::string &str) { +int Lua::run(Transaction *t, const std::string &str) const { #ifdef WITH_LUA std::string luaRet; const char *a = NULL; @@ -139,10 +138,12 @@ int Lua::run(Transaction *t, const std::string &str) { luaL_setfuncs(L, mscLuaLib, 0); lua_setglobal(L, "m"); + LuaScriptBlob blob(m_blob); + #ifdef WITH_LUA_5_1 - int rc = lua_load(L, Lua::blob_reader, &m_blob, m_scriptName.c_str()); + int rc = lua_load(L, Lua::blob_reader, &blob, m_scriptName.c_str()); #else - int rc = lua_load(L, Lua::blob_reader, &m_blob, m_scriptName.c_str(), + int rc = lua_load(L, Lua::blob_reader, &blob, m_scriptName.c_str(), NULL); #endif if (rc != LUA_OK) { @@ -234,7 +235,7 @@ int Lua::run(Transaction *t, const std::string &str) { #ifdef WITH_LUA int Lua::log(lua_State *L) { - const Transaction *t = NULL; + const Transaction *t(NULL); const char *text; int level; @@ -256,9 +257,9 @@ int Lua::log(lua_State *L) { int Lua::getvar(lua_State *L) { - const char *varname = NULL; - Transaction *t = NULL; - void *z = NULL; + const char *varname(NULL); + Transaction *t(NULL); + void *z(NULL); /* Retrieve parameters. */ varname = reinterpret_cast(luaL_checkstring(L, 1)); @@ -282,10 +283,10 @@ int Lua::getvar(lua_State *L) { int Lua::getvars(lua_State *L) { - const char *varname = NULL; - Transaction *t = NULL; - void *z = NULL; - std::vector l; + const char *varname(NULL); + Transaction *t(NULL); + void *z(NULL); + std::vector> l; int idx = 1; /* Retrieve parameters. */ @@ -314,25 +315,21 @@ int Lua::getvars(lua_State *L) { idx++; } - for (const VariableValue * i : l) { - delete i; - } - return 1; } int Lua::setvar(lua_State *L) { - Transaction *t = NULL; - const char *var_value = NULL; - const char *var_name = NULL; + Transaction *t(NULL); + const char *var_value(NULL); + const char *var_name(NULL); std::string vname; std::string collection; std::string variableName; int nargs = lua_gettop(L); char *chr = NULL; size_t pos; - void *z = NULL; + void *z(NULL); lua_getglobal(L, "__transaction"); z = const_cast(lua_topointer(L, -1)); @@ -440,20 +437,24 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, "t:" + std::string(name)); // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + ModSecString in; + ModSecString out; + in.assign(newVar.c_str(), newVar.size()); + tfn->execute(t, in, out); + newVar.assign(out.c_str(), out.size()); + delete tfn; } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ + std::string(name)); } - delete tfn; } return newVar; } if (lua_isstring(L, idx)) { - const char *name = NULL; + const char *name(NULL); name = reinterpret_cast(luaL_checkstring(L, idx)); actions::transformations::Transformation *tfn = \ @@ -462,7 +463,11 @@ std::string Lua::applyTransformations(lua_State *L, Transaction *t, // FIXME: transformation is not yet returning null. if (tfn) { - newVar = tfn->evaluate(newVar, t); + ModSecString in; + ModSecString out; + in.assign(newVar.c_str(), newVar.size()); + tfn->execute(t, in, out); + newVar.assign(out.c_str(), out.size()); delete tfn; } else { ms_dbg_a(t, 1, "SecRuleScript: Invalid transformation function: " \ diff --git a/src/engine/lua.h b/src/engine/lua.h index d2c209f360..da60876e79 100644 --- a/src/engine/lua.h +++ b/src/engine/lua.h @@ -34,7 +34,8 @@ class LuaScriptBlob { public: LuaScriptBlob() : m_data(NULL), - m_len(0) { } + m_len(0) + { } ~LuaScriptBlob() { if (m_data) { @@ -43,10 +44,17 @@ class LuaScriptBlob { } } + LuaScriptBlob(const LuaScriptBlob &other) : + m_data(NULL), + m_len(other.m_len) { + m_data = (unsigned char *)std::malloc(m_len); + // FIXME: m_data NULL? + std::memcpy(m_data, other.m_data, m_len); + } + void write(const void *data, size_t len) { - unsigned char *d = NULL; - d = (unsigned char *)realloc((unsigned char *)m_data, len + m_len); + unsigned char *d = (unsigned char *)realloc((unsigned char *)m_data, len + m_len); std::memcpy(d + m_len, data, len); m_len = m_len + len; m_data = d; @@ -69,7 +77,7 @@ class Lua { Lua() { } bool load(const std::string &script, std::string *err); - int run(Transaction *t, const std::string &str=""); + int run(Transaction *t, const std::string &str="") const; static bool isCompatible(const std::string &script, Lua *l, std::string *error); #ifdef WITH_LUA diff --git a/src/modsecurity.cc b/src/modsecurity.cc index ac8e52563a..fd56452499 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -188,7 +188,7 @@ const std::string& ModSecurity::getConnectorInformation() const { return m_connector; } -void ModSecurity::serverLog(void *data, std::shared_ptr rm) { +void ModSecurity::serverLog(void *data, RuleMessage *rm) { if (m_logCb == NULL) { std::cerr << "Server log callback is not set -- " << rm->errorLog(); std::cerr << std::endl; @@ -207,11 +207,12 @@ void ModSecurity::serverLog(void *data, std::shared_ptr rm) { } if (m_logProperties & RuleMessageLogProperty) { - const void *a = static_cast(rm.get()); + const void *a = static_cast(rm); if (m_logProperties & IncludeFullHighlightLogProperty) { m_logCb(data, a); return; } + m_logCb(data, a); return; } @@ -256,7 +257,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, strlen("highlight")); yajl_gen_array_open(g); - while (vars.size() > 0) { + while (!vars.empty()) { std::string value; yajl_gen_map_open(g); vars.pop_back(); @@ -303,9 +304,11 @@ int ModSecurity::processContentOffset(const char *content, size_t len, varValue.size()); yajl_gen_map_close(g); - while (trans.size() > 0) { + while (!trans.empty()) { modsecurity::actions::transformations::Transformation *t; - std::string varValueRes; + ModSecString in; + ModSecString out; + yajl_gen_map_open(g); yajl_gen_string(g, reinterpret_cast("transformation"), @@ -317,8 +320,9 @@ int ModSecurity::processContentOffset(const char *content, size_t len, t = modsecurity::actions::transformations::Transformation::instantiate( trans.back().str().c_str()); - varValueRes = t->evaluate(varValue, NULL); - varValue.assign(varValueRes); + in.assign(varValue.c_str()); + t->execute(NULL, in, out); + varValue.assign(out.c_str()); trans.pop_back(); yajl_gen_string(g, reinterpret_cast("value"), @@ -338,7 +342,7 @@ int ModSecurity::processContentOffset(const char *content, size_t len, yajl_gen_map_open(g); - while (ops.size() > 0) { + while (!ops.empty()) { std::string value; yajl_gen_string(g, reinterpret_cast("highlight"), strlen("highlight")); diff --git a/src/operators/begins_with.cc b/src/operators/begins_with.cc index e2766ec3f2..49b7c7db0d 100644 --- a/src/operators/begins_with.cc +++ b/src/operators/begins_with.cc @@ -24,8 +24,10 @@ namespace modsecurity { namespace operators { -bool BeginsWith::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { +bool BeginsWith::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); if (str.size() < p.size()) { diff --git a/src/operators/begins_with.h b/src/operators/begins_with.h index e8470d982f..130a10cab8 100644 --- a/src/operators/begins_with.h +++ b/src/operators/begins_with.h @@ -32,8 +32,10 @@ class BeginsWith : public Operator { explicit BeginsWith(std::unique_ptr param) : Operator("BeginsWith", std::move(param)) { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/contains.cc b/src/operators/contains.cc index e63e8adcc1..637d966c0f 100644 --- a/src/operators/contains.cc +++ b/src/operators/contains.cc @@ -21,10 +21,12 @@ namespace modsecurity { namespace operators { -bool Contains::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { +bool Contains::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - size_t offset = input.find(p); + size_t offset = input.to_string().find(p); bool contains = offset != std::string::npos; diff --git a/src/operators/contains.h b/src/operators/contains.h index 8bab08528a..4a00e2235c 100644 --- a/src/operators/contains.h +++ b/src/operators/contains.h @@ -33,10 +33,12 @@ class Contains : public Operator { public: /** @ingroup ModSecurity_Operator */ explicit Contains(std::unique_ptr param) - : Operator("Contains", std::move(param)) { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, - std::shared_ptr ruleMessage) override; + : Operator("Contains", std::move(param)) { }; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/contains_word.cc b/src/operators/contains_word.cc index 262b9b1947..36c03e030d 100644 --- a/src/operators/contains_word.cc +++ b/src/operators/contains_word.cc @@ -23,7 +23,7 @@ namespace modsecurity { namespace operators { -bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { +bool ContainsWord::acceptableChar(const bpstd::string_view &a, size_t pos) { if (a.size() - 1 < pos) { return false; } @@ -36,37 +36,40 @@ bool ContainsWord::acceptableChar(const std::string& a, size_t pos) { return true; } -bool ContainsWord::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { +bool ContainsWord::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &inputView, + RuleMessage *ruleMessage) { std::string paramTarget(m_string->evaluate(transaction)); + std::string input = inputView.to_string(); if (paramTarget.empty()) { return true; } - if (str.empty()) { + if (input.empty()) { return false; } - if (str == paramTarget) { + if (input == paramTarget) { return true; } - size_t pos = str.find(paramTarget); + size_t pos = input.find(paramTarget); while (pos != std::string::npos) { - if (pos == 0 && acceptableChar(str, paramTarget.size())) { + if (pos == 0 && acceptableChar(input, paramTarget.size())) { logOffset(ruleMessage, 0, paramTarget.size()); return true; } - if (pos + paramTarget.size() == str.size() && - acceptableChar(str, pos - 1)) { + if (pos + paramTarget.size() == input.size() && + acceptableChar(input, pos - 1)) { logOffset(ruleMessage, pos, paramTarget.size()); return true; } - if (acceptableChar(str, pos - 1) && - acceptableChar(str, pos + paramTarget.size())) { + if (acceptableChar(input, pos - 1) && + acceptableChar(input, pos + paramTarget.size())) { logOffset(ruleMessage, pos, paramTarget.size()); return true; } - pos = str.find(paramTarget, pos + 1); + pos = input.find(paramTarget, pos + 1); } return false; diff --git a/src/operators/contains_word.h b/src/operators/contains_word.h index c9698d215b..de697a5f91 100644 --- a/src/operators/contains_word.h +++ b/src/operators/contains_word.h @@ -32,12 +32,13 @@ class ContainsWord : public Operator { explicit ContainsWord(std::unique_ptr param) : Operator("ContainsWord", std::move(param)) { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; private: - static bool acceptableChar(const std::string& a, size_t pos); + static bool acceptableChar(const bpstd::string_view &a, size_t pos); }; } // namespace operators diff --git a/src/operators/detect_sqli.cc b/src/operators/detect_sqli.cc index f2032c6d82..5cd83be93c 100644 --- a/src/operators/detect_sqli.cc +++ b/src/operators/detect_sqli.cc @@ -20,38 +20,43 @@ #include "src/operators/operator.h" #include "others/libinjection/src/libinjection.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { -bool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool DetectSQLi::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { char fingerprint[8]; int issqli; issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint); + if (!transaction) { + goto tisempty; + } + if (issqli) { - if (t) { - t->m_matched.push_back(fingerprint); - ms_dbg_a(t, 4, "detected SQLi using libinjection with " \ - "fingerprint '" + std::string(fingerprint) + "' at: '" + - input + "'"); - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( - "0", std::string(fingerprint)); - ms_dbg_a(t, 7, "Added DetectSQLi match TX.0: " + \ - std::string(fingerprint)); - } + transaction->m_matched.push_back(fingerprint); + ms_dbg_a(transaction, 4, "detected SQLi using libinjection with " \ + "fingerprint '" + std::string(fingerprint) + "' at: '" + + input.to_string() + "'"); + if (rule && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( + "0", std::string(fingerprint)); + ms_dbg_a(transaction, 7, "Added DetectSQLi match TX.0: " + \ + std::string(fingerprint)); } } else { - if (t) { - ms_dbg_a(t, 9, "detected SQLi: not able to find an " \ - "inject on '" + input + "'"); - } + ms_dbg_a(transaction, 9, "detected SQLi: not able to find an " \ + "inject on '" + input.to_string() + "'"); } +tisempty: return issqli != 0; } diff --git a/src/operators/detect_sqli.h b/src/operators/detect_sqli.h index 2dc0d74836..02a207758d 100644 --- a/src/operators/detect_sqli.h +++ b/src/operators/detect_sqli.h @@ -32,9 +32,10 @@ class DetectSQLi : public Operator { m_match_message.assign("detected SQLi using libinjection."); } - bool evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/detect_xss.cc b/src/operators/detect_xss.cc index 859c20f836..64c21027d6 100644 --- a/src/operators/detect_xss.cc +++ b/src/operators/detect_xss.cc @@ -19,30 +19,33 @@ #include "src/operators/operator.h" #include "others/libinjection/src/libinjection.h" +#include "src/rule_with_actions.h" namespace modsecurity { namespace operators { -bool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool DetectXSS::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { int is_xss; is_xss = libinjection_xss(input.c_str(), input.length()); - if (t) { + if (transaction) { if (is_xss) { - ms_dbg_a(t, 5, "detected XSS using libinjection."); - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( + ms_dbg_a(transaction, 5, "detected XSS using libinjection."); + if (rule && transaction && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( "0", std::string(input)); - ms_dbg_a(t, 7, "Added DetectXSS match TX.0: " + \ + ms_dbg_a(transaction, 7, "Added DetectXSS match TX.0: " + \ std::string(input)); } } else { - ms_dbg_a(t, 9, "libinjection was not able to " \ - "find any XSS in: " + input); + ms_dbg_a(transaction, 9, "libinjection was not able to " \ + "find any XSS in: " + input.to_string()); } } return is_xss != 0; diff --git a/src/operators/detect_xss.h b/src/operators/detect_xss.h index 266fdf364c..748da98b9a 100644 --- a/src/operators/detect_xss.h +++ b/src/operators/detect_xss.h @@ -31,9 +31,10 @@ class DetectXSS : public Operator { m_match_message.assign("detected XSS using libinjection."); } - bool evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/ends_with.cc b/src/operators/ends_with.cc index 632fc8fe39..bf27d4ff74 100644 --- a/src/operators/ends_with.cc +++ b/src/operators/ends_with.cc @@ -23,16 +23,18 @@ namespace modsecurity { namespace operators { -bool EndsWith::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { +bool EndsWith::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { bool ret = false; std::string p(m_string->evaluate(transaction)); - if (str.length() >= p.length()) { - ret = (0 == str.compare(str.length() - p.length(), + if (input.length() >= p.length()) { + ret = (0 == input.compare(input.length() - p.length(), p.length(), p)); if (ret) { - logOffset(ruleMessage, str.length() - p.length(), + logOffset(ruleMessage, input.length() - p.length(), p.size()); } } diff --git a/src/operators/ends_with.h b/src/operators/ends_with.h index c5352618cf..8c206255eb 100644 --- a/src/operators/ends_with.h +++ b/src/operators/ends_with.h @@ -33,9 +33,11 @@ class EndsWith : public Operator { : Operator("EndsWith", std::move(param)) { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, - std::shared_ptr ruleMessage) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; diff --git a/src/operators/eq.cc b/src/operators/eq.cc index c9b31bf6ee..7a611dac4f 100644 --- a/src/operators/eq.cc +++ b/src/operators/eq.cc @@ -24,7 +24,10 @@ namespace modsecurity { namespace operators { -bool Eq::evaluate(Transaction *transaction, const std::string &input) { +bool Eq::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { int p = 0; int i = 0; std::string pt(m_string->evaluate(transaction)); @@ -35,7 +38,7 @@ bool Eq::evaluate(Transaction *transaction, const std::string &input) { p = 0; } try { - i = std::stoi(input); + i = std::stoi(input.c_str()); } catch (...) { i = 0; } diff --git a/src/operators/eq.h b/src/operators/eq.h index 30ac861484..1c426c2539 100644 --- a/src/operators/eq.h +++ b/src/operators/eq.h @@ -31,7 +31,11 @@ class Eq : public Operator { /** @ingroup ModSecurity_Operator */ explicit Eq(std::unique_ptr param) : Operator("Eq", std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &input) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/fuzzy_hash.cc b/src/operators/fuzzy_hash.cc index 1d57ab8c47..732236b0cb 100644 --- a/src/operators/fuzzy_hash.cc +++ b/src/operators/fuzzy_hash.cc @@ -96,21 +96,24 @@ FuzzyHash::~FuzzyHash() { } -bool FuzzyHash::evaluate(Transaction *t, const std::string &str) { +bool FuzzyHash::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { #ifdef WITH_SSDEEP char result[FUZZY_MAX_RESULT]; struct fuzzy_hash_chunk *chunk = m_head; if (fuzzy_hash_buf((const unsigned char*)str.c_str(), str.size(), result)) { - ms_dbg_a(t, 4, "Problems generating fuzzy hash"); + ms_dbg_a(transaction, 4, "Problems generating fuzzy hash"); return false; } while (chunk != NULL) { int i = fuzzy_compare(chunk->data, result); if (i >= m_threshold) { - ms_dbg_a(t, 4, "Fuzzy hash: matched " \ + ms_dbg_a(transaction, 4, "Fuzzy hash: matched " \ "with score: " + std::to_string(i) + "."); return true; } diff --git a/src/operators/fuzzy_hash.h b/src/operators/fuzzy_hash.h index c470b09ad9..c0ebfcb0a7 100644 --- a/src/operators/fuzzy_hash.h +++ b/src/operators/fuzzy_hash.h @@ -44,9 +44,12 @@ class FuzzyHash : public Operator { m_head(NULL) { } ~FuzzyHash(); - bool evaluate(Transaction *transaction, const std::string &std) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; - bool init(const std::string ¶m, std::string *error) override; + bool init(const std::string &file, std::string *error) override; private: int m_threshold; struct fuzzy_hash_chunk *m_head; diff --git a/src/operators/ge.cc b/src/operators/ge.cc index 0d27cfe8b7..e0c859440d 100644 --- a/src/operators/ge.cc +++ b/src/operators/ge.cc @@ -23,11 +23,13 @@ namespace modsecurity { namespace operators { -bool Ge::evaluate(Transaction *transaction, const std::string &input) { +bool Ge::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - std::string i = input; - bool ge = atoll(i.c_str()) >= atoll(p.c_str()); + bool ge = atoll(str.c_str()) >= atoll(p.c_str()); return ge; } diff --git a/src/operators/ge.h b/src/operators/ge.h index 57ca2a7c24..6f0bfc88ba 100644 --- a/src/operators/ge.h +++ b/src/operators/ge.h @@ -32,7 +32,11 @@ class Ge : public Operator { : Operator("Ge", std::move(param)) { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, const std::string &input) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/geo_lookup.cc b/src/operators/geo_lookup.cc index 51fb81288e..28989c5df1 100644 --- a/src/operators/geo_lookup.cc +++ b/src/operators/geo_lookup.cc @@ -34,16 +34,19 @@ namespace modsecurity { namespace operators { -bool GeoLookup::evaluate(Transaction *trans, const std::string &exp) { +bool GeoLookup::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { using std::placeholders::_1; using std::placeholders::_2; bool ret = true; - if (trans) { - ret = Utils::GeoLookup::getInstance().lookup(exp, trans, - std::bind(&GeoLookup::debug, this, trans, _1, _2)); + if (transaction) { + ret = Utils::GeoLookup::getInstance().lookup(str.c_str(), transaction, + std::bind(&GeoLookup::debug, this, transaction, _1, _2)); } else { - ret = Utils::GeoLookup::getInstance().lookup(exp, NULL, + ret = Utils::GeoLookup::getInstance().lookup(str.c_str(), NULL, nullptr); } diff --git a/src/operators/geo_lookup.h b/src/operators/geo_lookup.h index 757f9c2c6e..5dd872b049 100644 --- a/src/operators/geo_lookup.h +++ b/src/operators/geo_lookup.h @@ -29,11 +29,15 @@ class GeoLookup : public Operator { /** @ingroup ModSecurity_Operator */ GeoLookup() : Operator("GeoLookup") { } - bool evaluate(Transaction *transaction, const std::string &exp) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; protected: - bool debug(Transaction *transaction, int x, const std::string &a) { - ms_dbg_a(transaction, x, a); + bool debug(Transaction *transaction, int x, const bpstd::string_view &str) { + ms_dbg_a(transaction, x, str.to_string()); return true; } }; diff --git a/src/operators/gsblookup.cc b/src/operators/gsblookup.cc index e5f697f075..2c094b7470 100644 --- a/src/operators/gsblookup.cc +++ b/src/operators/gsblookup.cc @@ -23,7 +23,10 @@ namespace modsecurity { namespace operators { -bool GsbLookup::evaluate(Transaction *transaction, const std::string &str) { +bool GsbLookup::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { /** * @todo Implement the operator GeoLookup. * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#gsblookup diff --git a/src/operators/gsblookup.h b/src/operators/gsblookup.h index 57360ac627..c9eb726550 100644 --- a/src/operators/gsblookup.h +++ b/src/operators/gsblookup.h @@ -31,7 +31,10 @@ class GsbLookup : public Operator { explicit GsbLookup(std::unique_ptr param) : Operator("GsbLookup", std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &str) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/gt.cc b/src/operators/gt.cc index 1c967bbde2..32da3bc6e8 100644 --- a/src/operators/gt.cc +++ b/src/operators/gt.cc @@ -23,10 +23,13 @@ namespace modsecurity { namespace operators { -bool Gt::evaluate(Transaction *transaction, const std::string &input) { +bool Gt::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - bool gt = atoll(input.c_str()) > atoll(p.c_str()); + bool gt = atoll(str.c_str()) > atoll(p.c_str()); return gt; } diff --git a/src/operators/gt.h b/src/operators/gt.h index ac7fe134f4..13562f8d71 100644 --- a/src/operators/gt.h +++ b/src/operators/gt.h @@ -33,7 +33,11 @@ class Gt : public Operator { : Operator("Gt", std::move(param)) { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, const std::string &input) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/inspect_file.cc b/src/operators/inspect_file.cc index db0483d134..69cf73c64e 100644 --- a/src/operators/inspect_file.cc +++ b/src/operators/inspect_file.cc @@ -49,9 +49,12 @@ bool InspectFile::init(const std::string ¶m2, std::string *error) { } -bool InspectFile::evaluate(Transaction *transaction, const std::string &str) { +bool InspectFile::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { if (m_isScript) { - return m_lua.run(transaction, str); + return m_lua.run(transaction, str.to_string()); } else { FILE *in; char buff[512]; @@ -61,7 +64,7 @@ bool InspectFile::evaluate(Transaction *transaction, const std::string &str) { openstr.append(m_param); openstr.append(" "); - openstr.append(str); + openstr.append(str.to_string()); if (!(in = popen(openstr.c_str(), "r"))) { return false; } diff --git a/src/operators/inspect_file.h b/src/operators/inspect_file.h index 4bdac5ebab..65acde7fde 100644 --- a/src/operators/inspect_file.h +++ b/src/operators/inspect_file.h @@ -35,8 +35,13 @@ class InspectFile : public Operator { m_file(""), m_isScript(false) { } - bool init(const std::string ¶m, std::string *error) override; - bool evaluate(Transaction *transaction, const std::string &str) override; + bool init(const std::string &file, std::string *error) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; + private: std::string m_file; bool m_isScript; diff --git a/src/operators/ip_match.cc b/src/operators/ip_match.cc index ec84a8b785..94c16c2137 100644 --- a/src/operators/ip_match.cc +++ b/src/operators/ip_match.cc @@ -37,8 +37,11 @@ bool IpMatch::init(const std::string &file, std::string *error) { } -bool IpMatch::evaluate(Transaction *transaction, const std::string &input) { - return m_tree.contains(input); +bool IpMatch::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { + return m_tree.contains(str.c_str()); } diff --git a/src/operators/ip_match.h b/src/operators/ip_match.h index c84327fb4c..3522024b0c 100644 --- a/src/operators/ip_match.h +++ b/src/operators/ip_match.h @@ -34,7 +34,10 @@ class IpMatch : public Operator { IpMatch(const std::string &n, std::unique_ptr param) : Operator(n, std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &input) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; bool init(const std::string &file, std::string *error) override; diff --git a/src/operators/le.cc b/src/operators/le.cc index cc2e3dc60d..4abd6f0f72 100644 --- a/src/operators/le.cc +++ b/src/operators/le.cc @@ -23,10 +23,13 @@ namespace modsecurity { namespace operators { -bool Le::evaluate(Transaction *transaction, const std::string &input) { +bool Le::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - bool le = atoll(input.c_str()) <= atoll(p.c_str()); + bool le = atoll(str.c_str()) <= atoll(p.c_str()); return le; } diff --git a/src/operators/le.h b/src/operators/le.h index a463b3e8c4..d3f4bd348e 100644 --- a/src/operators/le.h +++ b/src/operators/le.h @@ -34,7 +34,10 @@ class Le : public Operator { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, const std::string &input) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; diff --git a/src/operators/lt.cc b/src/operators/lt.cc index 8458cd1aeb..3e3b2eba2b 100644 --- a/src/operators/lt.cc +++ b/src/operators/lt.cc @@ -22,10 +22,13 @@ namespace modsecurity { namespace operators { -bool Lt::evaluate(Transaction *transaction, const std::string &input) { +bool Lt::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - bool lt = atoll(input.c_str()) < atoll(p.c_str()); + bool lt = atoll(str.c_str()) < atoll(p.c_str()); return lt; } diff --git a/src/operators/lt.h b/src/operators/lt.h index 6a95adef47..b96240ea56 100644 --- a/src/operators/lt.h +++ b/src/operators/lt.h @@ -34,7 +34,10 @@ class Lt : public Operator { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, const std::string &input) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/no_match.cc b/src/operators/no_match.cc index c0979e1de9..180a6d4c6b 100644 --- a/src/operators/no_match.cc +++ b/src/operators/no_match.cc @@ -20,7 +20,10 @@ namespace modsecurity { namespace operators { -bool NoMatch::evaluate(Transaction *transaction, const std::string &str) { +bool NoMatch::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { return false; } diff --git a/src/operators/no_match.h b/src/operators/no_match.h index 8016905899..74c18b4bfc 100644 --- a/src/operators/no_match.h +++ b/src/operators/no_match.h @@ -32,7 +32,10 @@ class NoMatch : public Operator { NoMatch() : Operator("NoMatch") { } - bool evaluate(Transaction *transaction, const std::string &str) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/operator.cc b/src/operators/operator.cc index 3bb12ce8ef..da3af4032d 100644 --- a/src/operators/operator.cc +++ b/src/operators/operator.cc @@ -70,7 +70,7 @@ namespace operators { bool Operator::evaluateInternal(Transaction *transaction, - RuleWithActions *rule, const std::string& a, std::shared_ptr rm) { + const RuleWithActions *rule, const bpstd::string_view &a, RuleMessage *rm) { bool res = evaluate(transaction, rule, a, rm); if (m_negation) { @@ -80,28 +80,6 @@ bool Operator::evaluateInternal(Transaction *transaction, return res; } -bool Operator::evaluateInternal(Transaction *transaction, - RuleWithActions *rule, const std::string& a) { - bool res = evaluate(transaction, rule, a); - - if (m_negation) { - return !res; - } - - return res; -} - -bool Operator::evaluateInternal(Transaction *transaction, - const std::string& a) { - bool res = evaluate(transaction, a); - - if (m_negation) { - return !res; - } - - return res; -} - std::string Operator::resolveMatchMessage(Transaction *t, std::string key, std::string value) { @@ -131,7 +109,10 @@ std::string Operator::resolveMatchMessage(Transaction *t, } -bool Operator::evaluate(Transaction *transaction, const std::string& a) { +bool Operator::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { ms_dbg_a(transaction, 2, "Operator: " + m_op + \ " is not implemented or malfunctioning."); return true; diff --git a/src/operators/operator.h b/src/operators/operator.h index 523b9209c4..97ca5775fb 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -24,6 +24,7 @@ #include "modsecurity/rule.h" #include "modsecurity/rule_message.h" #include "src/run_time_string.h" +#include "modsecurity/string_view.hpp" namespace modsecurity { namespace operators { @@ -107,27 +108,18 @@ class Operator { return true; } - virtual std::string resolveMatchMessage(Transaction *t, - std::string key, std::string value); - - bool evaluateInternal(Transaction *t, const std::string& a); - bool evaluateInternal(Transaction *t, RuleWithActions *rule, - const std::string& a); - bool evaluateInternal(Transaction *t, RuleWithActions *rule, - const std::string& a, std::shared_ptr ruleMessage); + bool evaluateInternal(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view& a, + RuleMessage *ruleMessage); + virtual bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage); - virtual bool evaluate(Transaction *transaction, const std::string &str); - virtual bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str) { - return evaluate(transaction, str); - } - virtual bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { - return evaluate(transaction, str); - } - static void logOffset(std::shared_ptr ruleMessage, int offset, int len) { + static void logOffset(RuleMessage *ruleMessage, int offset, int len) { if (ruleMessage) { ruleMessage->m_reference.append("o" + std::to_string(offset) + "," @@ -135,6 +127,10 @@ class Operator { } } + virtual std::string resolveMatchMessage(Transaction *t, + std::string key, std::string value); + + std::string m_match_message; bool m_negation; std::string m_op; diff --git a/src/operators/pm.cc b/src/operators/pm.cc index 8c747ed301..d93e191b10 100644 --- a/src/operators/pm.cc +++ b/src/operators/pm.cc @@ -28,6 +28,8 @@ #include "src/operators/operator.h" #include "src/utils/acmp.h" #include "src/utils/string.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { @@ -81,9 +83,11 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) { } -bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { - int rc; +bool Pm::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { + int rc = -1; ACMPT pt; pt.parser = m_p; pt.ptr = NULL; @@ -91,7 +95,7 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule, #ifdef MODSEC_MUTEX_ON_PM pthread_mutex_lock(&m_lock); #endif - rc = acmp_process_quick(&pt, &match, input.c_str(), input.length()); + rc = acmp_process_quick(&pt, &match, str.c_str(), str.length()); #ifdef MODSEC_MUTEX_ON_PM pthread_mutex_unlock(&m_lock); #endif diff --git a/src/operators/pm.h b/src/operators/pm.h index 0c2e58f3b8..604cbba736 100644 --- a/src/operators/pm.h +++ b/src/operators/pm.h @@ -41,9 +41,11 @@ class Pm : public Operator { m_p = acmp_create(0); } ~Pm(); - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, - std::shared_ptr ruleMessage) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; bool init(const std::string &file, std::string *error) override; diff --git a/src/operators/pm_from_file.cc b/src/operators/pm_from_file.cc index 46d00c1032..53f326958a 100644 --- a/src/operators/pm_from_file.cc +++ b/src/operators/pm_from_file.cc @@ -56,7 +56,7 @@ bool PmFromFile::init(const std::string &config, std::string *error) { iss = new std::stringstream(client.content); } else { std::string err; - std::string resource = utils::find_resource(m_param, config, &err); + std::string resource = utils::find_resource(m_param, config.c_str(), &err); iss = new std::ifstream(resource, std::ios::in); if (((std::ifstream *)iss)->is_open() == false) { diff --git a/src/operators/rbl.cc b/src/operators/rbl.cc index 6753435f65..80f7277db7 100644 --- a/src/operators/rbl.cc +++ b/src/operators/rbl.cc @@ -25,6 +25,8 @@ #include "modsecurity/rules_set.h" #include "src/operators/operator.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { @@ -200,11 +202,12 @@ void Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr, } -bool Rbl::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& ipStr, - std::shared_ptr ruleMessage) { +bool Rbl::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { struct addrinfo *info = NULL; - std::string host = Rbl::mapIpToAddress(ipStr, t); + std::string host = Rbl::mapIpToAddress(str.c_str(), transaction); int rc = 0; if (host.empty()) { @@ -217,20 +220,20 @@ bool Rbl::evaluate(Transaction *t, RuleWithActions *rule, if (info != NULL) { freeaddrinfo(info); } - ms_dbg_a(t, 5, "RBL lookup of " + ipStr + " failed."); + ms_dbg_a(transaction, 5, "RBL lookup of " + str.to_string() + " failed."); return false; } struct sockaddr *addr = info->ai_addr; struct sockaddr_in *sin = (struct sockaddr_in *) addr; - furtherInfo(sin, ipStr, t, m_provider); + furtherInfo(sin, str.c_str(), transaction, m_provider); freeaddrinfo(info); - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( - "0", std::string(ipStr)); - ms_dbg_a(t, 7, "Added RXL match TX.0: " + \ - std::string(ipStr)); + if (rule && transaction && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( + "0", std::string(str)); + ms_dbg_a(transaction, 7, "Added RXL match TX.0: " + \ + std::string(str)); } return true; diff --git a/src/operators/rbl.h b/src/operators/rbl.h index 4cc1fc25a2..bd81914275 100644 --- a/src/operators/rbl.h +++ b/src/operators/rbl.h @@ -76,9 +76,11 @@ class Rbl : public Operator { m_provider = RblProvider::httpbl; } } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const; diff --git a/src/operators/rsub.cc b/src/operators/rsub.cc index 122ae70b5a..5b83f9c27c 100644 --- a/src/operators/rsub.cc +++ b/src/operators/rsub.cc @@ -23,7 +23,10 @@ namespace modsecurity { namespace operators { -bool Rsub::evaluate(Transaction *transaction, const std::string &str) { +bool Rsub::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { /** * @todo Implement the operator Rsub. * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#rsub diff --git a/src/operators/rsub.h b/src/operators/rsub.h index ae4eb248f2..b2a9a59f38 100644 --- a/src/operators/rsub.h +++ b/src/operators/rsub.h @@ -32,7 +32,11 @@ class Rsub : public Operator { /** @ingroup ModSecurity_Operator */ explicit Rsub(std::unique_ptr param) : Operator("Rsub", std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &str) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; diff --git a/src/operators/rx.cc b/src/operators/rx.cc index b4fc6ff4d7..24fd1c7772 100644 --- a/src/operators/rx.cc +++ b/src/operators/rx.cc @@ -22,13 +22,15 @@ #include "src/operators/operator.h" #include "modsecurity/rule.h" #include "modsecurity/rule_message.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { -bool Rx::init(const std::string &arg, std::string *error) { - if (m_string->m_containsMacro == false) { +bool Rx::init(const std::string &file, std::string *error) { + if (m_string->containsMacro() == false) { m_re = new Regex(m_param); } @@ -36,15 +38,17 @@ bool Rx::init(const std::string &arg, std::string *error) { } -bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool Rx::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { Regex *re; - if (m_param.empty() && !m_string->m_containsMacro) { + if (m_param.empty() && !m_string->containsMacro()) { return true; } - if (m_string->m_containsMacro) { + if (m_string->containsMacro()) { std::string eparam(m_string->evaluate(transaction)); re = new Regex(eparam); } else { @@ -52,8 +56,8 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, } std::vector captures; - re->searchOneMatch(input, captures); - + // FIXME: searchOneMatch should accept string_view. + re->searchOneMatch(input.c_str(), captures); if (rule && rule->hasCaptureAction() && transaction) { for (const Utils::SMatchCapture& capture : captures) { const std::string capture_substring(input.substr(capture.m_offset,capture.m_length)); @@ -69,11 +73,11 @@ bool Rx::evaluate(Transaction *transaction, RuleWithActions *rule, logOffset(ruleMessage, capture.m_offset, capture.m_length); } - if (m_string->m_containsMacro) { + if (m_string->containsMacro()) { delete re; } - if (captures.size() > 0) { + if (!captures.empty()) { return true; } diff --git a/src/operators/rx.h b/src/operators/rx.h index 97cc12a3aa..481b393d36 100644 --- a/src/operators/rx.h +++ b/src/operators/rx.h @@ -43,17 +43,18 @@ class Rx : public Operator { } ~Rx() { - if (m_string->m_containsMacro == false && m_re != NULL) { + if (m_string->containsMacro() == false && m_re != NULL) { delete m_re; m_re = NULL; } } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; - bool init(const std::string &arg, std::string *error) override; + bool init(const std::string &file, std::string *error) override; private: Regex *m_re; diff --git a/src/operators/str_eq.cc b/src/operators/str_eq.cc index fd083f9003..4f6c30c39d 100644 --- a/src/operators/str_eq.cc +++ b/src/operators/str_eq.cc @@ -20,9 +20,12 @@ namespace modsecurity { namespace operators { -bool StrEq::evaluate(Transaction *transaction, const std::string &str) { +bool StrEq::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string pt(m_string->evaluate(transaction)); - return !pt.compare(str); + return !pt.compare(str.to_string()); } diff --git a/src/operators/str_eq.h b/src/operators/str_eq.h index 87e46bf586..29632172b3 100644 --- a/src/operators/str_eq.h +++ b/src/operators/str_eq.h @@ -34,7 +34,10 @@ class StrEq : public Operator { explicit StrEq(std::unique_ptr param) : Operator("StrEq", std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &str) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/str_match.cc b/src/operators/str_match.cc index 2fae6f0f88..e4e56ffa31 100644 --- a/src/operators/str_match.cc +++ b/src/operators/str_match.cc @@ -24,9 +24,12 @@ namespace modsecurity { namespace operators { -bool StrMatch::evaluate(Transaction *transaction, const std::string &input) { +bool StrMatch::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { std::string p(m_string->evaluate(transaction)); - bool ret = input.find(p) != std::string::npos; + bool ret = str.find(p) != std::string::npos; return ret; } diff --git a/src/operators/str_match.h b/src/operators/str_match.h index c941117d34..1f16bbd440 100644 --- a/src/operators/str_match.h +++ b/src/operators/str_match.h @@ -34,7 +34,10 @@ class StrMatch : public Operator { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, const std::string &input) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/unconditional_match.cc b/src/operators/unconditional_match.cc index 54c6a43aa0..64010eff6c 100644 --- a/src/operators/unconditional_match.cc +++ b/src/operators/unconditional_match.cc @@ -19,7 +19,9 @@ namespace modsecurity { namespace operators { bool UnconditionalMatch::evaluate(Transaction *transaction, - const std::string &input) { + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { return true; } diff --git a/src/operators/unconditional_match.h b/src/operators/unconditional_match.h index 8a08d828a5..cbb2ce50ca 100644 --- a/src/operators/unconditional_match.h +++ b/src/operators/unconditional_match.h @@ -31,7 +31,10 @@ class UnconditionalMatch : public Operator { UnconditionalMatch() : Operator("UnconditionalMatch") { } - bool evaluate(Transaction *transaction, const std::string &exp) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/validate_byte_range.cc b/src/operators/validate_byte_range.cc index 47f67b5cd7..5687d6d492 100644 --- a/src/operators/validate_byte_range.cc +++ b/src/operators/validate_byte_range.cc @@ -23,7 +23,7 @@ namespace modsecurity { namespace operators { -bool ValidateByteRange::getRange(const std::string &rangeRepresentation, +bool ValidateByteRange::getRange(const bpstd::string_view &rangeRepresentation, std::string *error) { size_t pos = rangeRepresentation.find_first_of("-"); int start; @@ -31,9 +31,10 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation, if (pos == std::string::npos) { try { - start = std::stoi(rangeRepresentation); + start = std::stoi(rangeRepresentation.c_str()); } catch(...) { - error->assign("Not able to convert '" + rangeRepresentation + + error->assign("Not able to convert '" + \ + rangeRepresentation.to_string() + "' into a number"); return false; } @@ -42,19 +43,19 @@ bool ValidateByteRange::getRange(const std::string &rangeRepresentation, } try { - start = std::stoi(std::string(rangeRepresentation, 0, pos)); + start = std::stoi(std::string(rangeRepresentation.c_str(), 0, pos)); } catch (...) { error->assign("Not able to convert '" + - std::string(rangeRepresentation, 0, pos) + + std::string(rangeRepresentation.c_str(), 0, pos) + "' into a number"); return false; } try { - end = std::stoi(std::string(rangeRepresentation, pos + 1, + end = std::stoi(std::string(rangeRepresentation.c_str(), pos + 1, rangeRepresentation.length() - (pos + 1))); } catch (...) { - error->assign("Not able to convert '" + std::string(rangeRepresentation, + error->assign("Not able to convert '" + std::string(rangeRepresentation.c_str(), pos + 1, rangeRepresentation.length() - (pos + 1)) + "' into a number"); return false; @@ -110,16 +111,18 @@ bool ValidateByteRange::init(const std::string &file, } -bool ValidateByteRange::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { +bool ValidateByteRange::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { bool ret = true; size_t count = 0; - for (int i = 0; i < input.length(); i++) { - int x = (unsigned char) input.at(i); + for (int i = 0; i < str.length(); i++) { + int x = (unsigned char) str.at(i); if (!(table[x >> 3] & (1 << (x & 0x7)))) { // debug(9, "Value " + std::to_string(x) + " in " + - // input + " ouside range: " + param); + // str + " ouside range: " + param); logOffset(ruleMessage, i, 1); count++; } diff --git a/src/operators/validate_byte_range.h b/src/operators/validate_byte_range.h index d50f2997dc..244ac9c52d 100644 --- a/src/operators/validate_byte_range.h +++ b/src/operators/validate_byte_range.h @@ -37,10 +37,12 @@ class ValidateByteRange : public Operator { } ~ValidateByteRange() override { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, - std::shared_ptr ruleMessage) override; - bool getRange(const std::string &rangeRepresentation, std::string *error); + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; + + bool getRange(const bpstd::string_view &rangeRepresentation, std::string *error); bool init(const std::string& file, std::string *error) override; private: std::vector ranges; diff --git a/src/operators/validate_dtd.cc b/src/operators/validate_dtd.cc index 144041c7a4..226d595ad8 100644 --- a/src/operators/validate_dtd.cc +++ b/src/operators/validate_dtd.cc @@ -43,25 +43,28 @@ bool ValidateDTD::init(const std::string &file, std::string *error) { } -bool ValidateDTD::evaluate(Transaction *t, const std::string &str) { +bool ValidateDTD::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { xmlValidCtxtPtr cvp; m_dtd = xmlParseDTD(NULL, (const xmlChar *)m_resource.c_str()); if (m_dtd == NULL) { std::string err = std::string("XML: Failed to load DTD: ") \ + m_resource; - ms_dbg_a(t, 4, err); + ms_dbg_a(transaction, 4, err); return true; } - if (t->m_xml->m_data.doc == NULL) { - ms_dbg_a(t, 4, "XML document tree could not "\ + if (transaction->m_xml->m_data.doc == NULL) { + ms_dbg_a(transaction, 4, "XML document tree could not "\ "be found for DTD validation."); return true; } - if (t->m_xml->m_data.well_formed != 1) { - ms_dbg_a(t, 4, "XML: DTD validation failed because " \ + if (transaction->m_xml->m_data.well_formed != 1) { + ms_dbg_a(transaction, 4, "XML: DTD validation failed because " \ "content is not well formed."); return true; } @@ -78,22 +81,23 @@ bool ValidateDTD::evaluate(Transaction *t, const std::string &str) { cvp = xmlNewValidCtxt(); if (cvp == NULL) { - ms_dbg_a(t, 4, "XML: Failed to create a validation context."); + ms_dbg_a(transaction, 4, + "XML: Failed to create a validation context."); return true; } /* Send validator errors/warnings to msr_log */ cvp->error = (xmlSchemaValidityErrorFunc)error_runtime; cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime; - cvp->userData = t; + cvp->userData = transaction; - if (!xmlValidateDtd(cvp, t->m_xml->m_data.doc, m_dtd)) { - ms_dbg_a(t, 4, "XML: DTD validation failed."); + if (!xmlValidateDtd(cvp, transaction->m_xml->m_data.doc, m_dtd)) { + ms_dbg_a(transaction, 4, "XML: DTD validation failed."); xmlFreeValidCtxt(cvp); return true; } - ms_dbg_a(t, 4, std::string("XML: Successfully validated " \ + ms_dbg_a(transaction, 4, std::string("XML: Successfully validated " \ "payload against DTD: ") + m_resource); xmlFreeValidCtxt(cvp); diff --git a/src/operators/validate_dtd.h b/src/operators/validate_dtd.h index 07e3af5dd4..944fa66a7c 100644 --- a/src/operators/validate_dtd.h +++ b/src/operators/validate_dtd.h @@ -46,7 +46,11 @@ class ValidateDTD : public Operator { } } - bool evaluate(Transaction *transaction, const std::string &str) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; + bool init(const std::string &file, std::string *error) override; diff --git a/src/operators/validate_hash.cc b/src/operators/validate_hash.cc index 6d99c8c82c..652c79cf4b 100644 --- a/src/operators/validate_hash.cc +++ b/src/operators/validate_hash.cc @@ -22,7 +22,10 @@ namespace modsecurity { namespace operators { -bool ValidateHash::evaluate(Transaction *transaction, const std::string &str) { +bool ValidateHash::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { /** * @todo Implement the operator ValidateHash. * Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateHash diff --git a/src/operators/validate_hash.h b/src/operators/validate_hash.h index d462971b7b..0d811d228a 100644 --- a/src/operators/validate_hash.h +++ b/src/operators/validate_hash.h @@ -31,7 +31,11 @@ class ValidateHash : public Operator { /** @ingroup ModSecurity_Operator */ explicit ValidateHash(std::unique_ptr param) : Operator("ValidateHash", std::move(param)) { } - bool evaluate(Transaction *transaction, const std::string &str) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/operators/validate_schema.cc b/src/operators/validate_schema.cc index c66ffec8ef..65b471703d 100644 --- a/src/operators/validate_schema.cc +++ b/src/operators/validate_schema.cc @@ -39,8 +39,10 @@ bool ValidateSchema::init(const std::string &file, std::string *error) { } -bool ValidateSchema::evaluate(Transaction *t, - const std::string &str) { +bool ValidateSchema::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { int rc; m_parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str()); @@ -52,7 +54,7 @@ bool ValidateSchema::evaluate(Transaction *t, if (m_err.empty() == false) { err << m_err; } - ms_dbg_a(t, 4, err.str()); + ms_dbg_a(transaction, 4, err.str()); return true; } @@ -75,7 +77,7 @@ bool ValidateSchema::evaluate(Transaction *t, if (m_err.empty() == false) { err << " " << m_err; } - ms_dbg_a(t, 4, err.str()); + ms_dbg_a(transaction, 4, err.str()); xmlSchemaFreeParserCtxt(m_parserCtx); return true; } @@ -86,23 +88,23 @@ bool ValidateSchema::evaluate(Transaction *t, if (m_err.empty() == false) { err << " " << m_err; } - ms_dbg_a(t, 4, err.str()); + ms_dbg_a(transaction, 4, err.str()); return true; } /* Send validator errors/warnings to msr_log */ xmlSchemaSetValidErrors(m_validCtx, (xmlSchemaValidityErrorFunc)error_runtime, - (xmlSchemaValidityWarningFunc)warn_runtime, t); + (xmlSchemaValidityWarningFunc)warn_runtime, transaction); - if (t->m_xml->m_data.doc == NULL) { - ms_dbg_a(t, 4, "XML document tree could not be found for " \ + if (transaction->m_xml->m_data.doc == NULL) { + ms_dbg_a(transaction, 4, "XML document tree could not be found for " \ "schema validation."); return true; } - if (t->m_xml->m_data.well_formed != 1) { - ms_dbg_a(t, 4, "XML: Schema validation failed because " \ + if (transaction->m_xml->m_data.well_formed != 1) { + ms_dbg_a(transaction, 4, "XML: Schema validation failed because " \ "content is not well formed."); return true; } @@ -116,15 +118,15 @@ bool ValidateSchema::evaluate(Transaction *t, } */ - rc = xmlSchemaValidateDoc(m_validCtx, t->m_xml->m_data.doc); + rc = xmlSchemaValidateDoc(m_validCtx, transaction->m_xml->m_data.doc); if (rc != 0) { - ms_dbg_a(t, 4, "XML: Schema validation failed."); + ms_dbg_a(transaction, 4, "XML: Schema validation failed."); xmlSchemaFree(m_schema); xmlSchemaFreeParserCtxt(m_parserCtx); return true; /* No match. */ } - ms_dbg_a(t, 4, "XML: Successfully validated payload against " \ + ms_dbg_a(transaction, 4, "XML: Successfully validated payload against " \ "Schema: " + m_resource); xmlSchemaFree(m_schema); xmlSchemaFreeParserCtxt(m_parserCtx); diff --git a/src/operators/validate_schema.h b/src/operators/validate_schema.h index 242a209b1e..1182773528 100644 --- a/src/operators/validate_schema.h +++ b/src/operators/validate_schema.h @@ -58,7 +58,11 @@ class ValidateSchema : public Operator { } } - bool evaluate(Transaction *transaction, const std::string &str) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; + bool init(const std::string &file, std::string *error) override; diff --git a/src/operators/validate_url_encoding.cc b/src/operators/validate_url_encoding.cc index f04a5fa78c..b2b073b2ba 100644 --- a/src/operators/validate_url_encoding.cc +++ b/src/operators/validate_url_encoding.cc @@ -68,8 +68,10 @@ int ValidateUrlEncoding::validate_url_encoding(const char *input, } -bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, std::shared_ptr ruleMessage) { +bool ValidateUrlEncoding::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { size_t offset = 0; bool res = false; @@ -82,14 +84,15 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru case 1 : /* Encoding is valid */ if (transaction) { - ms_dbg_a(transaction, 7, "Valid URL Encoding at '" +input + "'"); + ms_dbg_a(transaction, 7, "Valid URL Encoding at '" + \ + input.to_string() + "'"); } res = false; break; case -2 : if (transaction) { ms_dbg_a(transaction, 7, "Invalid URL Encoding: Non-hexadecimal " - "digits used at '" + input + "'"); + "digits used at '" + input.to_string() + "'"); logOffset(ruleMessage, offset, input.size()); } res = true; /* Invalid match. */ @@ -97,7 +100,7 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru case -3 : if (transaction) { ms_dbg_a(transaction, 7, "Invalid URL Encoding: Not enough " \ - "characters at the end of input at '" + input + "'"); + "characters at the end of input at '" + input.to_string() + "'"); logOffset(ruleMessage, offset, input.size()); } res = true; /* Invalid match. */ @@ -107,7 +110,7 @@ bool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *ru if (transaction) { ms_dbg_a(transaction, 7, "Invalid URL Encoding: Internal " \ "Error (rc = " + std::to_string(rc) + ") at '" + - input + "'"); + input.to_string() + "'"); logOffset(ruleMessage, offset, input.size()); } res = true; diff --git a/src/operators/validate_url_encoding.h b/src/operators/validate_url_encoding.h index 80d61b96c9..b48ee78d73 100644 --- a/src/operators/validate_url_encoding.h +++ b/src/operators/validate_url_encoding.h @@ -31,9 +31,10 @@ class ValidateUrlEncoding : public Operator { ValidateUrlEncoding() : Operator("ValidateUrlEncoding") { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; static int validate_url_encoding(const char *input, uint64_t input_length, size_t *offset); diff --git a/src/operators/validate_utf8_encoding.cc b/src/operators/validate_utf8_encoding.cc index 9374116a9e..319d48f6dd 100644 --- a/src/operators/validate_utf8_encoding.cc +++ b/src/operators/validate_utf8_encoding.cc @@ -113,8 +113,10 @@ int ValidateUtf8Encoding::detect_utf8_character( return unicode_len; } -bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { +bool ValidateUtf8Encoding::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { unsigned int i, bytes_left; const char *str_c = str.c_str(); @@ -128,7 +130,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " "not enough bytes in character " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); } return true; @@ -137,7 +139,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " "invalid byte value in character " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); logOffset(ruleMessage, i, str.size()); } @@ -147,7 +149,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " "overlong character detected " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); logOffset(ruleMessage, i, str.size()); } @@ -157,7 +159,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r if (transaction) { ms_dbg_a(transaction, 8, "Invalid UTF-8 encoding: " "use of restricted character " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); logOffset(ruleMessage, i, str.size()); } @@ -166,7 +168,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r case UNICODE_ERROR_DECODING_ERROR : if (transaction) { ms_dbg_a(transaction, 8, "Error validating UTF-8 decoding " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); logOffset(ruleMessage, i, str.size()); } @@ -177,7 +179,7 @@ bool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *r if (rc <= 0) { if (transaction) { ms_dbg_a(transaction, 8, "Internal error during UTF-8 validation " - "at " + str + ". [offset \"" + + "at " + str.to_string() + ". [offset \"" + std::to_string(i) + "\"]"); logOffset(ruleMessage, i, str.size()); } diff --git a/src/operators/validate_utf8_encoding.h b/src/operators/validate_utf8_encoding.h index e01c19a225..49ae82947a 100644 --- a/src/operators/validate_utf8_encoding.h +++ b/src/operators/validate_utf8_encoding.h @@ -38,9 +38,10 @@ class ValidateUtf8Encoding : public Operator { ValidateUtf8Encoding() : Operator("ValidateUtf8Encoding") { } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; static int detect_utf8_character(const unsigned char *p_read, unsigned int length); diff --git a/src/operators/verify_cc.cc b/src/operators/verify_cc.cc index f23c7a1f98..56fa2c545f 100644 --- a/src/operators/verify_cc.cc +++ b/src/operators/verify_cc.cc @@ -21,6 +21,8 @@ #include #include "src/operators/operator.h" +#include "src/rule_with_actions.h" + #if PCRE_HAVE_JIT #define pcre_study_opt PCRE_STUDY_JIT_COMPILE @@ -117,8 +119,10 @@ bool VerifyCC::init(const std::string ¶m2, std::string *error) { } -bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& i, std::shared_ptr ruleMessage) { +bool VerifyCC::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &i, + RuleMessage *ruleMessage) { int offset = 0; int target_length = i.length(); @@ -137,18 +141,18 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, return false; } if (ret > 0) { - match = std::string(i, ovector[0], ovector[1] - ovector[0]); + match = std::string(i.to_string(), ovector[0], ovector[1] - ovector[0]); int is_cc = luhnVerify(match.c_str(), match.size()); if (is_cc) { - if (t) { - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( + if (transaction) { + if (rule && transaction && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( "0", std::string(match)); - ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + \ + ms_dbg_a(transaction, 7, "Added VerifyCC match TX.0: " + \ std::string(match)); } - ms_dbg_a(t, 9, "CC# match \"" + m_param + - "\" at " + i + ". [offset " + + ms_dbg_a(transaction, 9, "CC# match \"" + m_param + + "\" at " + i.to_string() + ". [offset " + std::to_string(offset) + "]"); } return true; diff --git a/src/operators/verify_cc.h b/src/operators/verify_cc.h index ee97f2b4b9..e14c756671 100644 --- a/src/operators/verify_cc.h +++ b/src/operators/verify_cc.h @@ -35,10 +35,13 @@ class VerifyCC : public Operator { m_pce(NULL) { } ~VerifyCC(); - bool evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; bool init(const std::string ¶m, std::string *error) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; + private: pcre *m_pc; pcre_extra *m_pce; diff --git a/src/operators/verify_cpf.cc b/src/operators/verify_cpf.cc index 0ec49ac479..45310f3b95 100644 --- a/src/operators/verify_cpf.cc +++ b/src/operators/verify_cpf.cc @@ -19,6 +19,8 @@ #include #include "src/operators/operator.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { @@ -108,8 +110,10 @@ bool VerifyCPF::verify(const char *cpfnumber, int len) { } -bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool VerifyCPF::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { std::list matches; bool is_cpf = false; int i; @@ -119,15 +123,15 @@ bool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule, } for (i = 0; i < input.size() - 1 && is_cpf == false; i++) { - matches = m_re->searchAll(input.substr(i, input.size())); + matches = m_re->searchAll(input.substr(i, input.size()).to_string()); for (const auto & m : matches) { is_cpf = verify(m.str().c_str(), m.str().size()); if (is_cpf) { logOffset(ruleMessage, m.offset(), m.str().size()); - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( + if (rule && transaction && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( "0", m.str()); - ms_dbg_a(t, 7, "Added VerifyCPF match TX.0: " + \ + ms_dbg_a(transaction, 7, "Added VerifyCPF match TX.0: " + \ m.str()); } diff --git a/src/operators/verify_cpf.h b/src/operators/verify_cpf.h index c5b0dfa593..0b5e8b3db6 100644 --- a/src/operators/verify_cpf.h +++ b/src/operators/verify_cpf.h @@ -46,9 +46,10 @@ class VerifyCPF : public Operator { bool operator=(const VerifyCPF &a) = delete; VerifyCPF(const VerifyCPF &a) = delete; - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; bool verify(const char *ssnumber, int len); diff --git a/src/operators/verify_ssn.cc b/src/operators/verify_ssn.cc index 00b0c5c201..16c8ec7bf6 100644 --- a/src/operators/verify_ssn.cc +++ b/src/operators/verify_ssn.cc @@ -20,6 +20,8 @@ #include #include "src/operators/operator.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace operators { @@ -110,8 +112,10 @@ bool VerifySSN::verify(const char *ssnumber, int len) { } -bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool VerifySSN::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) { std::list matches; bool is_ssn = false; int i; @@ -121,15 +125,15 @@ bool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule, } for (i = 0; i < input.size() - 1 && is_ssn == false; i++) { - matches = m_re->searchAll(input.substr(i, input.size())); + matches = m_re->searchAll(input.substr(i, input.size()).to_string()); for (const auto & j : matches) { is_ssn = verify(j.str().c_str(), j.str().size()); if (is_ssn) { logOffset(ruleMessage, j.offset(), j.str().size()); - if (rule && t && rule->hasCaptureAction()) { - t->m_collections.m_tx_collection->storeOrUpdateFirst( + if (rule && transaction && rule->hasCaptureAction()) { + transaction->m_collections.m_tx_collection->storeOrUpdateFirst( "0", j.str()); - ms_dbg_a(t, 7, "Added VerifySSN match TX.0: " + \ + ms_dbg_a(transaction, 7, "Added VerifySSN match TX.0: " + \ j.str()); } diff --git a/src/operators/verify_ssn.h b/src/operators/verify_ssn.h index 86f3341344..55c5cb12f0 100644 --- a/src/operators/verify_ssn.h +++ b/src/operators/verify_ssn.h @@ -46,9 +46,10 @@ class VerifySSN : public Operator { bool operator=(const VerifySSN &a) = delete; VerifySSN(const VerifySSN &a) = delete; - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; diff --git a/src/operators/verify_svnr.cc b/src/operators/verify_svnr.cc index 248e6b4ec1..2673afd623 100644 --- a/src/operators/verify_svnr.cc +++ b/src/operators/verify_svnr.cc @@ -9,6 +9,7 @@ #include "modsecurity/rule_message.h" #include "modsecurity/rules_set_properties.h" +#include "src/rule_with_actions.h" namespace modsecurity { namespace operators { @@ -77,8 +78,10 @@ bool VerifySVNR::verify(const char *svnrnumber, int len) { } -bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule, - const std::string& input, std::shared_ptr ruleMessage) { +bool VerifySVNR::evaluate(Transaction *t, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage* ruleMessage) { std::list matches; bool is_svnr = false; int i; @@ -88,7 +91,7 @@ bool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule, } for (i = 0; i < input.size() - 1 && is_svnr == false; i++) { - matches = m_re->searchAll(input.substr(i, input.size())); + matches = m_re->searchAll(input.substr(i, input.size()).to_string()); for (const auto & j : matches) { is_svnr = verify(j.str().c_str(), j.str().size()); diff --git a/src/operators/verify_svnr.h b/src/operators/verify_svnr.h index 6fe9df9afb..5a9511fc81 100644 --- a/src/operators/verify_svnr.h +++ b/src/operators/verify_svnr.h @@ -32,9 +32,10 @@ class VerifySVNR : public Operator { bool operator=(const VerifySVNR &a) = delete; VerifySVNR(const VerifySVNR &a) = delete; - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string& input, - std::shared_ptr ruleMessage) override; + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; bool verify(const char *ssnumber, int len); diff --git a/src/operators/within.cc b/src/operators/within.cc index f83f53a718..bb74392129 100644 --- a/src/operators/within.cc +++ b/src/operators/within.cc @@ -24,8 +24,10 @@ namespace modsecurity { namespace operators { -bool Within::evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) { +bool Within::evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &str, + RuleMessage *ruleMessage) { bool res = false; size_t pos = 0; std::string paramTarget(m_string->evaluate(transaction)); @@ -34,7 +36,7 @@ bool Within::evaluate(Transaction *transaction, RuleWithActions *rule, return true; } - pos = paramTarget.find(str); + pos = paramTarget.find(str.c_str()); res = pos != std::string::npos; if (res) { logOffset(ruleMessage, pos, str.size()); diff --git a/src/operators/within.h b/src/operators/within.h index 1a03aa687c..81f371b10c 100644 --- a/src/operators/within.h +++ b/src/operators/within.h @@ -33,8 +33,11 @@ class Within : public Operator { : Operator("Within", std::move(param)) { m_couldContainsMacro = true; } - bool evaluate(Transaction *transaction, RuleWithActions *rule, - const std::string &str, std::shared_ptr ruleMessage) override; + + bool evaluate(Transaction *transaction, + const RuleWithActions *rule, + const bpstd::string_view &input, + RuleMessage *ruleMessage) override; }; } // namespace operators diff --git a/src/parser/driver.cc b/src/parser/driver.cc index 6e97ae0f04..15f6615f7f 100644 --- a/src/parser/driver.cc +++ b/src/parser/driver.cc @@ -18,7 +18,7 @@ #include "modsecurity/rules_set_properties.h" #include "src/parser/seclang-parser.hh" #include "modsecurity/audit_log.h" -#include "modsecurity/rule_marker.h" +#include "src/rule_marker.h" using modsecurity::audit_log::AuditLog; using modsecurity::RuleWithOperator; @@ -81,16 +81,92 @@ int Driver::addSecRule(std::unique_ptr r) { } /* is it a chained rule? */ - if (m_lastRule != nullptr && m_lastRule->isChained()) { + if (m_lastRule != nullptr && m_lastRule->hasChainAction()) { r->setPhase(m_lastRule->getPhase()); if (r->hasDisruptiveAction()) { m_parserError << "Disruptive actions can only be specified by"; m_parserError << " chain starter rules."; return false; } - m_lastRule->m_chainedRuleChild = std::move(r); - m_lastRule->m_chainedRuleChild->m_chainedRuleParent = m_lastRule; - m_lastRule = m_lastRule->m_chainedRuleChild.get(); + + m_lastRule->setChainedNext(std::move(r)); + m_lastRule->getChainedNext()->setChainedParent(m_lastRule); + m_lastRule = m_lastRule->getChainedNext(); + + /* Lets set all meta-data to the first rule */ + RuleWithActions *firstRule = m_lastRule; + if (!firstRule->hasChainAction()) { + while (firstRule->getChainedParent() != nullptr) { + if (firstRule->hasMessageAction()) { + firstRule->getChainedParent()->setMessageAction( + firstRule->getMessageAction() + ); + firstRule->setMessageAction(nullptr); + } + if (firstRule->hasLogDataAction()) { + firstRule->getChainedParent()->setLogDataAction( + firstRule->getLogDataAction() + ); + firstRule->setLogDataAction(nullptr); + } + if (firstRule->hasSeverityAction()) { + firstRule->getChainedParent()->setSeverity( + firstRule->getSeverity() + ); + } + if (firstRule->hasRevisionAction()) { + firstRule->getChainedParent()->setRevision( + firstRule->getRevision() + ); + } + if (firstRule->hasVersionAction()) { + firstRule->getChainedParent()->setVersion( + firstRule->getVersion() + ); + } + if (firstRule->hasAccuracyAction()) { + firstRule->getChainedParent()->setAccuracy( + firstRule->getAccuracy() + ); + } + if (firstRule->hasMaturityAction()) { + firstRule->getChainedParent()->setMaturity( + firstRule->getMaturity() + ); + } + + if (firstRule->hasTagAction()) { + firstRule->getChainedParent()->setTags( + firstRule->getTagsAction() + ); + firstRule->cleanTags(); + } + + if (firstRule->hasDisruptiveAction()) { + firstRule->getChainedParent()->setDisruptiveAction( + firstRule->getDisruptiveAction() + ); + firstRule->setDisruptiveAction(nullptr); + } + firstRule->getChainedParent()->setHasBlockAction( + firstRule->hasBlockAction() + ); + firstRule->getChainedParent()->setHasLogAction( + firstRule->hasLogAction() + ); + firstRule->getChainedParent()->setHasLogAction( + firstRule->hasNoLogAction() + ); + firstRule->getChainedParent()->setHasAuditLogAction( + firstRule->hasAuditLogAction() + ); + firstRule->getChainedParent()->setHasNoAuditLogAction( + firstRule->hasNoAuditLogAction() + ); + firstRule = firstRule->getChainedParent(); + } + } + return true; } @@ -99,26 +175,15 @@ int Driver::addSecRule(std::unique_ptr r) { * Checking if the rule has an ID and also checking if this ID is not used * by other rule */ - if (rule->m_ruleId == 0) { + if (rule->getId() == 0) { m_parserError << "Rules must have an ID. File: "; m_parserError << rule->getFileName() << " at line: "; m_parserError << std::to_string(rule->getLineNumber()) << std::endl; return false; } - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - Rules *rules = m_rulesSetPhases[i]; - for (int j = 0; j < rules->size(); j++) { - RuleWithOperator *lr = dynamic_cast(rules->at(j).get()); - if (lr && lr->m_ruleId == rule->m_ruleId) { - m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \ - << " is duplicated" << std::endl; - return false; - } - } - } - m_lastRule = rule.get(); + m_rulesSetPhases.insert(rule); return true; diff --git a/src/parser/location.hh b/src/parser/location.hh index eafd7be734..5757718f37 100644 --- a/src/parser/location.hh +++ b/src/parser/location.hh @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.5.3. +// A Bison parser, made by GNU Bison 3.6.2. // Locations for Bison parsers in C++ diff --git a/src/parser/position.hh b/src/parser/position.hh index faf8952748..4f090056c4 100644 --- a/src/parser/position.hh +++ b/src/parser/position.hh @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.5.3. +// A Bison parser, made by GNU Bison 3.6.2. // Starting with Bison 3.2, this file is useless: the structure it // used to define is now defined in "location.hh". diff --git a/src/parser/seclang-parser.cc b/src/parser/seclang-parser.cc index 7672095334..a7a2d08488 100644 --- a/src/parser/seclang-parser.cc +++ b/src/parser/seclang-parser.cc @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.5.3. +// A Bison parser, made by GNU Bison 3.6.2. // Skeleton implementation for Bison LALR(1) parsers in C++ @@ -30,8 +30,9 @@ // This special exception was added by the Free Software Foundation in // version 2.2 of Bison. -// Undocumented macros, especially those whose name start with YY_, -// are private implementation details. Do not rely on them. +// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, +// especially those whose name start with YY_ or yy_. They are +// private implementation details that can be changed or removed. @@ -41,11 +42,11 @@ // Unqualified %code blocks. -#line 324 "seclang-parser.yy" +#line 327 "seclang-parser.yy" #include "src/parser/driver.h" -#line 49 "seclang-parser.cc" +#line 50 "seclang-parser.cc" #ifndef YY_ @@ -60,6 +61,7 @@ # endif #endif + // Whether we are compiled with exception support. #ifndef YY_EXCEPTIONS # if defined __GNUC__ && !defined __EXCEPTIONS @@ -115,7 +117,7 @@ # define YY_STACK_PRINT() \ do { \ if (yydebug_) \ - yystack_print_ (); \ + yy_stack_print_ (); \ } while (false) #else // !YYDEBUG @@ -136,49 +138,7 @@ #define YYRECOVERING() (!!yyerrstatus_) namespace yy { -#line 140 "seclang-parser.cc" - - - /* Return YYSTR after stripping away unnecessary quotes and - backslashes, so that it's suitable for yyerror. The heuristic is - that double-quoting is unnecessary unless the string contains an - apostrophe, a comma, or backslash (other than backslash-backslash). - YYSTR is taken from yytname. */ - std::string - seclang_parser::yytnamerr_ (const char *yystr) - { - if (*yystr == '"') - { - std::string yyr; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - else - goto append; - - append: - default: - yyr += *yyp; - break; - - case '"': - return yyr; - } - do_not_strip_quotes: ; - } - - return yystr; - } - +#line 142 "seclang-parser.cc" /// Build a parser object. seclang_parser::seclang_parser (modsecurity::Parser::Driver& driver_yyarg) @@ -198,7 +158,7 @@ namespace yy { {} /*---------------. - | Symbol types. | + | symbol kinds. | `---------------*/ @@ -229,13 +189,13 @@ namespace yy { : state (s) {} - seclang_parser::symbol_number_type - seclang_parser::by_state::type_get () const YY_NOEXCEPT + seclang_parser::symbol_kind_type + seclang_parser::by_state::kind () const YY_NOEXCEPT { if (state == empty_state) - return empty_symbol; + return symbol_kind::S_YYEMPTY; else - return yystos_[+state]; + return YY_CAST (symbol_kind_type, yystos_[+state]); } seclang_parser::stack_symbol_type::stack_symbol_type () @@ -244,7 +204,7 @@ namespace yy { seclang_parser::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that) : super_type (YY_MOVE (that.state), YY_MOVE (that.location)) { - switch (that.type_get ()) + switch (that.kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -488,7 +448,7 @@ namespace yy { seclang_parser::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that) : super_type (s, YY_MOVE (that.location)) { - switch (that.type_get ()) + switch (that.kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -724,7 +684,7 @@ namespace yy { } // that is emptied. - that.type = empty_symbol; + that.kind_ = symbol_kind::S_YYEMPTY; } #if YY_CPLUSPLUS < 201103L @@ -732,7 +692,7 @@ namespace yy { seclang_parser::stack_symbol_type::operator= (const stack_symbol_type& that) { state = that.state; - switch (that.type_get ()) + switch (that.kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -975,7 +935,7 @@ namespace yy { seclang_parser::stack_symbol_type::operator= (stack_symbol_type& that) { state = that.state; - switch (that.type_get ()) + switch (that.kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -1228,23 +1188,21 @@ namespace yy { #if YYDEBUG template void - seclang_parser::yy_print_ (std::ostream& yyo, - const basic_symbol& yysym) const + seclang_parser::yy_print_ (std::ostream& yyo, const basic_symbol& yysym) const { std::ostream& yyoutput = yyo; YYUSE (yyoutput); - symbol_number_type yytype = yysym.type_get (); -#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408 - // Avoid a (spurious) G++ 4.8 warning about "array subscript is - // below array bounds". if (yysym.empty ()) - std::abort (); -#endif - yyo << (yytype < yyntokens_ ? "token" : "nterm") - << ' ' << yytname_[yytype] << " (" - << yysym.location << ": "; - YYUSE (yytype); - yyo << ')'; + yyo << "empty symbol"; + else + { + symbol_kind_type yykind = yysym.kind (); + yyo << (yykind < YYNTOKENS ? "token" : "nterm") + << ' ' << yysym.name () << " (" + << yysym.location << ": "; + YYUSE (yykind); + yyo << ')'; + } } #endif @@ -1303,11 +1261,11 @@ namespace yy { seclang_parser::state_type seclang_parser::yy_lr_goto_state_ (state_type yystate, int yysym) { - int yyr = yypgoto_[yysym - yyntokens_] + yystate; + int yyr = yypgoto_[yysym - YYNTOKENS] + yystate; if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate) return yytable_[yyr]; else - return yydefgoto_[yysym - yyntokens_]; + return yydefgoto_[yysym - YYNTOKENS]; } bool @@ -1356,13 +1314,13 @@ namespace yy { // User initialization code. -#line 317 "seclang-parser.yy" +#line 320 "seclang-parser.yy" { // Initialize the initial location. yyla.location.begin.filename = yyla.location.end.filename = new std::string(driver.file); } -#line 1366 "seclang-parser.cc" +#line 1324 "seclang-parser.cc" /* Initialize the stack. The initial state will be set in @@ -1377,6 +1335,7 @@ namespace yy { `-----------------------------------------------*/ yynewstate: YYCDEBUG << "Entering state " << int (yystack_[0].state) << '\n'; + YY_STACK_PRINT (); // Accept? if (yystack_[0].state == yyfinal_) @@ -1397,7 +1356,7 @@ namespace yy { // Read a lookahead token. if (yyla.empty ()) { - YYCDEBUG << "Reading a token: "; + YYCDEBUG << "Reading a token\n"; #if YY_EXCEPTIONS try #endif // YY_EXCEPTIONS @@ -1416,10 +1375,20 @@ namespace yy { } YY_SYMBOL_PRINT ("Next token is", yyla); + if (yyla.kind () == symbol_kind::S_YYerror) + { + // The scanner already issued an error message, process directly + // to error recovery. But do not keep the error token as + // lookahead, it is too special and may lead us to an endless + // loop in error recovery. */ + yyla.kind_ = symbol_kind::S_YYUNDEF; + goto yyerrlab1; + } + /* If the proper action on seeing token YYLA.TYPE is to reduce or to detect an error, take that action. */ - yyn += yyla.type_get (); - if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ()) + yyn += yyla.kind (); + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ()) { goto yydefault; } @@ -1716,241 +1685,241 @@ namespace yy { switch (yyn) { case 2: -#line 709 "seclang-parser.yy" +#line 712 "seclang-parser.yy" { return 0; } -#line 1724 "seclang-parser.cc" +#line 1693 "seclang-parser.cc" break; case 6: -#line 722 "seclang-parser.yy" +#line 725 "seclang-parser.yy" { driver.m_auditLog->setStorageDirMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8)); } -#line 1732 "seclang-parser.cc" +#line 1701 "seclang-parser.cc" break; case 7: -#line 728 "seclang-parser.yy" +#line 731 "seclang-parser.yy" { driver.m_auditLog->setStorageDir(yystack_[0].value.as < std::string > ()); } -#line 1740 "seclang-parser.cc" +#line 1709 "seclang-parser.cc" break; case 8: -#line 734 "seclang-parser.yy" +#line 737 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::RelevantOnlyAuditLogStatus); } -#line 1748 "seclang-parser.cc" +#line 1717 "seclang-parser.cc" break; case 9: -#line 738 "seclang-parser.yy" +#line 741 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OffAuditLogStatus); } -#line 1756 "seclang-parser.cc" +#line 1725 "seclang-parser.cc" break; case 10: -#line 742 "seclang-parser.yy" +#line 745 "seclang-parser.yy" { driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OnAuditLogStatus); } -#line 1764 "seclang-parser.cc" +#line 1733 "seclang-parser.cc" break; case 11: -#line 748 "seclang-parser.yy" +#line 751 "seclang-parser.yy" { driver.m_auditLog->setFileMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8)); } -#line 1772 "seclang-parser.cc" +#line 1741 "seclang-parser.cc" break; case 12: -#line 754 "seclang-parser.yy" +#line 757 "seclang-parser.yy" { driver.m_auditLog->setFilePath2(yystack_[0].value.as < std::string > ()); } -#line 1780 "seclang-parser.cc" +#line 1749 "seclang-parser.cc" break; case 13: -#line 760 "seclang-parser.yy" +#line 763 "seclang-parser.yy" { driver.m_auditLog->setParts(yystack_[0].value.as < std::string > ()); } -#line 1788 "seclang-parser.cc" +#line 1757 "seclang-parser.cc" break; case 14: -#line 766 "seclang-parser.yy" +#line 769 "seclang-parser.yy" { driver.m_auditLog->setFilePath1(yystack_[0].value.as < std::string > ()); } -#line 1796 "seclang-parser.cc" +#line 1765 "seclang-parser.cc" break; case 15: -#line 771 "seclang-parser.yy" +#line 774 "seclang-parser.yy" { driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::JSONAuditLogFormat); } -#line 1804 "seclang-parser.cc" +#line 1773 "seclang-parser.cc" break; case 16: -#line 776 "seclang-parser.yy" +#line 779 "seclang-parser.yy" { driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::NativeAuditLogFormat); } -#line 1812 "seclang-parser.cc" +#line 1781 "seclang-parser.cc" break; case 17: -#line 782 "seclang-parser.yy" +#line 785 "seclang-parser.yy" { std::string relevant_status(yystack_[0].value.as < std::string > ()); driver.m_auditLog->setRelevantStatus(relevant_status); } -#line 1821 "seclang-parser.cc" +#line 1790 "seclang-parser.cc" break; case 18: -#line 789 "seclang-parser.yy" +#line 792 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::SerialAuditLogType); } -#line 1829 "seclang-parser.cc" +#line 1798 "seclang-parser.cc" break; case 19: -#line 793 "seclang-parser.yy" +#line 796 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::ParallelAuditLogType); } -#line 1837 "seclang-parser.cc" +#line 1806 "seclang-parser.cc" break; case 20: -#line 797 "seclang-parser.yy" +#line 800 "seclang-parser.yy" { driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::HttpsAuditLogType); } -#line 1845 "seclang-parser.cc" +#line 1814 "seclang-parser.cc" break; case 21: -#line 803 "seclang-parser.yy" +#line 806 "seclang-parser.yy" { driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 1853 "seclang-parser.cc" +#line 1822 "seclang-parser.cc" break; case 22: -#line 807 "seclang-parser.yy" +#line 810 "seclang-parser.yy" { driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 1861 "seclang-parser.cc" +#line 1830 "seclang-parser.cc" break; case 23: -#line 811 "seclang-parser.yy" +#line 814 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecUploadKeepFiles RelevantOnly is not currently supported. Accepted values are On or Off"); YYERROR; } -#line 1870 "seclang-parser.cc" +#line 1839 "seclang-parser.cc" break; case 24: -#line 816 "seclang-parser.yy" +#line 819 "seclang-parser.yy" { driver.m_uploadFileLimit.m_set = true; driver.m_uploadFileLimit.m_value = strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 10); } -#line 1879 "seclang-parser.cc" +#line 1848 "seclang-parser.cc" break; case 25: -#line 821 "seclang-parser.yy" +#line 824 "seclang-parser.yy" { driver.m_uploadFileMode.m_set = true; driver.m_uploadFileMode.m_value = strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8); } -#line 1888 "seclang-parser.cc" +#line 1857 "seclang-parser.cc" break; case 26: -#line 826 "seclang-parser.yy" +#line 829 "seclang-parser.yy" { driver.m_uploadDirectory.m_set = true; driver.m_uploadDirectory.m_value = yystack_[0].value.as < std::string > (); } -#line 1897 "seclang-parser.cc" +#line 1866 "seclang-parser.cc" break; case 27: -#line 831 "seclang-parser.yy" +#line 834 "seclang-parser.yy" { driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 1905 "seclang-parser.cc" +#line 1874 "seclang-parser.cc" break; case 28: -#line 835 "seclang-parser.yy" +#line 838 "seclang-parser.yy" { driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 1913 "seclang-parser.cc" +#line 1882 "seclang-parser.cc" break; case 29: -#line 842 "seclang-parser.yy" +#line 845 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[1].value.as < std::unique_ptr > > > ()); } -#line 1921 "seclang-parser.cc" +#line 1890 "seclang-parser.cc" break; case 30: -#line 846 "seclang-parser.yy" +#line 849 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); } -#line 1929 "seclang-parser.cc" +#line 1898 "seclang-parser.cc" break; case 31: -#line 853 "seclang-parser.yy" +#line 856 "seclang-parser.yy" { ACTION_INIT(yystack_[0].value.as < std::unique_ptr > (), yystack_[3].location) yystack_[2].value.as < std::unique_ptr > > > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[2].value.as < std::unique_ptr > > > ()); } -#line 1939 "seclang-parser.cc" +#line 1908 "seclang-parser.cc" break; case 32: -#line 859 "seclang-parser.yy" +#line 862 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); ACTION_INIT(yystack_[0].value.as < std::unique_ptr > (), yystack_[1].location) b->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 1950 "seclang-parser.cc" +#line 1919 "seclang-parser.cc" break; case 33: -#line 869 "seclang-parser.yy" +#line 872 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); std::string error; @@ -1959,11 +1928,11 @@ namespace yy { YYERROR; } } -#line 1963 "seclang-parser.cc" +#line 1932 "seclang-parser.cc" break; case 34: -#line 878 "seclang-parser.yy" +#line 881 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); yylhs.value.as < std::unique_ptr > ()->m_negation = true; @@ -1973,11 +1942,11 @@ namespace yy { YYERROR; } } -#line 1977 "seclang-parser.cc" +#line 1946 "seclang-parser.cc" break; case 35: -#line 888 "seclang-parser.yy" +#line 891 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); std::string error; @@ -1986,11 +1955,11 @@ namespace yy { YYERROR; } } -#line 1990 "seclang-parser.cc" +#line 1959 "seclang-parser.cc" break; case 36: -#line 897 "seclang-parser.yy" +#line 900 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yylhs.value.as < std::unique_ptr > ()->m_negation = true; @@ -2000,294 +1969,294 @@ namespace yy { YYERROR; } } -#line 2004 "seclang-parser.cc" +#line 1973 "seclang-parser.cc" break; case 37: -#line 910 "seclang-parser.yy" +#line 913 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::UnconditionalMatch()); } -#line 2012 "seclang-parser.cc" +#line 1981 "seclang-parser.cc" break; case 38: -#line 914 "seclang-parser.yy" +#line 917 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::DetectSQLi()); } -#line 2020 "seclang-parser.cc" +#line 1989 "seclang-parser.cc" break; case 39: -#line 918 "seclang-parser.yy" +#line 921 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::DetectXSS()); } -#line 2028 "seclang-parser.cc" +#line 1997 "seclang-parser.cc" break; case 40: -#line 922 "seclang-parser.yy" +#line 925 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateUrlEncoding()); } -#line 2036 "seclang-parser.cc" +#line 2005 "seclang-parser.cc" break; case 41: -#line 926 "seclang-parser.yy" +#line 929 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateUtf8Encoding()); } -#line 2044 "seclang-parser.cc" +#line 2013 "seclang-parser.cc" break; case 42: -#line 930 "seclang-parser.yy" +#line 933 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::InspectFile(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2052 "seclang-parser.cc" +#line 2021 "seclang-parser.cc" break; case 43: -#line 934 "seclang-parser.yy" +#line 937 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::FuzzyHash(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2060 "seclang-parser.cc" +#line 2029 "seclang-parser.cc" break; case 44: -#line 938 "seclang-parser.yy" +#line 941 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateByteRange(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2068 "seclang-parser.cc" +#line 2037 "seclang-parser.cc" break; case 45: -#line 942 "seclang-parser.yy" +#line 945 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateDTD(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2076 "seclang-parser.cc" +#line 2045 "seclang-parser.cc" break; case 46: -#line 946 "seclang-parser.yy" +#line 949 "seclang-parser.yy" { /* $$ = new operators::ValidateHash($1); */ OPERATOR_NOT_SUPPORTED("ValidateHash", yystack_[2].location); } -#line 2085 "seclang-parser.cc" +#line 2054 "seclang-parser.cc" break; case 47: -#line 951 "seclang-parser.yy" +#line 954 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ValidateSchema(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2093 "seclang-parser.cc" +#line 2062 "seclang-parser.cc" break; case 48: -#line 955 "seclang-parser.yy" +#line 958 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifyCC(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2101 "seclang-parser.cc" +#line 2070 "seclang-parser.cc" break; case 49: -#line 959 "seclang-parser.yy" +#line 962 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifyCPF(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2109 "seclang-parser.cc" +#line 2078 "seclang-parser.cc" break; case 50: -#line 963 "seclang-parser.yy" +#line 966 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifySSN(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2117 "seclang-parser.cc" +#line 2086 "seclang-parser.cc" break; case 51: -#line 967 "seclang-parser.yy" +#line 970 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::VerifySVNR(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2125 "seclang-parser.cc" +#line 2094 "seclang-parser.cc" break; case 52: -#line 971 "seclang-parser.yy" +#line 974 "seclang-parser.yy" { /* $$ = new operators::GsbLookup($1); */ OPERATOR_NOT_SUPPORTED("GsbLookup", yystack_[2].location); } -#line 2134 "seclang-parser.cc" +#line 2103 "seclang-parser.cc" break; case 53: -#line 976 "seclang-parser.yy" +#line 979 "seclang-parser.yy" { /* $$ = new operators::Rsub($1); */ OPERATOR_NOT_SUPPORTED("Rsub", yystack_[2].location); } -#line 2143 "seclang-parser.cc" +#line 2112 "seclang-parser.cc" break; case 54: -#line 981 "seclang-parser.yy" +#line 984 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Within(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2151 "seclang-parser.cc" +#line 2120 "seclang-parser.cc" break; case 55: -#line 985 "seclang-parser.yy" +#line 988 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::ContainsWord(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2159 "seclang-parser.cc" +#line 2128 "seclang-parser.cc" break; case 56: -#line 989 "seclang-parser.yy" +#line 992 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Contains(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2167 "seclang-parser.cc" +#line 2136 "seclang-parser.cc" break; case 57: -#line 993 "seclang-parser.yy" +#line 996 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::EndsWith(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2175 "seclang-parser.cc" +#line 2144 "seclang-parser.cc" break; case 58: -#line 997 "seclang-parser.yy" +#line 1000 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Eq(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2183 "seclang-parser.cc" +#line 2152 "seclang-parser.cc" break; case 59: -#line 1001 "seclang-parser.yy" +#line 1004 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Ge(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2191 "seclang-parser.cc" +#line 2160 "seclang-parser.cc" break; case 60: -#line 1005 "seclang-parser.yy" +#line 1008 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Gt(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2199 "seclang-parser.cc" +#line 2168 "seclang-parser.cc" break; case 61: -#line 1009 "seclang-parser.yy" +#line 1012 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::IpMatchF(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2207 "seclang-parser.cc" +#line 2176 "seclang-parser.cc" break; case 62: -#line 1013 "seclang-parser.yy" +#line 1016 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::IpMatch(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2215 "seclang-parser.cc" +#line 2184 "seclang-parser.cc" break; case 63: -#line 1017 "seclang-parser.yy" +#line 1020 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Le(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2223 "seclang-parser.cc" +#line 2192 "seclang-parser.cc" break; case 64: -#line 1021 "seclang-parser.yy" +#line 1024 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Lt(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2231 "seclang-parser.cc" +#line 2200 "seclang-parser.cc" break; case 65: -#line 1025 "seclang-parser.yy" +#line 1028 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::PmFromFile(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2239 "seclang-parser.cc" +#line 2208 "seclang-parser.cc" break; case 66: -#line 1029 "seclang-parser.yy" +#line 1032 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Pm(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2247 "seclang-parser.cc" +#line 2216 "seclang-parser.cc" break; case 67: -#line 1033 "seclang-parser.yy" +#line 1036 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rbl(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2255 "seclang-parser.cc" +#line 2224 "seclang-parser.cc" break; case 68: -#line 1037 "seclang-parser.yy" +#line 1040 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2263 "seclang-parser.cc" +#line 2232 "seclang-parser.cc" break; case 69: -#line 1041 "seclang-parser.yy" +#line 1044 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::StrEq(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2271 "seclang-parser.cc" +#line 2240 "seclang-parser.cc" break; case 70: -#line 1045 "seclang-parser.yy" +#line 1048 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::StrMatch(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2279 "seclang-parser.cc" +#line 2248 "seclang-parser.cc" break; case 71: -#line 1049 "seclang-parser.yy" +#line 1052 "seclang-parser.yy" { OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::BeginsWith(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 2287 "seclang-parser.cc" +#line 2256 "seclang-parser.cc" break; case 72: -#line 1053 "seclang-parser.yy" +#line 1056 "seclang-parser.yy" { #if defined(WITH_GEOIP) or defined(WITH_MAXMIND) OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr > (), new operators::GeoLookup()); @@ -2298,17 +2267,19 @@ namespace yy { YYERROR; #endif // WITH_GEOIP } -#line 2302 "seclang-parser.cc" +#line 2271 "seclang-parser.cc" break; case 74: -#line 1068 "seclang-parser.yy" +#line 1071 "seclang-parser.yy" { std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -2332,11 +2303,11 @@ namespace yy { YYERROR; } } -#line 2336 "seclang-parser.cc" +#line 2307 "seclang-parser.cc" break; case 75: -#line 1098 "seclang-parser.yy" +#line 1103 "seclang-parser.yy" { variables::Variables *v = new variables::Variables(); for (auto &i : *yystack_[1].value.as < std::unique_ptr > > > ().get()) { @@ -2355,17 +2326,19 @@ namespace yy { YYERROR; } } -#line 2359 "seclang-parser.cc" +#line 2330 "seclang-parser.cc" break; case 76: -#line 1117 "seclang-parser.yy" +#line 1122 "seclang-parser.yy" { std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -2378,18 +2351,20 @@ namespace yy { )); driver.addSecAction(std::move(rule)); } -#line 2382 "seclang-parser.cc" +#line 2355 "seclang-parser.cc" break; case 77: -#line 1136 "seclang-parser.yy" +#line 1143 "seclang-parser.yy" { std::string err; std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *yystack_[0].value.as < std::unique_ptr > > > ().get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -2410,11 +2385,11 @@ namespace yy { YYERROR; } } -#line 2414 "seclang-parser.cc" +#line 2389 "seclang-parser.cc" break; case 78: -#line 1164 "seclang-parser.yy" +#line 1173 "seclang-parser.yy" { bool hasDisruptive = false; std::vector *actions = new std::vector(); @@ -2426,23 +2401,19 @@ namespace yy { int secRuleDefinedPhase = -1; for (actions::Action *a : *actions) { actions::Phase *phase = dynamic_cast(a); - if (a->isDisruptive() == true && dynamic_cast(a) == NULL) { + if (dynamic_cast(a) != NULL + && dynamic_cast(a) == NULL) { hasDisruptive = true; } if (phase != NULL) { - definedPhase = phase->m_phase; - secRuleDefinedPhase = phase->m_secRulesPhase; + definedPhase = phase->getPhase(); + secRuleDefinedPhase = phase->getSecRulePhase(); delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { - actions::transformations::None *none = dynamic_cast(a); - if (none != NULL) { - driver.error(yystack_[2].location, "The transformation none is not suitable to be part of the SecDefaultActions"); - YYERROR; - } + } else if (dynamic_cast(a) + && !dynamic_cast(a)) { checkedActions.push_back(a); } else { - driver.error(yystack_[2].location, "The action '" + *a->m_name.get() + "' is not suitable to be part of the SecDefaultActions"); + driver.error(yystack_[2].location, "The action '" + *a->getName() + "' is not suitable to be part of the SecDefaultActions"); YYERROR; } } @@ -2455,7 +2426,7 @@ namespace yy { YYERROR; } - if (!driver.m_defaultActions[definedPhase].empty()) { + if (!driver.m_rulesSetPhases[definedPhase]->m_defaultActions.empty()) { std::stringstream ss; ss << "SecDefaultActions can only be placed once per phase and configuration context. Phase "; ss << secRuleDefinedPhase; @@ -2465,84 +2436,89 @@ namespace yy { } for (actions::Action *a : checkedActions) { - driver.m_defaultActions[definedPhase].push_back( - std::unique_ptr(a)); + if (dynamic_cast(a)) { + driver.m_rulesSetPhases[definedPhase]->m_defaultTransformations.push_back( + std::shared_ptr( + dynamic_cast(a))); + } else { + driver.m_rulesSetPhases[definedPhase]->m_defaultActions.push_back(std::unique_ptr(a)); + } } delete actions; } -#line 2475 "seclang-parser.cc" +#line 2451 "seclang-parser.cc" break; case 79: -#line 1221 "seclang-parser.yy" +#line 1231 "seclang-parser.yy" { driver.addSecMarker(modsecurity::utils::string::removeBracketsIfNeeded(yystack_[0].value.as < std::string > ()), /* file name */ std::unique_ptr(new std::string(*yystack_[0].location.end.filename)), /* line number */ yystack_[0].location.end.line ); } -#line 2486 "seclang-parser.cc" +#line 2462 "seclang-parser.cc" break; case 80: -#line 1228 "seclang-parser.yy" +#line 1238 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::DisabledRuleEngine; } -#line 2494 "seclang-parser.cc" +#line 2470 "seclang-parser.cc" break; case 81: -#line 1232 "seclang-parser.yy" +#line 1242 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::EnabledRuleEngine; } -#line 2502 "seclang-parser.cc" +#line 2478 "seclang-parser.cc" break; case 82: -#line 1236 "seclang-parser.yy" +#line 1246 "seclang-parser.yy" { driver.m_secRuleEngine = modsecurity::RulesSet::DetectionOnlyRuleEngine; } -#line 2510 "seclang-parser.cc" +#line 2486 "seclang-parser.cc" break; case 83: -#line 1240 "seclang-parser.yy" +#line 1250 "seclang-parser.yy" { driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 2518 "seclang-parser.cc" +#line 2494 "seclang-parser.cc" break; case 84: -#line 1244 "seclang-parser.yy" +#line 1254 "seclang-parser.yy" { driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 2526 "seclang-parser.cc" +#line 2502 "seclang-parser.cc" break; case 85: -#line 1248 "seclang-parser.yy" +#line 1258 "seclang-parser.yy" { driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 2534 "seclang-parser.cc" +#line 2510 "seclang-parser.cc" break; case 86: -#line 1252 "seclang-parser.yy" +#line 1262 "seclang-parser.yy" { driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 2542 "seclang-parser.cc" +#line 2518 "seclang-parser.cc" break; case 87: -#line 1256 "seclang-parser.yy" +#line 1266 "seclang-parser.yy" { if (yystack_[0].value.as < std::string > ().length() != 1) { driver.error(yystack_[1].location, "Argument separator should be set to a single character."); @@ -2551,259 +2527,259 @@ namespace yy { driver.m_secArgumentSeparator.m_value = yystack_[0].value.as < std::string > (); driver.m_secArgumentSeparator.m_set = true; } -#line 2555 "seclang-parser.cc" +#line 2531 "seclang-parser.cc" break; case 88: -#line 1265 "seclang-parser.yy" +#line 1275 "seclang-parser.yy" { driver.m_components.push_back(yystack_[0].value.as < std::string > ()); } -#line 2563 "seclang-parser.cc" +#line 2539 "seclang-parser.cc" break; case 89: -#line 1269 "seclang-parser.yy" +#line 1279 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecConnEngine is not yet supported."); YYERROR; } -#line 2572 "seclang-parser.cc" +#line 2548 "seclang-parser.cc" break; case 90: -#line 1274 "seclang-parser.yy" +#line 1284 "seclang-parser.yy" { } -#line 2579 "seclang-parser.cc" +#line 2555 "seclang-parser.cc" break; case 91: -#line 1277 "seclang-parser.yy" +#line 1287 "seclang-parser.yy" { driver.m_secWebAppId.m_value = yystack_[0].value.as < std::string > (); driver.m_secWebAppId.m_set = true; } -#line 2588 "seclang-parser.cc" +#line 2564 "seclang-parser.cc" break; case 92: -#line 1282 "seclang-parser.yy" +#line 1292 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecServerSignature is not supported."); YYERROR; } -#line 2597 "seclang-parser.cc" +#line 2573 "seclang-parser.cc" break; case 93: -#line 1287 "seclang-parser.yy" +#line 1297 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecCacheTransformations is not supported."); YYERROR; } -#line 2606 "seclang-parser.cc" +#line 2582 "seclang-parser.cc" break; case 94: -#line 1292 "seclang-parser.yy" +#line 1302 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecDisableBackendCompression is not supported."); YYERROR; } -#line 2615 "seclang-parser.cc" +#line 2591 "seclang-parser.cc" break; case 95: -#line 1297 "seclang-parser.yy" +#line 1307 "seclang-parser.yy" { } -#line 2622 "seclang-parser.cc" +#line 2598 "seclang-parser.cc" break; case 96: -#line 1300 "seclang-parser.yy" +#line 1310 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecContentInjection is not yet supported."); YYERROR; } -#line 2631 "seclang-parser.cc" +#line 2607 "seclang-parser.cc" break; case 97: -#line 1305 "seclang-parser.yy" +#line 1315 "seclang-parser.yy" { } -#line 2638 "seclang-parser.cc" +#line 2614 "seclang-parser.cc" break; case 98: -#line 1308 "seclang-parser.yy" +#line 1318 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecChrootDir is not supported."); YYERROR; } -#line 2647 "seclang-parser.cc" +#line 2623 "seclang-parser.cc" break; case 99: -#line 1313 "seclang-parser.yy" +#line 1323 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecHashEngine is not yet supported."); YYERROR; } -#line 2656 "seclang-parser.cc" +#line 2632 "seclang-parser.cc" break; case 100: -#line 1318 "seclang-parser.yy" +#line 1328 "seclang-parser.yy" { } -#line 2663 "seclang-parser.cc" +#line 2639 "seclang-parser.cc" break; case 101: -#line 1321 "seclang-parser.yy" +#line 1331 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashKey is not yet supported."); YYERROR; } -#line 2672 "seclang-parser.cc" +#line 2648 "seclang-parser.cc" break; case 102: -#line 1326 "seclang-parser.yy" +#line 1336 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashParam is not yet supported."); YYERROR; } -#line 2681 "seclang-parser.cc" +#line 2657 "seclang-parser.cc" break; case 103: -#line 1331 "seclang-parser.yy" +#line 1341 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashMethodRx is not yet supported."); YYERROR; } -#line 2690 "seclang-parser.cc" +#line 2666 "seclang-parser.cc" break; case 104: -#line 1336 "seclang-parser.yy" +#line 1346 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecHashMethodPm is not yet supported."); YYERROR; } -#line 2699 "seclang-parser.cc" +#line 2675 "seclang-parser.cc" break; case 105: -#line 1341 "seclang-parser.yy" +#line 1351 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecGsbLookupDb is not supported."); YYERROR; } -#line 2708 "seclang-parser.cc" +#line 2684 "seclang-parser.cc" break; case 106: -#line 1346 "seclang-parser.yy" +#line 1356 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecGuardianLog is not supported."); YYERROR; } -#line 2717 "seclang-parser.cc" +#line 2693 "seclang-parser.cc" break; case 107: -#line 1351 "seclang-parser.yy" +#line 1361 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecInterceptOnError is not yet supported."); YYERROR; } -#line 2726 "seclang-parser.cc" +#line 2702 "seclang-parser.cc" break; case 108: -#line 1356 "seclang-parser.yy" +#line 1366 "seclang-parser.yy" { } -#line 2733 "seclang-parser.cc" +#line 2709 "seclang-parser.cc" break; case 109: -#line 1359 "seclang-parser.yy" +#line 1369 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecConnReadStateLimit is not yet supported."); YYERROR; } -#line 2742 "seclang-parser.cc" +#line 2718 "seclang-parser.cc" break; case 110: -#line 1364 "seclang-parser.yy" +#line 1374 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecConnWriteStateLimit is not yet supported."); YYERROR; } -#line 2751 "seclang-parser.cc" +#line 2727 "seclang-parser.cc" break; case 111: -#line 1369 "seclang-parser.yy" +#line 1379 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecSensorId is not yet supported."); YYERROR; } -#line 2760 "seclang-parser.cc" +#line 2736 "seclang-parser.cc" break; case 112: -#line 1374 "seclang-parser.yy" +#line 1384 "seclang-parser.yy" { driver.error(yystack_[2].location, "SecRuleInheritance is not yet supported."); YYERROR; } -#line 2769 "seclang-parser.cc" +#line 2745 "seclang-parser.cc" break; case 113: -#line 1379 "seclang-parser.yy" +#line 1389 "seclang-parser.yy" { } -#line 2776 "seclang-parser.cc" +#line 2752 "seclang-parser.cc" break; case 114: -#line 1382 "seclang-parser.yy" +#line 1392 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecRulePerfTime is not yet supported."); YYERROR; } -#line 2785 "seclang-parser.cc" +#line 2761 "seclang-parser.cc" break; case 115: -#line 1387 "seclang-parser.yy" +#line 1397 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecStreamInBodyInspection is not supported."); YYERROR; } -#line 2794 "seclang-parser.cc" +#line 2770 "seclang-parser.cc" break; case 116: -#line 1392 "seclang-parser.yy" +#line 1402 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecStreamOutBodyInspection is not supported."); YYERROR; } -#line 2803 "seclang-parser.cc" +#line 2779 "seclang-parser.cc" break; case 117: -#line 1397 "seclang-parser.yy" +#line 1407 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.load(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2816,11 +2792,11 @@ namespace yy { YYERROR; } } -#line 2820 "seclang-parser.cc" +#line 2796 "seclang-parser.cc" break; case 118: -#line 1410 "seclang-parser.yy" +#line 1420 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadRemoveRuleByTag(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2833,11 +2809,11 @@ namespace yy { YYERROR; } } -#line 2837 "seclang-parser.cc" +#line 2813 "seclang-parser.cc" break; case 119: -#line 1423 "seclang-parser.yy" +#line 1433 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadRemoveRuleByMsg(yystack_[0].value.as < std::string > (), &error) == false) { @@ -2850,11 +2826,11 @@ namespace yy { YYERROR; } } -#line 2854 "seclang-parser.cc" +#line 2830 "seclang-parser.cc" break; case 120: -#line 1436 "seclang-parser.yy" +#line 1446 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadUpdateTargetByTag(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > > > ()), &error) == false) { @@ -2867,11 +2843,11 @@ namespace yy { YYERROR; } } -#line 2871 "seclang-parser.cc" +#line 2847 "seclang-parser.cc" break; case 121: -#line 1449 "seclang-parser.yy" +#line 1459 "seclang-parser.yy" { std::string error; if (driver.m_exceptions.loadUpdateTargetByMsg(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > > > ()), &error) == false) { @@ -2884,11 +2860,11 @@ namespace yy { YYERROR; } } -#line 2888 "seclang-parser.cc" +#line 2864 "seclang-parser.cc" break; case 122: -#line 1462 "seclang-parser.yy" +#line 1472 "seclang-parser.yy" { std::string error; double ruleId; @@ -2914,11 +2890,11 @@ namespace yy { YYERROR; } } -#line 2918 "seclang-parser.cc" +#line 2894 "seclang-parser.cc" break; case 123: -#line 1488 "seclang-parser.yy" +#line 1498 "seclang-parser.yy" { std::string error; double ruleId; @@ -2945,11 +2921,11 @@ namespace yy { YYERROR; } } -#line 2949 "seclang-parser.cc" +#line 2925 "seclang-parser.cc" break; case 124: -#line 1516 "seclang-parser.yy" +#line 1526 "seclang-parser.yy" { if (driver.m_debugLog != NULL) { driver.m_debugLog->setDebugLogLevel(atoi(yystack_[0].value.as < std::string > ().c_str())); @@ -2961,11 +2937,11 @@ namespace yy { YYERROR; } } -#line 2965 "seclang-parser.cc" +#line 2941 "seclang-parser.cc" break; case 125: -#line 1528 "seclang-parser.yy" +#line 1538 "seclang-parser.yy" { if (driver.m_debugLog != NULL) { std::string error; @@ -2984,11 +2960,11 @@ namespace yy { YYERROR; } } -#line 2988 "seclang-parser.cc" +#line 2964 "seclang-parser.cc" break; case 126: -#line 1548 "seclang-parser.yy" +#line 1558 "seclang-parser.yy" { #if defined(WITH_GEOIP) or defined(WITH_MAXMIND) std::string err; @@ -3015,38 +2991,38 @@ namespace yy { YYERROR; #endif // WITH_GEOIP } -#line 3019 "seclang-parser.cc" +#line 2995 "seclang-parser.cc" break; case 127: -#line 1575 "seclang-parser.yy" +#line 1585 "seclang-parser.yy" { driver.m_argumentsLimit.m_set = true; driver.m_argumentsLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3028 "seclang-parser.cc" +#line 3004 "seclang-parser.cc" break; case 128: -#line 1581 "seclang-parser.yy" +#line 1591 "seclang-parser.yy" { driver.m_requestBodyLimit.m_set = true; driver.m_requestBodyLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3037 "seclang-parser.cc" +#line 3013 "seclang-parser.cc" break; case 129: -#line 1586 "seclang-parser.yy" +#line 1596 "seclang-parser.yy" { driver.m_requestBodyNoFilesLimit.m_set = true; driver.m_requestBodyNoFilesLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3046 "seclang-parser.cc" +#line 3022 "seclang-parser.cc" break; case 130: -#line 1591 "seclang-parser.yy" +#line 1601 "seclang-parser.yy" { std::stringstream ss; ss << "As of ModSecurity version 3.0, SecRequestBodyInMemoryLimit is no longer "; @@ -3055,68 +3031,68 @@ namespace yy { driver.error(yystack_[1].location, ss.str()); YYERROR; } -#line 3059 "seclang-parser.cc" +#line 3035 "seclang-parser.cc" break; case 131: -#line 1600 "seclang-parser.yy" +#line 1610 "seclang-parser.yy" { driver.m_responseBodyLimit.m_set = true; driver.m_responseBodyLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str()); } -#line 3068 "seclang-parser.cc" +#line 3044 "seclang-parser.cc" break; case 132: -#line 1605 "seclang-parser.yy" +#line 1615 "seclang-parser.yy" { driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction; } -#line 3076 "seclang-parser.cc" +#line 3052 "seclang-parser.cc" break; case 133: -#line 1609 "seclang-parser.yy" +#line 1619 "seclang-parser.yy" { driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction; } -#line 3084 "seclang-parser.cc" +#line 3060 "seclang-parser.cc" break; case 134: -#line 1613 "seclang-parser.yy" +#line 1623 "seclang-parser.yy" { driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction; } -#line 3092 "seclang-parser.cc" +#line 3068 "seclang-parser.cc" break; case 135: -#line 1617 "seclang-parser.yy" +#line 1627 "seclang-parser.yy" { driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction; } -#line 3100 "seclang-parser.cc" +#line 3076 "seclang-parser.cc" break; case 136: -#line 1621 "seclang-parser.yy" +#line 1631 "seclang-parser.yy" { driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction; } -#line 3108 "seclang-parser.cc" +#line 3084 "seclang-parser.cc" break; case 137: -#line 1625 "seclang-parser.yy" +#line 1635 "seclang-parser.yy" { driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction; } -#line 3116 "seclang-parser.cc" +#line 3092 "seclang-parser.cc" break; case 140: -#line 1639 "seclang-parser.yy" +#line 1649 "seclang-parser.yy" { std::istringstream buf(yystack_[0].value.as < std::string > ()); std::istream_iterator beg(buf), end; @@ -3128,37 +3104,37 @@ namespace yy { driver.m_responseBodyTypeToBeInspected.m_value.insert(*it); } } -#line 3132 "seclang-parser.cc" +#line 3108 "seclang-parser.cc" break; case 141: -#line 1651 "seclang-parser.yy" +#line 1661 "seclang-parser.yy" { driver.m_responseBodyTypeToBeInspected.m_set = true; driver.m_responseBodyTypeToBeInspected.m_clear = true; driver.m_responseBodyTypeToBeInspected.m_value.clear(); } -#line 3142 "seclang-parser.cc" +#line 3118 "seclang-parser.cc" break; case 142: -#line 1657 "seclang-parser.yy" +#line 1667 "seclang-parser.yy" { driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::FalseConfigBoolean; } -#line 3150 "seclang-parser.cc" +#line 3126 "seclang-parser.cc" break; case 143: -#line 1661 "seclang-parser.yy" +#line 1671 "seclang-parser.yy" { driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::TrueConfigBoolean; } -#line 3158 "seclang-parser.cc" +#line 3134 "seclang-parser.cc" break; case 144: -#line 1665 "seclang-parser.yy" +#line 1675 "seclang-parser.yy" { /* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended std::stringstream ss; @@ -3169,31 +3145,31 @@ namespace yy { YYERROR; */ } -#line 3173 "seclang-parser.cc" +#line 3149 "seclang-parser.cc" break; case 147: -#line 1686 "seclang-parser.yy" +#line 1696 "seclang-parser.yy" { if (atoi(yystack_[0].value.as < std::string > ().c_str()) == 1) { driver.error(yystack_[1].location, "SecCookieFormat 1 is not yet supported."); YYERROR; } } -#line 3184 "seclang-parser.cc" +#line 3160 "seclang-parser.cc" break; case 148: -#line 1693 "seclang-parser.yy" +#line 1703 "seclang-parser.yy" { driver.error(yystack_[1].location, "SecCookieV0Separator is not yet supported."); YYERROR; } -#line 3193 "seclang-parser.cc" +#line 3169 "seclang-parser.cc" break; case 150: -#line 1703 "seclang-parser.yy" +#line 1713 "seclang-parser.yy" { std::string error; std::vector param; @@ -3247,31 +3223,31 @@ namespace yy { } } -#line 3251 "seclang-parser.cc" +#line 3227 "seclang-parser.cc" break; case 151: -#line 1757 "seclang-parser.yy" +#line 1767 "seclang-parser.yy" { /* Parser error disabled to avoid breaking default CRS installations with crs-setup.conf-recommended driver.error(@0, "SecCollectionTimeout is not yet supported."); YYERROR; */ } -#line 3262 "seclang-parser.cc" +#line 3238 "seclang-parser.cc" break; case 152: -#line 1764 "seclang-parser.yy" +#line 1774 "seclang-parser.yy" { driver.m_httpblKey.m_set = true; driver.m_httpblKey.m_value = yystack_[0].value.as < std::string > (); } -#line 3271 "seclang-parser.cc" +#line 3247 "seclang-parser.cc" break; case 153: -#line 1772 "seclang-parser.yy" +#line 1782 "seclang-parser.yy" { std::unique_ptr > > originalList = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); std::unique_ptr>> newList(new std::vector>()); @@ -3305,2363 +3281,2362 @@ namespace yy { } yylhs.value.as < std::unique_ptr > > > () = std::move(newNewList); } -#line 3309 "seclang-parser.cc" +#line 3285 "seclang-parser.cc" break; case 154: -#line 1809 "seclang-parser.yy" +#line 1819 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[0].value.as < std::unique_ptr > > > ()); } -#line 3317 "seclang-parser.cc" +#line 3293 "seclang-parser.cc" break; case 155: -#line 1813 "seclang-parser.yy" +#line 1823 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[1].value.as < std::unique_ptr > > > ()); } -#line 3325 "seclang-parser.cc" +#line 3301 "seclang-parser.cc" break; case 156: -#line 1820 "seclang-parser.yy" +#line 1830 "seclang-parser.yy" { yystack_[2].value.as < std::unique_ptr > > > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[2].value.as < std::unique_ptr > > > ()); } -#line 3334 "seclang-parser.cc" +#line 3310 "seclang-parser.cc" break; case 157: -#line 1825 "seclang-parser.yy" +#line 1835 "seclang-parser.yy" { std::unique_ptr c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yystack_[3].value.as < std::unique_ptr > > > ()->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[3].value.as < std::unique_ptr > > > ()); } -#line 3344 "seclang-parser.cc" +#line 3320 "seclang-parser.cc" break; case 158: -#line 1831 "seclang-parser.yy" +#line 1841 "seclang-parser.yy" { std::unique_ptr c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr > ()))); yystack_[3].value.as < std::unique_ptr > > > ()->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(yystack_[3].value.as < std::unique_ptr > > > ()); } -#line 3354 "seclang-parser.cc" +#line 3330 "seclang-parser.cc" break; case 159: -#line 1837 "seclang-parser.yy" +#line 1847 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); b->push_back(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3364 "seclang-parser.cc" +#line 3340 "seclang-parser.cc" break; case 160: -#line 1843 "seclang-parser.yy" +#line 1853 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); std::unique_ptr c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr > ()))); b->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3375 "seclang-parser.cc" +#line 3351 "seclang-parser.cc" break; case 161: -#line 1850 "seclang-parser.yy" +#line 1860 "seclang-parser.yy" { std::unique_ptr>> b(new std::vector>()); std::unique_ptr c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr > ()))); b->push_back(std::move(c)); yylhs.value.as < std::unique_ptr > > > () = std::move(b); } -#line 3386 "seclang-parser.cc" +#line 3362 "seclang-parser.cc" break; case 162: -#line 1860 "seclang-parser.yy" +#line 1870 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3394 "seclang-parser.cc" +#line 3370 "seclang-parser.cc" break; case 163: -#line 1864 "seclang-parser.yy" +#line 1874 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3402 "seclang-parser.cc" +#line 3378 "seclang-parser.cc" break; case 164: -#line 1868 "seclang-parser.yy" +#line 1878 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Args_NoDictElement()); } -#line 3410 "seclang-parser.cc" +#line 3386 "seclang-parser.cc" break; case 165: -#line 1872 "seclang-parser.yy" +#line 1882 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3418 "seclang-parser.cc" +#line 3394 "seclang-parser.cc" break; case 166: -#line 1876 "seclang-parser.yy" +#line 1886 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3426 "seclang-parser.cc" +#line 3402 "seclang-parser.cc" break; case 167: -#line 1880 "seclang-parser.yy" +#line 1890 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPost_NoDictElement()); } -#line 3434 "seclang-parser.cc" +#line 3410 "seclang-parser.cc" break; case 168: -#line 1884 "seclang-parser.yy" +#line 1894 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3442 "seclang-parser.cc" +#line 3418 "seclang-parser.cc" break; case 169: -#line 1888 "seclang-parser.yy" +#line 1898 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3450 "seclang-parser.cc" +#line 3426 "seclang-parser.cc" break; case 170: -#line 1892 "seclang-parser.yy" +#line 1902 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGet_NoDictElement()); } -#line 3458 "seclang-parser.cc" +#line 3434 "seclang-parser.cc" break; case 171: -#line 1896 "seclang-parser.yy" +#line 1906 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3466 "seclang-parser.cc" +#line 3442 "seclang-parser.cc" break; case 172: -#line 1900 "seclang-parser.yy" +#line 1910 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3474 "seclang-parser.cc" +#line 3450 "seclang-parser.cc" break; case 173: -#line 1904 "seclang-parser.yy" +#line 1914 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesSizes_NoDictElement()); } -#line 3482 "seclang-parser.cc" +#line 3458 "seclang-parser.cc" break; case 174: -#line 1908 "seclang-parser.yy" +#line 1918 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3490 "seclang-parser.cc" +#line 3466 "seclang-parser.cc" break; case 175: -#line 1912 "seclang-parser.yy" +#line 1922 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3498 "seclang-parser.cc" +#line 3474 "seclang-parser.cc" break; case 176: -#line 1916 "seclang-parser.yy" +#line 1926 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesNames_NoDictElement()); } -#line 3506 "seclang-parser.cc" +#line 3482 "seclang-parser.cc" break; case 177: -#line 1920 "seclang-parser.yy" +#line 1930 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3514 "seclang-parser.cc" +#line 3490 "seclang-parser.cc" break; case 178: -#line 1924 "seclang-parser.yy" +#line 1934 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3522 "seclang-parser.cc" +#line 3498 "seclang-parser.cc" break; case 179: -#line 1928 "seclang-parser.yy" +#line 1938 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpContent_NoDictElement()); } -#line 3530 "seclang-parser.cc" +#line 3506 "seclang-parser.cc" break; case 180: -#line 1932 "seclang-parser.yy" +#line 1942 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3538 "seclang-parser.cc" +#line 3514 "seclang-parser.cc" break; case 181: -#line 1936 "seclang-parser.yy" +#line 1946 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3546 "seclang-parser.cc" +#line 3522 "seclang-parser.cc" break; case 182: -#line 1940 "seclang-parser.yy" +#line 1950 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartFileName_NoDictElement()); } -#line 3554 "seclang-parser.cc" +#line 3530 "seclang-parser.cc" break; case 183: -#line 1944 "seclang-parser.yy" +#line 1954 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3562 "seclang-parser.cc" +#line 3538 "seclang-parser.cc" break; case 184: -#line 1948 "seclang-parser.yy" +#line 1958 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3570 "seclang-parser.cc" +#line 3546 "seclang-parser.cc" break; case 185: -#line 1952 "seclang-parser.yy" +#line 1962 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultiPartName_NoDictElement()); } -#line 3578 "seclang-parser.cc" +#line 3554 "seclang-parser.cc" break; case 186: -#line 1956 "seclang-parser.yy" +#line 1966 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3586 "seclang-parser.cc" +#line 3562 "seclang-parser.cc" break; case 187: -#line 1960 "seclang-parser.yy" +#line 1970 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3594 "seclang-parser.cc" +#line 3570 "seclang-parser.cc" break; case 188: -#line 1964 "seclang-parser.yy" +#line 1974 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarsNames_NoDictElement()); } -#line 3602 "seclang-parser.cc" +#line 3578 "seclang-parser.cc" break; case 189: -#line 1968 "seclang-parser.yy" +#line 1978 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3610 "seclang-parser.cc" +#line 3586 "seclang-parser.cc" break; case 190: -#line 1972 "seclang-parser.yy" +#line 1982 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3618 "seclang-parser.cc" +#line 3594 "seclang-parser.cc" break; case 191: -#line 1976 "seclang-parser.yy" +#line 1986 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVars_NoDictElement()); } -#line 3626 "seclang-parser.cc" +#line 3602 "seclang-parser.cc" break; case 192: -#line 1980 "seclang-parser.yy" +#line 1990 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3634 "seclang-parser.cc" +#line 3610 "seclang-parser.cc" break; case 193: -#line 1984 "seclang-parser.yy" +#line 1994 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3642 "seclang-parser.cc" +#line 3618 "seclang-parser.cc" break; case 194: -#line 1988 "seclang-parser.yy" +#line 1998 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Files_NoDictElement()); } -#line 3650 "seclang-parser.cc" +#line 3626 "seclang-parser.cc" break; case 195: -#line 1992 "seclang-parser.yy" +#line 2002 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3658 "seclang-parser.cc" +#line 3634 "seclang-parser.cc" break; case 196: -#line 1996 "seclang-parser.yy" +#line 2006 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3666 "seclang-parser.cc" +#line 3642 "seclang-parser.cc" break; case 197: -#line 2000 "seclang-parser.yy" +#line 2010 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookies_NoDictElement()); } -#line 3674 "seclang-parser.cc" +#line 3650 "seclang-parser.cc" break; case 198: -#line 2004 "seclang-parser.yy" +#line 2014 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3682 "seclang-parser.cc" +#line 3658 "seclang-parser.cc" break; case 199: -#line 2008 "seclang-parser.yy" +#line 2018 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3690 "seclang-parser.cc" +#line 3666 "seclang-parser.cc" break; case 200: -#line 2012 "seclang-parser.yy" +#line 2022 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeaders_NoDictElement()); } -#line 3698 "seclang-parser.cc" +#line 3674 "seclang-parser.cc" break; case 201: -#line 2016 "seclang-parser.yy" +#line 2026 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3706 "seclang-parser.cc" +#line 3682 "seclang-parser.cc" break; case 202: -#line 2020 "seclang-parser.yy" +#line 2030 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3714 "seclang-parser.cc" +#line 3690 "seclang-parser.cc" break; case 203: -#line 2024 "seclang-parser.yy" +#line 2034 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeaders_NoDictElement()); } -#line 3722 "seclang-parser.cc" +#line 3698 "seclang-parser.cc" break; case 204: -#line 2028 "seclang-parser.yy" +#line 2038 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3730 "seclang-parser.cc" +#line 3706 "seclang-parser.cc" break; case 205: -#line 2032 "seclang-parser.yy" +#line 2042 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3738 "seclang-parser.cc" +#line 3714 "seclang-parser.cc" break; case 206: -#line 2036 "seclang-parser.yy" +#line 2046 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Geo_NoDictElement()); } -#line 3746 "seclang-parser.cc" +#line 3722 "seclang-parser.cc" break; case 207: -#line 2040 "seclang-parser.yy" +#line 2050 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3754 "seclang-parser.cc" +#line 3730 "seclang-parser.cc" break; case 208: -#line 2044 "seclang-parser.yy" +#line 2054 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3762 "seclang-parser.cc" +#line 3738 "seclang-parser.cc" break; case 209: -#line 2048 "seclang-parser.yy" +#line 2058 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestCookiesNames_NoDictElement()); } -#line 3770 "seclang-parser.cc" +#line 3746 "seclang-parser.cc" break; case 210: -#line 2052 "seclang-parser.yy" +#line 2062 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3778 "seclang-parser.cc" +#line 3754 "seclang-parser.cc" break; case 211: -#line 2056 "seclang-parser.yy" +#line 2066 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3786 "seclang-parser.cc" +#line 3762 "seclang-parser.cc" break; case 212: -#line 2060 "seclang-parser.yy" +#line 2070 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Rule_NoDictElement()); } -#line 3794 "seclang-parser.cc" +#line 3770 "seclang-parser.cc" break; case 213: -#line 2064 "seclang-parser.yy" +#line 2074 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV:" + yystack_[0].value.as < std::string > ())); } -#line 3802 "seclang-parser.cc" +#line 3778 "seclang-parser.cc" break; case 214: -#line 2068 "seclang-parser.yy" +#line 2078 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV:" + yystack_[0].value.as < std::string > ())); } -#line 3810 "seclang-parser.cc" +#line 3786 "seclang-parser.cc" break; case 215: -#line 2072 "seclang-parser.yy" +#line 2082 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Env("ENV")); } -#line 3818 "seclang-parser.cc" +#line 3794 "seclang-parser.cc" break; case 216: -#line 2076 "seclang-parser.yy" +#line 2086 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); } -#line 3826 "seclang-parser.cc" +#line 3802 "seclang-parser.cc" break; case 217: -#line 2080 "seclang-parser.yy" +#line 2090 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); } -#line 3834 "seclang-parser.cc" +#line 3810 "seclang-parser.cc" break; case 218: -#line 2084 "seclang-parser.yy" +#line 2094 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::XML_NoDictElement()); } -#line 3842 "seclang-parser.cc" +#line 3818 "seclang-parser.cc" break; case 219: -#line 2088 "seclang-parser.yy" +#line 2098 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3850 "seclang-parser.cc" +#line 3826 "seclang-parser.cc" break; case 220: -#line 2092 "seclang-parser.yy" +#line 2102 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3858 "seclang-parser.cc" +#line 3834 "seclang-parser.cc" break; case 221: -#line 2096 "seclang-parser.yy" +#line 2106 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesTmpNames_NoDictElement()); } -#line 3866 "seclang-parser.cc" +#line 3842 "seclang-parser.cc" break; case 222: -#line 2100 "seclang-parser.yy" +#line 2110 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3874 "seclang-parser.cc" +#line 3850 "seclang-parser.cc" break; case 223: -#line 2104 "seclang-parser.yy" +#line 2114 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3882 "seclang-parser.cc" +#line 3858 "seclang-parser.cc" break; case 224: -#line 2108 "seclang-parser.yy" +#line 2118 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3890 "seclang-parser.cc" +#line 3866 "seclang-parser.cc" break; case 225: -#line 2112 "seclang-parser.yy" +#line 2122 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Resource_NoDictElement()); } -#line 3898 "seclang-parser.cc" +#line 3874 "seclang-parser.cc" break; case 226: -#line 2116 "seclang-parser.yy" +#line 2126 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3906 "seclang-parser.cc" +#line 3882 "seclang-parser.cc" break; case 227: -#line 2120 "seclang-parser.yy" +#line 2130 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3914 "seclang-parser.cc" +#line 3890 "seclang-parser.cc" break; case 228: -#line 2124 "seclang-parser.yy" +#line 2134 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3922 "seclang-parser.cc" +#line 3898 "seclang-parser.cc" break; case 229: -#line 2128 "seclang-parser.yy" +#line 2138 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Ip_NoDictElement()); } -#line 3930 "seclang-parser.cc" +#line 3906 "seclang-parser.cc" break; case 230: -#line 2132 "seclang-parser.yy" +#line 2142 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3938 "seclang-parser.cc" +#line 3914 "seclang-parser.cc" break; case 231: -#line 2136 "seclang-parser.yy" +#line 2146 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3946 "seclang-parser.cc" +#line 3922 "seclang-parser.cc" break; case 232: -#line 2140 "seclang-parser.yy" +#line 2150 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3954 "seclang-parser.cc" +#line 3930 "seclang-parser.cc" break; case 233: -#line 2144 "seclang-parser.yy" +#line 2154 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Global_NoDictElement()); } -#line 3962 "seclang-parser.cc" +#line 3938 "seclang-parser.cc" break; case 234: -#line 2148 "seclang-parser.yy" +#line 2158 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 3970 "seclang-parser.cc" +#line 3946 "seclang-parser.cc" break; case 235: -#line 2152 "seclang-parser.yy" +#line 2162 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DictElement(yystack_[0].value.as < std::string > ())); } -#line 3978 "seclang-parser.cc" +#line 3954 "seclang-parser.cc" break; case 236: -#line 2156 "seclang-parser.yy" +#line 2166 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 3986 "seclang-parser.cc" +#line 3962 "seclang-parser.cc" break; case 237: -#line 2160 "seclang-parser.yy" +#line 2170 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::User_NoDictElement()); } -#line 3994 "seclang-parser.cc" +#line 3970 "seclang-parser.cc" break; case 238: -#line 2164 "seclang-parser.yy" +#line 2174 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 4002 "seclang-parser.cc" +#line 3978 "seclang-parser.cc" break; case 239: -#line 2168 "seclang-parser.yy" +#line 2178 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4010 "seclang-parser.cc" +#line 3986 "seclang-parser.cc" break; case 240: -#line 2172 "seclang-parser.yy" +#line 2182 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4018 "seclang-parser.cc" +#line 3994 "seclang-parser.cc" break; case 241: -#line 2176 "seclang-parser.yy" +#line 2186 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Tx_NoDictElement()); } -#line 4026 "seclang-parser.cc" +#line 4002 "seclang-parser.cc" break; case 242: -#line 2180 "seclang-parser.yy" +#line 2190 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 4034 "seclang-parser.cc" +#line 4010 "seclang-parser.cc" break; case 243: -#line 2184 "seclang-parser.yy" +#line 2194 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4042 "seclang-parser.cc" +#line 4018 "seclang-parser.cc" break; case 244: -#line 2188 "seclang-parser.yy" +#line 2198 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4050 "seclang-parser.cc" +#line 4026 "seclang-parser.cc" break; case 245: -#line 2192 "seclang-parser.yy" +#line 2202 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Session_NoDictElement()); } -#line 4058 "seclang-parser.cc" +#line 4034 "seclang-parser.cc" break; case 246: -#line 2196 "seclang-parser.yy" +#line 2206 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4066 "seclang-parser.cc" +#line 4042 "seclang-parser.cc" break; case 247: -#line 2200 "seclang-parser.yy" +#line 2210 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4074 "seclang-parser.cc" +#line 4050 "seclang-parser.cc" break; case 248: -#line 2204 "seclang-parser.yy" +#line 2214 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsNames_NoDictElement()); } -#line 4082 "seclang-parser.cc" +#line 4058 "seclang-parser.cc" break; case 249: -#line 2208 "seclang-parser.yy" +#line 2218 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4090 "seclang-parser.cc" +#line 4066 "seclang-parser.cc" break; case 250: -#line 2212 "seclang-parser.yy" +#line 2222 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4098 "seclang-parser.cc" +#line 4074 "seclang-parser.cc" break; case 251: -#line 2216 "seclang-parser.yy" +#line 2226 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsGetNames_NoDictElement()); } -#line 4106 "seclang-parser.cc" +#line 4082 "seclang-parser.cc" break; case 252: -#line 2221 "seclang-parser.yy" +#line 2231 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4114 "seclang-parser.cc" +#line 4090 "seclang-parser.cc" break; case 253: -#line 2225 "seclang-parser.yy" +#line 2235 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4122 "seclang-parser.cc" +#line 4098 "seclang-parser.cc" break; case 254: -#line 2229 "seclang-parser.yy" +#line 2239 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsPostNames_NoDictElement()); } -#line 4130 "seclang-parser.cc" +#line 4106 "seclang-parser.cc" break; case 255: -#line 2234 "seclang-parser.yy" +#line 2244 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4138 "seclang-parser.cc" +#line 4114 "seclang-parser.cc" break; case 256: -#line 2238 "seclang-parser.yy" +#line 2248 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4146 "seclang-parser.cc" +#line 4122 "seclang-parser.cc" break; case 257: -#line 2242 "seclang-parser.yy" +#line 2252 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestHeadersNames_NoDictElement()); } -#line 4154 "seclang-parser.cc" +#line 4130 "seclang-parser.cc" break; case 258: -#line 2247 "seclang-parser.yy" +#line 2257 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseContentType()); } -#line 4162 "seclang-parser.cc" +#line 4138 "seclang-parser.cc" break; case 259: -#line 2252 "seclang-parser.yy" +#line 2262 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_DictElement(yystack_[0].value.as < std::string > ())); } -#line 4170 "seclang-parser.cc" +#line 4146 "seclang-parser.cc" break; case 260: -#line 2256 "seclang-parser.yy" +#line 2266 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ())); } -#line 4178 "seclang-parser.cc" +#line 4154 "seclang-parser.cc" break; case 261: -#line 2260 "seclang-parser.yy" +#line 2270 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseHeadersNames_NoDictElement()); } -#line 4186 "seclang-parser.cc" +#line 4162 "seclang-parser.cc" break; case 262: -#line 2264 "seclang-parser.yy" +#line 2274 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ArgsCombinedSize()); } -#line 4194 "seclang-parser.cc" +#line 4170 "seclang-parser.cc" break; case 263: -#line 2268 "seclang-parser.yy" +#line 2278 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::AuthType()); } -#line 4202 "seclang-parser.cc" +#line 4178 "seclang-parser.cc" break; case 264: -#line 2272 "seclang-parser.yy" +#line 2282 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FilesCombinedSize()); } -#line 4210 "seclang-parser.cc" +#line 4186 "seclang-parser.cc" break; case 265: -#line 2276 "seclang-parser.yy" +#line 2286 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FullRequest()); } -#line 4218 "seclang-parser.cc" +#line 4194 "seclang-parser.cc" break; case 266: -#line 2280 "seclang-parser.yy" +#line 2290 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::FullRequestLength()); } -#line 4226 "seclang-parser.cc" +#line 4202 "seclang-parser.cc" break; case 267: -#line 2284 "seclang-parser.yy" +#line 2294 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::InboundDataError()); } -#line 4234 "seclang-parser.cc" +#line 4210 "seclang-parser.cc" break; case 268: -#line 2288 "seclang-parser.yy" +#line 2298 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVar()); } -#line 4242 "seclang-parser.cc" +#line 4218 "seclang-parser.cc" break; case 269: -#line 2292 "seclang-parser.yy" +#line 2302 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MatchedVarName()); } -#line 4250 "seclang-parser.cc" +#line 4226 "seclang-parser.cc" break; case 270: -#line 2296 "seclang-parser.yy" +#line 2306 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartBoundaryQuoted()); } -#line 4258 "seclang-parser.cc" +#line 4234 "seclang-parser.cc" break; case 271: -#line 2300 "seclang-parser.yy" +#line 2310 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartBoundaryWhiteSpace()); } -#line 4266 "seclang-parser.cc" +#line 4242 "seclang-parser.cc" break; case 272: -#line 2304 "seclang-parser.yy" +#line 2314 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartCrlfLFLines()); } -#line 4274 "seclang-parser.cc" +#line 4250 "seclang-parser.cc" break; case 273: -#line 2308 "seclang-parser.yy" +#line 2318 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartDateAfter()); } -#line 4282 "seclang-parser.cc" +#line 4258 "seclang-parser.cc" break; case 274: -#line 2312 "seclang-parser.yy" +#line 2322 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartDateBefore()); } -#line 4290 "seclang-parser.cc" +#line 4266 "seclang-parser.cc" break; case 275: -#line 2316 "seclang-parser.yy" +#line 2326 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartFileLimitExceeded()); } -#line 4298 "seclang-parser.cc" +#line 4274 "seclang-parser.cc" break; case 276: -#line 2320 "seclang-parser.yy" +#line 2330 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartHeaderFolding()); } -#line 4306 "seclang-parser.cc" +#line 4282 "seclang-parser.cc" break; case 277: -#line 2324 "seclang-parser.yy" +#line 2334 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidHeaderFolding()); } -#line 4314 "seclang-parser.cc" +#line 4290 "seclang-parser.cc" break; case 278: -#line 2328 "seclang-parser.yy" +#line 2338 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidPart()); } -#line 4322 "seclang-parser.cc" +#line 4298 "seclang-parser.cc" break; case 279: -#line 2332 "seclang-parser.yy" +#line 2342 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartInvalidQuoting()); } -#line 4330 "seclang-parser.cc" +#line 4306 "seclang-parser.cc" break; case 280: -#line 2336 "seclang-parser.yy" +#line 2346 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartLFLine()); } -#line 4338 "seclang-parser.cc" +#line 4314 "seclang-parser.cc" break; case 281: -#line 2340 "seclang-parser.yy" +#line 2350 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartMissingSemicolon()); } -#line 4346 "seclang-parser.cc" +#line 4322 "seclang-parser.cc" break; case 282: -#line 2344 "seclang-parser.yy" +#line 2354 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartMissingSemicolon()); } -#line 4354 "seclang-parser.cc" +#line 4330 "seclang-parser.cc" break; case 283: -#line 2348 "seclang-parser.yy" +#line 2358 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartStrictError()); } -#line 4362 "seclang-parser.cc" +#line 4338 "seclang-parser.cc" break; case 284: -#line 2352 "seclang-parser.yy" +#line 2362 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::MultipartUnmatchedBoundary()); } -#line 4370 "seclang-parser.cc" +#line 4346 "seclang-parser.cc" break; case 285: -#line 2356 "seclang-parser.yy" +#line 2366 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::OutboundDataError()); } -#line 4378 "seclang-parser.cc" +#line 4354 "seclang-parser.cc" break; case 286: -#line 2360 "seclang-parser.yy" +#line 2370 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::PathInfo()); } -#line 4386 "seclang-parser.cc" +#line 4362 "seclang-parser.cc" break; case 287: -#line 2364 "seclang-parser.yy" +#line 2374 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::QueryString()); } -#line 4394 "seclang-parser.cc" +#line 4370 "seclang-parser.cc" break; case 288: -#line 2368 "seclang-parser.yy" +#line 2378 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemoteAddr()); } -#line 4402 "seclang-parser.cc" +#line 4378 "seclang-parser.cc" break; case 289: -#line 2372 "seclang-parser.yy" +#line 2382 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemoteHost()); } -#line 4410 "seclang-parser.cc" +#line 4386 "seclang-parser.cc" break; case 290: -#line 2376 "seclang-parser.yy" +#line 2386 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RemotePort()); } -#line 4418 "seclang-parser.cc" +#line 4394 "seclang-parser.cc" break; case 291: -#line 2380 "seclang-parser.yy" +#line 2390 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyError()); } -#line 4426 "seclang-parser.cc" +#line 4402 "seclang-parser.cc" break; case 292: -#line 2384 "seclang-parser.yy" +#line 2394 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyErrorMsg()); } -#line 4434 "seclang-parser.cc" +#line 4410 "seclang-parser.cc" break; case 293: -#line 2388 "seclang-parser.yy" +#line 2398 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessor()); } -#line 4442 "seclang-parser.cc" +#line 4418 "seclang-parser.cc" break; case 294: -#line 2392 "seclang-parser.yy" +#line 2402 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessorError()); } -#line 4450 "seclang-parser.cc" +#line 4426 "seclang-parser.cc" break; case 295: -#line 2396 "seclang-parser.yy" +#line 2406 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ReqbodyProcessorErrorMsg()); } -#line 4458 "seclang-parser.cc" +#line 4434 "seclang-parser.cc" break; case 296: -#line 2400 "seclang-parser.yy" +#line 2410 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBasename()); } -#line 4466 "seclang-parser.cc" +#line 4442 "seclang-parser.cc" break; case 297: -#line 2404 "seclang-parser.yy" +#line 2414 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBody()); } -#line 4474 "seclang-parser.cc" +#line 4450 "seclang-parser.cc" break; case 298: -#line 2408 "seclang-parser.yy" +#line 2418 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestBodyLength()); } -#line 4482 "seclang-parser.cc" +#line 4458 "seclang-parser.cc" break; case 299: -#line 2412 "seclang-parser.yy" +#line 2422 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestFilename()); } -#line 4490 "seclang-parser.cc" +#line 4466 "seclang-parser.cc" break; case 300: -#line 2416 "seclang-parser.yy" +#line 2426 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestLine()); } -#line 4498 "seclang-parser.cc" +#line 4474 "seclang-parser.cc" break; case 301: -#line 2420 "seclang-parser.yy" +#line 2430 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestMethod()); } -#line 4506 "seclang-parser.cc" +#line 4482 "seclang-parser.cc" break; case 302: -#line 2424 "seclang-parser.yy" +#line 2434 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestProtocol()); } -#line 4514 "seclang-parser.cc" +#line 4490 "seclang-parser.cc" break; case 303: -#line 2428 "seclang-parser.yy" +#line 2438 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestURI()); } -#line 4522 "seclang-parser.cc" +#line 4498 "seclang-parser.cc" break; case 304: -#line 2432 "seclang-parser.yy" +#line 2442 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::RequestURIRaw()); } -#line 4530 "seclang-parser.cc" +#line 4506 "seclang-parser.cc" break; case 305: -#line 2436 "seclang-parser.yy" +#line 2446 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseBody()); } -#line 4538 "seclang-parser.cc" +#line 4514 "seclang-parser.cc" break; case 306: -#line 2440 "seclang-parser.yy" +#line 2450 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseContentLength()); } -#line 4546 "seclang-parser.cc" +#line 4522 "seclang-parser.cc" break; case 307: -#line 2444 "seclang-parser.yy" +#line 2454 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseProtocol()); } -#line 4554 "seclang-parser.cc" +#line 4530 "seclang-parser.cc" break; case 308: -#line 2448 "seclang-parser.yy" +#line 2458 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ResponseStatus()); } -#line 4562 "seclang-parser.cc" +#line 4538 "seclang-parser.cc" break; case 309: -#line 2452 "seclang-parser.yy" +#line 2462 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerAddr()); } -#line 4570 "seclang-parser.cc" +#line 4546 "seclang-parser.cc" break; case 310: -#line 2456 "seclang-parser.yy" +#line 2466 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerName()); } -#line 4578 "seclang-parser.cc" +#line 4554 "seclang-parser.cc" break; case 311: -#line 2460 "seclang-parser.yy" +#line 2470 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::ServerPort()); } -#line 4586 "seclang-parser.cc" +#line 4562 "seclang-parser.cc" break; case 312: -#line 2464 "seclang-parser.yy" +#line 2474 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::SessionID()); } -#line 4594 "seclang-parser.cc" +#line 4570 "seclang-parser.cc" break; case 313: -#line 2468 "seclang-parser.yy" +#line 2478 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UniqueID()); } -#line 4602 "seclang-parser.cc" +#line 4578 "seclang-parser.cc" break; case 314: -#line 2472 "seclang-parser.yy" +#line 2482 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UrlEncodedError()); } -#line 4610 "seclang-parser.cc" +#line 4586 "seclang-parser.cc" break; case 315: -#line 2476 "seclang-parser.yy" +#line 2486 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::UserID()); } -#line 4618 "seclang-parser.cc" +#line 4594 "seclang-parser.cc" break; case 316: -#line 2480 "seclang-parser.yy" +#line 2490 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Status()); } -#line 4626 "seclang-parser.cc" +#line 4602 "seclang-parser.cc" break; case 317: -#line 2484 "seclang-parser.yy" +#line 2494 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::Status()); } -#line 4634 "seclang-parser.cc" +#line 4610 "seclang-parser.cc" break; case 318: -#line 2488 "seclang-parser.yy" +#line 2498 "seclang-parser.yy" { VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr > (), new variables::WebAppId()); } -#line 4642 "seclang-parser.cc" +#line 4618 "seclang-parser.cc" break; case 319: -#line 2492 "seclang-parser.yy" +#line 2502 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new Duration(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4653 "seclang-parser.cc" +#line 4629 "seclang-parser.cc" break; case 320: -#line 2500 "seclang-parser.yy" +#line 2510 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new ModsecBuild(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4664 "seclang-parser.cc" +#line 4640 "seclang-parser.cc" break; case 321: -#line 2507 "seclang-parser.yy" +#line 2517 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new HighestSeverity(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4675 "seclang-parser.cc" +#line 4651 "seclang-parser.cc" break; case 322: -#line 2514 "seclang-parser.yy" +#line 2524 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new RemoteUser(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4686 "seclang-parser.cc" +#line 4662 "seclang-parser.cc" break; case 323: -#line 2521 "seclang-parser.yy" +#line 2531 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new Time(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4697 "seclang-parser.cc" +#line 4673 "seclang-parser.cc" break; case 324: -#line 2528 "seclang-parser.yy" +#line 2538 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeDay(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4708 "seclang-parser.cc" +#line 4684 "seclang-parser.cc" break; case 325: -#line 2535 "seclang-parser.yy" +#line 2545 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeEpoch(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4719 "seclang-parser.cc" +#line 4695 "seclang-parser.cc" break; case 326: -#line 2542 "seclang-parser.yy" +#line 2552 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeHour(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4730 "seclang-parser.cc" +#line 4706 "seclang-parser.cc" break; case 327: -#line 2549 "seclang-parser.yy" +#line 2559 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeMin(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4741 "seclang-parser.cc" +#line 4717 "seclang-parser.cc" break; case 328: -#line 2556 "seclang-parser.yy" +#line 2566 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeMon(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4752 "seclang-parser.cc" +#line 4728 "seclang-parser.cc" break; case 329: -#line 2563 "seclang-parser.yy" +#line 2573 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeSec(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4763 "seclang-parser.cc" +#line 4739 "seclang-parser.cc" break; case 330: -#line 2570 "seclang-parser.yy" +#line 2580 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeWDay(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4774 "seclang-parser.cc" +#line 4750 "seclang-parser.cc" break; case 331: -#line 2577 "seclang-parser.yy" +#line 2587 "seclang-parser.yy" { std::string name(yystack_[0].value.as < std::string > ()); char z = name.at(0); std::unique_ptr c(new TimeYear(name)); yylhs.value.as < std::unique_ptr > () = std::move(c); } -#line 4785 "seclang-parser.cc" +#line 4761 "seclang-parser.cc" break; case 332: -#line 2587 "seclang-parser.yy" +#line 2597 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Accuracy(yystack_[0].value.as < std::string > ())); } -#line 4793 "seclang-parser.cc" +#line 4769 "seclang-parser.cc" break; case 333: -#line 2591 "seclang-parser.yy" +#line 2601 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Allow(yystack_[0].value.as < std::string > ())); } -#line 4801 "seclang-parser.cc" +#line 4777 "seclang-parser.cc" break; case 334: -#line 2595 "seclang-parser.yy" +#line 2605 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Append", yystack_[1].location); } -#line 4809 "seclang-parser.cc" +#line 4785 "seclang-parser.cc" break; case 335: -#line 2599 "seclang-parser.yy" +#line 2609 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::AuditLog(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::AuditLog()); } -#line 4817 "seclang-parser.cc" +#line 4793 "seclang-parser.cc" break; case 336: -#line 2603 "seclang-parser.yy" +#line 2613 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Block(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Block()); } -#line 4825 "seclang-parser.cc" +#line 4801 "seclang-parser.cc" break; case 337: -#line 2607 "seclang-parser.yy" +#line 2617 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Capture(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Capture()); } -#line 4833 "seclang-parser.cc" +#line 4809 "seclang-parser.cc" break; case 338: -#line 2611 "seclang-parser.yy" +#line 2621 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Chain(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Chain()); } -#line 4841 "seclang-parser.cc" +#line 4817 "seclang-parser.cc" break; case 339: -#line 2615 "seclang-parser.yy" +#line 2625 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlAuditEngine", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4850 "seclang-parser.cc" +#line 4826 "seclang-parser.cc" break; case 340: -#line 2620 "seclang-parser.yy" +#line 2630 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlAuditEngine", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4859 "seclang-parser.cc" +#line 4835 "seclang-parser.cc" break; case 341: -#line 2625 "seclang-parser.yy" +#line 2635 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlAuditEngine", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4868 "seclang-parser.cc" +#line 4844 "seclang-parser.cc" break; case 342: -#line 2630 "seclang-parser.yy" +#line 2640 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::AuditLogParts(yystack_[0].value.as < std::string > ())); } -#line 4876 "seclang-parser.cc" +#line 4852 "seclang-parser.cc" break; case 343: -#line 2634 "seclang-parser.yy" +#line 2644 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorJSON(yystack_[0].value.as < std::string > ())); } -#line 4884 "seclang-parser.cc" +#line 4860 "seclang-parser.cc" break; case 344: -#line 2638 "seclang-parser.yy" +#line 2648 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorXML(yystack_[0].value.as < std::string > ())); } -#line 4892 "seclang-parser.cc" +#line 4868 "seclang-parser.cc" break; case 345: -#line 2642 "seclang-parser.yy" +#line 2652 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyProcessorURLENCODED(yystack_[0].value.as < std::string > ())); } -#line 4900 "seclang-parser.cc" +#line 4876 "seclang-parser.cc" break; case 346: -#line 2646 "seclang-parser.yy" +#line 2656 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlForceReequestBody", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4909 "seclang-parser.cc" +#line 4885 "seclang-parser.cc" break; case 347: -#line 2651 "seclang-parser.yy" +#line 2661 "seclang-parser.yy" { //ACTION_NOT_SUPPORTED("CtlForceReequestBody", @0); ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[1].value.as < std::string > ())); } -#line 4918 "seclang-parser.cc" +#line 4894 "seclang-parser.cc" break; case 348: -#line 2656 "seclang-parser.yy" +#line 2666 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + "true")); } -#line 4926 "seclang-parser.cc" +#line 4902 "seclang-parser.cc" break; case 349: -#line 2660 "seclang-parser.yy" +#line 2670 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + "false")); } -#line 4934 "seclang-parser.cc" +#line 4910 "seclang-parser.cc" break; case 350: -#line 2664 "seclang-parser.yy" +#line 2674 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=on")); } -#line 4942 "seclang-parser.cc" +#line 4918 "seclang-parser.cc" break; case 351: -#line 2668 "seclang-parser.yy" +#line 2678 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=off")); } -#line 4950 "seclang-parser.cc" +#line 4926 "seclang-parser.cc" break; case 352: -#line 2672 "seclang-parser.yy" +#line 2682 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleEngine("ctl:RuleEngine=detectiononly")); } -#line 4958 "seclang-parser.cc" +#line 4934 "seclang-parser.cc" break; case 353: -#line 2676 "seclang-parser.yy" +#line 2686 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveById(yystack_[0].value.as < std::string > ())); } -#line 4966 "seclang-parser.cc" +#line 4942 "seclang-parser.cc" break; case 354: -#line 2680 "seclang-parser.yy" +#line 2690 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveByTag(yystack_[0].value.as < std::string > ())); } -#line 4974 "seclang-parser.cc" +#line 4950 "seclang-parser.cc" break; case 355: -#line 2684 "seclang-parser.yy" +#line 2694 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveTargetById(yystack_[0].value.as < std::string > ())); } -#line 4982 "seclang-parser.cc" +#line 4958 "seclang-parser.cc" break; case 356: -#line 2688 "seclang-parser.yy" +#line 2698 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ctl::RuleRemoveTargetByTag(yystack_[0].value.as < std::string > ())); } -#line 4990 "seclang-parser.cc" +#line 4966 "seclang-parser.cc" break; case 357: -#line 2692 "seclang-parser.yy" +#line 2702 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Deny(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Deny()); } -#line 4998 "seclang-parser.cc" +#line 4974 "seclang-parser.cc" break; case 358: -#line 2696 "seclang-parser.yy" +#line 2706 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("DeprecateVar", yystack_[1].location); } -#line 5006 "seclang-parser.cc" +#line 4982 "seclang-parser.cc" break; case 359: -#line 2700 "seclang-parser.yy" +#line 2710 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Drop(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Drop()); } -#line 5014 "seclang-parser.cc" +#line 4990 "seclang-parser.cc" break; case 360: -#line 2704 "seclang-parser.yy" +#line 2714 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Exec(yystack_[0].value.as < std::string > ())); } -#line 5022 "seclang-parser.cc" +#line 4998 "seclang-parser.cc" break; case 361: -#line 2708 "seclang-parser.yy" +#line 2718 "seclang-parser.yy" { - //ACTION_NOT_SUPPORTED("ExpireVar", @0); - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Action(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::ExpireVar(yystack_[0].value.as < std::string > ())); } -#line 5031 "seclang-parser.cc" +#line 5006 "seclang-parser.cc" break; case 362: -#line 2713 "seclang-parser.yy" +#line 2722 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::RuleId(yystack_[0].value.as < std::string > ())); } -#line 5039 "seclang-parser.cc" +#line 5014 "seclang-parser.cc" break; case 363: -#line 2717 "seclang-parser.yy" +#line 2726 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::InitCol(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5047 "seclang-parser.cc" +#line 5022 "seclang-parser.cc" break; case 364: -#line 2721 "seclang-parser.yy" +#line 2730 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::LogData(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5055 "seclang-parser.cc" +#line 5030 "seclang-parser.cc" break; case 365: -#line 2725 "seclang-parser.yy" +#line 2734 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Log(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Log()); } -#line 5063 "seclang-parser.cc" +#line 5038 "seclang-parser.cc" break; case 366: -#line 2729 "seclang-parser.yy" +#line 2738 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Maturity(yystack_[0].value.as < std::string > ())); } -#line 5071 "seclang-parser.cc" +#line 5046 "seclang-parser.cc" break; case 367: -#line 2733 "seclang-parser.yy" +#line 2742 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Msg(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5079 "seclang-parser.cc" +#line 5054 "seclang-parser.cc" break; case 368: -#line 2737 "seclang-parser.yy" +#line 2746 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::MultiMatch(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::MultiMatch()); } -#line 5087 "seclang-parser.cc" +#line 5062 "seclang-parser.cc" break; case 369: -#line 2741 "seclang-parser.yy" +#line 2750 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoAuditLog(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoAuditLog()); } -#line 5095 "seclang-parser.cc" +#line 5070 "seclang-parser.cc" break; case 370: -#line 2745 "seclang-parser.yy" +#line 2754 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoLog(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::NoLog()); } -#line 5103 "seclang-parser.cc" +#line 5078 "seclang-parser.cc" break; case 371: -#line 2749 "seclang-parser.yy" +#line 2758 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Pass(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Pass()); } -#line 5111 "seclang-parser.cc" +#line 5086 "seclang-parser.cc" break; case 372: -#line 2753 "seclang-parser.yy" +#line 2762 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Pause", yystack_[1].location); } -#line 5119 "seclang-parser.cc" +#line 5094 "seclang-parser.cc" break; case 373: -#line 2757 "seclang-parser.yy" +#line 2766 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Phase(yystack_[0].value.as < std::string > ())); } -#line 5127 "seclang-parser.cc" +#line 5102 "seclang-parser.cc" break; case 374: -#line 2761 "seclang-parser.yy" +#line 2770 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Prepend", yystack_[1].location); } -#line 5135 "seclang-parser.cc" +#line 5110 "seclang-parser.cc" break; case 375: -#line 2765 "seclang-parser.yy" +#line 2774 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("Proxy", yystack_[1].location); } -#line 5143 "seclang-parser.cc" +#line 5118 "seclang-parser.cc" break; case 376: -#line 2769 "seclang-parser.yy" +#line 2778 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::disruptive::Redirect(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5151 "seclang-parser.cc" +#line 5126 "seclang-parser.cc" break; case 377: -#line 2773 "seclang-parser.yy" +#line 2782 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Rev(yystack_[0].value.as < std::string > ())); } -#line 5159 "seclang-parser.cc" +#line 5134 "seclang-parser.cc" break; case 378: -#line 2777 "seclang-parser.yy" +#line 2786 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseArg", yystack_[1].location); } -#line 5167 "seclang-parser.cc" +#line 5142 "seclang-parser.cc" break; case 379: -#line 2781 "seclang-parser.yy" +#line 2790 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseMatched", yystack_[1].location); } -#line 5175 "seclang-parser.cc" +#line 5150 "seclang-parser.cc" break; case 380: -#line 2785 "seclang-parser.yy" +#line 2794 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseMatchedBytes", yystack_[1].location); } -#line 5183 "seclang-parser.cc" +#line 5158 "seclang-parser.cc" break; case 381: -#line 2789 "seclang-parser.yy" +#line 2798 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseRequestHeader", yystack_[1].location); } -#line 5191 "seclang-parser.cc" +#line 5166 "seclang-parser.cc" break; case 382: -#line 2793 "seclang-parser.yy" +#line 2802 "seclang-parser.yy" { ACTION_NOT_SUPPORTED("SanitiseResponseHeader", yystack_[1].location); } -#line 5199 "seclang-parser.cc" +#line 5174 "seclang-parser.cc" break; case 383: -#line 2797 "seclang-parser.yy" +#line 2806 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetENV(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5207 "seclang-parser.cc" +#line 5182 "seclang-parser.cc" break; case 384: -#line 2801 "seclang-parser.yy" +#line 2810 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetRSC(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5215 "seclang-parser.cc" +#line 5190 "seclang-parser.cc" break; case 385: -#line 2805 "seclang-parser.yy" +#line 2814 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetSID(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5223 "seclang-parser.cc" +#line 5198 "seclang-parser.cc" break; case 386: -#line 2809 "seclang-parser.yy" +#line 2818 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetUID(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5231 "seclang-parser.cc" +#line 5206 "seclang-parser.cc" break; case 387: -#line 2813 "seclang-parser.yy" +#line 2822 "seclang-parser.yy" { yylhs.value.as < std::unique_ptr > () = std::move(yystack_[0].value.as < std::unique_ptr > ()); } -#line 5239 "seclang-parser.cc" +#line 5214 "seclang-parser.cc" break; case 388: -#line 2817 "seclang-parser.yy" +#line 2826 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Severity(yystack_[0].value.as < std::string > ())); } -#line 5247 "seclang-parser.cc" +#line 5222 "seclang-parser.cc" break; case 389: -#line 2821 "seclang-parser.yy" +#line 2830 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Skip(yystack_[0].value.as < std::string > ())); } -#line 5255 "seclang-parser.cc" +#line 5230 "seclang-parser.cc" break; case 390: -#line 2825 "seclang-parser.yy" +#line 2834 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SkipAfter(yystack_[0].value.as < std::string > ())); } -#line 5263 "seclang-parser.cc" +#line 5238 "seclang-parser.cc" break; case 391: -#line 2829 "seclang-parser.yy" +#line 2838 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::data::Status(yystack_[0].value.as < std::string > ())); } -#line 5271 "seclang-parser.cc" +#line 5246 "seclang-parser.cc" break; case 392: -#line 2833 "seclang-parser.yy" +#line 2842 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Tag(std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5279 "seclang-parser.cc" +#line 5254 "seclang-parser.cc" break; case 393: -#line 2837 "seclang-parser.yy" +#line 2846 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::Ver(yystack_[0].value.as < std::string > ())); } -#line 5287 "seclang-parser.cc" +#line 5262 "seclang-parser.cc" break; case 394: -#line 2841 "seclang-parser.yy" +#line 2850 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::XmlNS(yystack_[0].value.as < std::string > ())); } -#line 5295 "seclang-parser.cc" +#line 5270 "seclang-parser.cc" break; case 395: -#line 2845 "seclang-parser.yy" +#line 2854 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityZero7bit(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityZero7bit()); } -#line 5303 "seclang-parser.cc" +#line 5278 "seclang-parser.cc" break; case 396: -#line 2849 "seclang-parser.yy" +#line 2858 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityOdd7bit(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityOdd7bit()); } -#line 5311 "seclang-parser.cc" +#line 5286 "seclang-parser.cc" break; case 397: -#line 2853 "seclang-parser.yy" +#line 2862 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityEven7bit(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ParityEven7bit()); } -#line 5319 "seclang-parser.cc" +#line 5294 "seclang-parser.cc" break; case 398: -#line 2857 "seclang-parser.yy" +#line 2866 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::SqlHexDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::SqlHexDecode()); } -#line 5327 "seclang-parser.cc" +#line 5302 "seclang-parser.cc" break; case 399: -#line 2861 "seclang-parser.yy" +#line 2870 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Encode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Encode()); } -#line 5335 "seclang-parser.cc" +#line 5310 "seclang-parser.cc" break; case 400: -#line 2865 "seclang-parser.yy" +#line 2874 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Decode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64Decode()); } -#line 5343 "seclang-parser.cc" +#line 5318 "seclang-parser.cc" break; case 401: -#line 2869 "seclang-parser.yy" +#line 2878 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64DecodeExt(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Base64DecodeExt()); } -#line 5351 "seclang-parser.cc" +#line 5326 "seclang-parser.cc" break; case 402: -#line 2873 "seclang-parser.yy" +#line 2882 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CmdLine(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CmdLine()); } -#line 5359 "seclang-parser.cc" +#line 5334 "seclang-parser.cc" break; case 403: -#line 2877 "seclang-parser.yy" +#line 2886 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Sha1(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Sha1()); } -#line 5367 "seclang-parser.cc" +#line 5342 "seclang-parser.cc" break; case 404: -#line 2881 "seclang-parser.yy" +#line 2890 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Md5(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Md5()); } -#line 5375 "seclang-parser.cc" +#line 5350 "seclang-parser.cc" break; case 405: -#line 2885 "seclang-parser.yy" +#line 2894 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::EscapeSeqDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::EscapeSeqDecode()); } -#line 5383 "seclang-parser.cc" +#line 5358 "seclang-parser.cc" break; case 406: -#line 2889 "seclang-parser.yy" +#line 2898 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexEncode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexEncode()); } -#line 5391 "seclang-parser.cc" +#line 5366 "seclang-parser.cc" break; case 407: -#line 2893 "seclang-parser.yy" +#line 2902 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HexDecode()); } -#line 5399 "seclang-parser.cc" +#line 5374 "seclang-parser.cc" break; case 408: -#line 2897 "seclang-parser.yy" +#line 2906 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::LowerCase(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::LowerCase()); } -#line 5407 "seclang-parser.cc" +#line 5382 "seclang-parser.cc" break; case 409: -#line 2901 "seclang-parser.yy" +#line 2910 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UpperCase(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UpperCase()); } -#line 5415 "seclang-parser.cc" +#line 5390 "seclang-parser.cc" break; case 410: -#line 2905 "seclang-parser.yy" +#line 2914 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecodeUni(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecodeUni()); } -#line 5423 "seclang-parser.cc" +#line 5398 "seclang-parser.cc" break; case 411: -#line 2909 "seclang-parser.yy" +#line 2918 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlDecode()); } -#line 5431 "seclang-parser.cc" +#line 5406 "seclang-parser.cc" break; case 412: -#line 2913 "seclang-parser.yy" +#line 2922 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlEncode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::UrlEncode()); } -#line 5439 "seclang-parser.cc" +#line 5414 "seclang-parser.cc" break; case 413: -#line 2917 "seclang-parser.yy" +#line 2926 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::None(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::None()); } -#line 5447 "seclang-parser.cc" +#line 5422 "seclang-parser.cc" break; case 414: -#line 2921 "seclang-parser.yy" +#line 2930 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CompressWhitespace(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CompressWhitespace()); } -#line 5455 "seclang-parser.cc" +#line 5430 "seclang-parser.cc" break; case 415: -#line 2925 "seclang-parser.yy" +#line 2934 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveWhitespace(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveWhitespace()); } -#line 5463 "seclang-parser.cc" +#line 5438 "seclang-parser.cc" break; case 416: -#line 2929 "seclang-parser.yy" +#line 2938 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceNulls(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceNulls()); } -#line 5471 "seclang-parser.cc" +#line 5446 "seclang-parser.cc" break; case 417: -#line 2933 "seclang-parser.yy" +#line 2942 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveNulls(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveNulls()); } -#line 5479 "seclang-parser.cc" +#line 5454 "seclang-parser.cc" break; case 418: -#line 2937 "seclang-parser.yy" +#line 2946 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HtmlEntityDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::HtmlEntityDecode()); } -#line 5487 "seclang-parser.cc" +#line 5462 "seclang-parser.cc" break; case 419: -#line 2941 "seclang-parser.yy" +#line 2950 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::JsDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::JsDecode()); } -#line 5495 "seclang-parser.cc" +#line 5470 "seclang-parser.cc" break; case 420: -#line 2945 "seclang-parser.yy" +#line 2954 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CssDecode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::CssDecode()); } -#line 5503 "seclang-parser.cc" +#line 5478 "seclang-parser.cc" break; case 421: -#line 2949 "seclang-parser.yy" +#line 2958 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Trim(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Trim()); } -#line 5511 "seclang-parser.cc" +#line 5486 "seclang-parser.cc" break; case 422: -#line 2953 "seclang-parser.yy" +#line 2962 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimLeft(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimLeft()); } -#line 5519 "seclang-parser.cc" +#line 5494 "seclang-parser.cc" break; case 423: -#line 2957 "seclang-parser.yy" +#line 2966 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimRight(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::TrimRight()); } -#line 5527 "seclang-parser.cc" +#line 5502 "seclang-parser.cc" break; case 424: -#line 2961 "seclang-parser.yy" +#line 2970 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePathWin(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePathWin()); } -#line 5535 "seclang-parser.cc" +#line 5510 "seclang-parser.cc" break; case 425: -#line 2965 "seclang-parser.yy" +#line 2974 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePath(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::NormalisePath()); } -#line 5543 "seclang-parser.cc" +#line 5518 "seclang-parser.cc" break; case 426: -#line 2969 "seclang-parser.yy" +#line 2978 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Length(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Length()); } -#line 5551 "seclang-parser.cc" +#line 5526 "seclang-parser.cc" break; case 427: -#line 2973 "seclang-parser.yy" +#line 2982 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Utf8ToUnicode(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::Utf8ToUnicode()); } -#line 5559 "seclang-parser.cc" +#line 5534 "seclang-parser.cc" break; case 428: -#line 2977 "seclang-parser.yy" +#line 2986 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveCommentsChar(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveCommentsChar()); } -#line 5567 "seclang-parser.cc" +#line 5542 "seclang-parser.cc" break; case 429: -#line 2981 "seclang-parser.yy" +#line 2990 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveComments(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::RemoveComments()); } -#line 5575 "seclang-parser.cc" +#line 5550 "seclang-parser.cc" break; case 430: -#line 2985 "seclang-parser.yy" +#line 2994 "seclang-parser.yy" { - ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceComments(yystack_[0].value.as < std::string > ())); + ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::transformations::ReplaceComments()); } -#line 5583 "seclang-parser.cc" +#line 5558 "seclang-parser.cc" break; case 431: -#line 2992 "seclang-parser.yy" +#line 3001 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::unsetOperation, std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5591 "seclang-parser.cc" +#line 5566 "seclang-parser.cc" break; case 432: -#line 2996 "seclang-parser.yy" +#line 3005 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::setToOneOperation, std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5599 "seclang-parser.cc" +#line 5574 "seclang-parser.cc" break; case 433: -#line 3000 "seclang-parser.yy" +#line 3009 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::setOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5607 "seclang-parser.cc" +#line 5582 "seclang-parser.cc" break; case 434: -#line 3004 "seclang-parser.yy" +#line 3013 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5615 "seclang-parser.cc" +#line 5590 "seclang-parser.cc" break; case 435: -#line 3008 "seclang-parser.yy" +#line 3017 "seclang-parser.yy" { ACTION_CONTAINER(yylhs.value.as < std::unique_ptr > (), new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr > ()), std::move(yystack_[0].value.as < std::unique_ptr > ()))); } -#line 5623 "seclang-parser.cc" +#line 5598 "seclang-parser.cc" break; case 436: -#line 3015 "seclang-parser.yy" +#line 3024 "seclang-parser.yy" { yystack_[1].value.as < std::unique_ptr > ()->appendText(yystack_[0].value.as < std::string > ()); yylhs.value.as < std::unique_ptr > () = std::move(yystack_[1].value.as < std::unique_ptr > ()); } -#line 5632 "seclang-parser.cc" +#line 5607 "seclang-parser.cc" break; case 437: -#line 3020 "seclang-parser.yy" +#line 3029 "seclang-parser.yy" { yystack_[1].value.as < std::unique_ptr > ()->appendVar(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > () = std::move(yystack_[1].value.as < std::unique_ptr > ()); } -#line 5641 "seclang-parser.cc" +#line 5616 "seclang-parser.cc" break; case 438: -#line 3025 "seclang-parser.yy" +#line 3034 "seclang-parser.yy" { std::unique_ptr r(new RunTimeString()); r->appendText(yystack_[0].value.as < std::string > ()); yylhs.value.as < std::unique_ptr > () = std::move(r); } -#line 5651 "seclang-parser.cc" +#line 5626 "seclang-parser.cc" break; case 439: -#line 3031 "seclang-parser.yy" +#line 3040 "seclang-parser.yy" { std::unique_ptr r(new RunTimeString()); r->appendVar(std::move(yystack_[0].value.as < std::unique_ptr > ())); yylhs.value.as < std::unique_ptr > () = std::move(r); } -#line 5661 "seclang-parser.cc" +#line 5636 "seclang-parser.cc" break; -#line 5665 "seclang-parser.cc" +#line 5640 "seclang-parser.cc" default: break; @@ -5678,7 +5653,6 @@ namespace yy { YY_SYMBOL_PRINT ("-> $$ =", yylhs); yypop_ (yylen); yylen = 0; - YY_STACK_PRINT (); // Shift the result of the reduction. yypush_ (YY_NULLPTR, YY_MOVE (yylhs)); @@ -5694,7 +5668,9 @@ namespace yy { if (!yyerrstatus_) { ++yynerrs_; - error (yyla.location, yysyntax_error_ (yystack_[0].state, yyla)); + context yyctx (*this, yyla); + std::string msg = yysyntax_error_ (yyctx); + error (yyla.location, YY_MOVE (msg)); } @@ -5705,7 +5681,7 @@ namespace yy { error, discard it. */ // Return failure if at end of input. - if (yyla.type_get () == yyeof_) + if (yyla.kind () == symbol_kind::S_YYEOF) YYABORT; else if (!yyla.empty ()) { @@ -5731,6 +5707,7 @@ namespace yy { this YYERROR. */ yypop_ (yylen); yylen = 0; + YY_STACK_PRINT (); goto yyerrlab1; @@ -5739,31 +5716,33 @@ namespace yy { `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus_ = 3; // Each real token shifted decrements this. - { - stack_symbol_type error_token; - for (;;) - { - yyn = yypact_[+yystack_[0].state]; - if (!yy_pact_value_is_default_ (yyn)) - { - yyn += yy_error_token_; - if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_) - { - yyn = yytable_[yyn]; - if (0 < yyn) - break; - } - } + // Pop stack until we find a state that shifts the error token. + for (;;) + { + yyn = yypact_[+yystack_[0].state]; + if (!yy_pact_value_is_default_ (yyn)) + { + yyn += symbol_kind::S_YYerror; + if (0 <= yyn && yyn <= yylast_ + && yycheck_[yyn] == symbol_kind::S_YYerror) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } - // Pop the current state because it cannot handle the error token. - if (yystack_.size () == 1) - YYABORT; + // Pop the current state because it cannot handle the error token. + if (yystack_.size () == 1) + YYABORT; - yyerror_range[1].location = yystack_[0].location; - yy_destroy_ ("Error: popping", yystack_[0]); - yypop_ (); - YY_STACK_PRINT (); - } + yyerror_range[1].location = yystack_[0].location; + yy_destroy_ ("Error: popping", yystack_[0]); + yypop_ (); + YY_STACK_PRINT (); + } + { + stack_symbol_type error_token; yyerror_range[2].location = yyla.location; YYLLOC_DEFAULT (error_token.location, yyerror_range, 2); @@ -5801,6 +5780,7 @@ namespace yy { /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ yypop_ (yylen); + YY_STACK_PRINT (); while (1 < yystack_.size ()) { yy_destroy_ ("Cleanup: popping", yystack_[0]); @@ -5834,18 +5814,100 @@ namespace yy { error (yyexc.location, yyexc.what ()); } - // Generate an error message. + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ std::string - seclang_parser::yysyntax_error_ (state_type yystate, const symbol_type& yyla) const + seclang_parser::yytnamerr_ (const char *yystr) { - // Number of reported tokens (one for the "unexpected", one per - // "expected"). - std::ptrdiff_t yycount = 0; - // Its maximum. - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - // Arguments of yyformat. - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + if (*yystr == '"') + { + std::string yyr; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + else + goto append; + + append: + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + return yystr; + } + + std::string + seclang_parser::symbol_name (symbol_kind_type yysymbol) + { + return yytnamerr_ (yytname_[yysymbol]); + } + + + + // seclang_parser::context. + seclang_parser::context::context (const seclang_parser& yyparser, const symbol_type& yyla) + : yyparser_ (yyparser) + , yyla_ (yyla) + {} + + int + seclang_parser::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const + { + // Actual number of expected tokens + int yycount = 0; + + int yyn = yypact_[+yyparser_.yystack_[0].state]; + if (!yy_pact_value_is_default_ (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + // Stay within bounds of both yycheck and yytname. + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + for (int yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::S_YYerror + && !yy_table_value_is_error_ (yytable_[yyx + yyn])) + { + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx); + } + } + + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = symbol_kind::S_YYEMPTY; + return yycount; + } + + + + int + seclang_parser::yy_syntax_error_arguments_ (const context& yyctx, + symbol_kind_type yyarg[], int yyargn) const + { /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action @@ -5870,35 +5932,26 @@ namespace yy { one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ - if (!yyla.empty ()) - { - symbol_number_type yytoken = yyla.type_get (); - yyarg[yycount++] = yytname_[yytoken]; - int yyn = yypact_[+yystate]; - if (!yy_pact_value_is_default_ (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - // Stay within bounds of both yycheck and yytname. - int yychecklim = yylast_ - yyn + 1; - int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; - for (int yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck_[yyx + yyn] == yyx && yyx != yy_error_token_ - && !yy_table_value_is_error_ (yytable_[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - break; - } - else - yyarg[yycount++] = yytname_[yyx]; - } - } + if (!yyctx.lookahead ().empty ()) + { + if (yyarg) + yyarg[0] = yyctx.token (); + int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1); + return yyn + 1; } + return 0; + } + + // Generate an error message. + std::string + seclang_parser::yysyntax_error_ (const context& yyctx) const + { + // Its maximum. + enum { YYARGS_MAX = 5 }; + // Arguments of yyformat. + symbol_kind_type yyarg[YYARGS_MAX]; + int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX); char const* yyformat = YY_NULLPTR; switch (yycount) @@ -5923,7 +5976,7 @@ namespace yy { for (char const* yyp = yyformat; *yyp; ++yyp) if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount) { - yyres += yytnamerr_ (yyarg[yyi++]); + yyres += symbol_name (yyarg[yyi++]); ++yyp; } else @@ -6887,13 +6940,13 @@ namespace yy { }; - +#if YYDEBUG || 1 // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - // First, the terminals, then, starting at \a yyntokens_, nonterminals. + // First, the terminals, then, starting at \a YYNTOKENS, nonterminals. const char* const seclang_parser::yytname_[] = { - "\"end of file\"", "error", "$undefined", "\",\"", + "\"end of file\"", "error", "\"invalid token\"", "\",\"", "\"CONFIG_CONTENT_INJECTION\"", "\"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\"", "PIPE", "NEW_LINE", "VAR_COUNT", "VAR_EXCLUSION", "VARIABLE_ARGS", "VARIABLE_ARGS_POST", "VARIABLE_ARGS_GET", "VARIABLE_FILES_SIZES", @@ -7066,60 +7119,61 @@ namespace yy { "variables_may_be_quoted", "var", "act", "setvar_action", "run_time_string", YY_NULLPTR }; +#endif + #if YYDEBUG const short seclang_parser::yyrline_[] = { - 0, 708, 708, 712, 713, 716, 721, 727, 733, 737, - 741, 747, 753, 759, 765, 770, 775, 781, 788, 792, - 796, 802, 806, 810, 815, 820, 825, 830, 834, 841, - 845, 852, 858, 868, 877, 887, 896, 909, 913, 917, - 921, 925, 929, 933, 937, 941, 945, 950, 954, 958, - 962, 966, 970, 975, 980, 984, 988, 992, 996, 1000, - 1004, 1008, 1012, 1016, 1020, 1024, 1028, 1032, 1036, 1040, - 1044, 1048, 1052, 1066, 1067, 1097, 1116, 1135, 1163, 1220, - 1227, 1231, 1235, 1239, 1243, 1247, 1251, 1255, 1264, 1268, - 1273, 1276, 1281, 1286, 1291, 1296, 1299, 1304, 1307, 1312, - 1317, 1320, 1325, 1330, 1335, 1340, 1345, 1350, 1355, 1358, - 1363, 1368, 1373, 1378, 1381, 1386, 1391, 1396, 1409, 1422, - 1435, 1448, 1461, 1487, 1515, 1527, 1547, 1574, 1580, 1585, - 1590, 1599, 1604, 1608, 1612, 1616, 1620, 1624, 1628, 1633, - 1638, 1650, 1656, 1660, 1664, 1675, 1684, 1685, 1692, 1697, - 1702, 1756, 1763, 1771, 1808, 1812, 1819, 1824, 1830, 1836, - 1842, 1849, 1859, 1863, 1867, 1871, 1875, 1879, 1883, 1887, - 1891, 1895, 1899, 1903, 1907, 1911, 1915, 1919, 1923, 1927, - 1931, 1935, 1939, 1943, 1947, 1951, 1955, 1959, 1963, 1967, - 1971, 1975, 1979, 1983, 1987, 1991, 1995, 1999, 2003, 2007, - 2011, 2015, 2019, 2023, 2027, 2031, 2035, 2039, 2043, 2047, - 2051, 2055, 2059, 2063, 2067, 2071, 2075, 2079, 2083, 2087, - 2091, 2095, 2099, 2103, 2107, 2111, 2115, 2119, 2123, 2127, - 2131, 2135, 2139, 2143, 2147, 2151, 2155, 2159, 2163, 2167, - 2171, 2175, 2179, 2183, 2187, 2191, 2195, 2199, 2203, 2207, - 2211, 2215, 2220, 2224, 2228, 2233, 2237, 2241, 2246, 2251, - 2255, 2259, 2263, 2267, 2271, 2275, 2279, 2283, 2287, 2291, - 2295, 2299, 2303, 2307, 2311, 2315, 2319, 2323, 2327, 2331, - 2335, 2339, 2343, 2347, 2351, 2355, 2359, 2363, 2367, 2371, - 2375, 2379, 2383, 2387, 2391, 2395, 2399, 2403, 2407, 2411, - 2415, 2419, 2423, 2427, 2431, 2435, 2439, 2443, 2447, 2451, - 2455, 2459, 2463, 2467, 2471, 2475, 2479, 2483, 2487, 2491, - 2499, 2506, 2513, 2520, 2527, 2534, 2541, 2548, 2555, 2562, - 2569, 2576, 2586, 2590, 2594, 2598, 2602, 2606, 2610, 2614, - 2619, 2624, 2629, 2633, 2637, 2641, 2645, 2650, 2655, 2659, - 2663, 2667, 2671, 2675, 2679, 2683, 2687, 2691, 2695, 2699, - 2703, 2707, 2712, 2716, 2720, 2724, 2728, 2732, 2736, 2740, - 2744, 2748, 2752, 2756, 2760, 2764, 2768, 2772, 2776, 2780, - 2784, 2788, 2792, 2796, 2800, 2804, 2808, 2812, 2816, 2820, - 2824, 2828, 2832, 2836, 2840, 2844, 2848, 2852, 2856, 2860, - 2864, 2868, 2872, 2876, 2880, 2884, 2888, 2892, 2896, 2900, - 2904, 2908, 2912, 2916, 2920, 2924, 2928, 2932, 2936, 2940, - 2944, 2948, 2952, 2956, 2960, 2964, 2968, 2972, 2976, 2980, - 2984, 2991, 2995, 2999, 3003, 3007, 3014, 3019, 3024, 3030 + 0, 711, 711, 715, 716, 719, 724, 730, 736, 740, + 744, 750, 756, 762, 768, 773, 778, 784, 791, 795, + 799, 805, 809, 813, 818, 823, 828, 833, 837, 844, + 848, 855, 861, 871, 880, 890, 899, 912, 916, 920, + 924, 928, 932, 936, 940, 944, 948, 953, 957, 961, + 965, 969, 973, 978, 983, 987, 991, 995, 999, 1003, + 1007, 1011, 1015, 1019, 1023, 1027, 1031, 1035, 1039, 1043, + 1047, 1051, 1055, 1069, 1070, 1102, 1121, 1142, 1172, 1230, + 1237, 1241, 1245, 1249, 1253, 1257, 1261, 1265, 1274, 1278, + 1283, 1286, 1291, 1296, 1301, 1306, 1309, 1314, 1317, 1322, + 1327, 1330, 1335, 1340, 1345, 1350, 1355, 1360, 1365, 1368, + 1373, 1378, 1383, 1388, 1391, 1396, 1401, 1406, 1419, 1432, + 1445, 1458, 1471, 1497, 1525, 1537, 1557, 1584, 1590, 1595, + 1600, 1609, 1614, 1618, 1622, 1626, 1630, 1634, 1638, 1643, + 1648, 1660, 1666, 1670, 1674, 1685, 1694, 1695, 1702, 1707, + 1712, 1766, 1773, 1781, 1818, 1822, 1829, 1834, 1840, 1846, + 1852, 1859, 1869, 1873, 1877, 1881, 1885, 1889, 1893, 1897, + 1901, 1905, 1909, 1913, 1917, 1921, 1925, 1929, 1933, 1937, + 1941, 1945, 1949, 1953, 1957, 1961, 1965, 1969, 1973, 1977, + 1981, 1985, 1989, 1993, 1997, 2001, 2005, 2009, 2013, 2017, + 2021, 2025, 2029, 2033, 2037, 2041, 2045, 2049, 2053, 2057, + 2061, 2065, 2069, 2073, 2077, 2081, 2085, 2089, 2093, 2097, + 2101, 2105, 2109, 2113, 2117, 2121, 2125, 2129, 2133, 2137, + 2141, 2145, 2149, 2153, 2157, 2161, 2165, 2169, 2173, 2177, + 2181, 2185, 2189, 2193, 2197, 2201, 2205, 2209, 2213, 2217, + 2221, 2225, 2230, 2234, 2238, 2243, 2247, 2251, 2256, 2261, + 2265, 2269, 2273, 2277, 2281, 2285, 2289, 2293, 2297, 2301, + 2305, 2309, 2313, 2317, 2321, 2325, 2329, 2333, 2337, 2341, + 2345, 2349, 2353, 2357, 2361, 2365, 2369, 2373, 2377, 2381, + 2385, 2389, 2393, 2397, 2401, 2405, 2409, 2413, 2417, 2421, + 2425, 2429, 2433, 2437, 2441, 2445, 2449, 2453, 2457, 2461, + 2465, 2469, 2473, 2477, 2481, 2485, 2489, 2493, 2497, 2501, + 2509, 2516, 2523, 2530, 2537, 2544, 2551, 2558, 2565, 2572, + 2579, 2586, 2596, 2600, 2604, 2608, 2612, 2616, 2620, 2624, + 2629, 2634, 2639, 2643, 2647, 2651, 2655, 2660, 2665, 2669, + 2673, 2677, 2681, 2685, 2689, 2693, 2697, 2701, 2705, 2709, + 2713, 2717, 2721, 2725, 2729, 2733, 2737, 2741, 2745, 2749, + 2753, 2757, 2761, 2765, 2769, 2773, 2777, 2781, 2785, 2789, + 2793, 2797, 2801, 2805, 2809, 2813, 2817, 2821, 2825, 2829, + 2833, 2837, 2841, 2845, 2849, 2853, 2857, 2861, 2865, 2869, + 2873, 2877, 2881, 2885, 2889, 2893, 2897, 2901, 2905, 2909, + 2913, 2917, 2921, 2925, 2929, 2933, 2937, 2941, 2945, 2949, + 2953, 2957, 2961, 2965, 2969, 2973, 2977, 2981, 2985, 2989, + 2993, 3000, 3004, 3008, 3012, 3016, 3023, 3028, 3033, 3039 }; - // Print the state stack on the debug stream. void - seclang_parser::yystack_print_ () + seclang_parser::yy_stack_print_ () const { *yycdebug_ << "Stack now"; for (stack_type::const_iterator @@ -7130,9 +7184,8 @@ namespace yy { *yycdebug_ << '\n'; } - // Report on the debug stream that the rule \a yyrule is going to be reduced. void - seclang_parser::yy_reduce_print_ (int yyrule) + seclang_parser::yy_reduce_print_ (int yyrule) const { int yylno = yyrline_[yyrule]; int yynrhs = yyr2_[yyrule]; @@ -7148,9 +7201,9 @@ namespace yy { } // yy -#line 7152 "seclang-parser.cc" +#line 7205 "seclang-parser.cc" -#line 3037 "seclang-parser.yy" +#line 3046 "seclang-parser.yy" void yy::seclang_parser::error (const location_type& l, const std::string& m) { diff --git a/src/parser/seclang-parser.hh b/src/parser/seclang-parser.hh index 1a42b1edd2..2e3664c213 100644 --- a/src/parser/seclang-parser.hh +++ b/src/parser/seclang-parser.hh @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.5.3. +// A Bison parser, made by GNU Bison 3.6.2. // Skeleton interface for Bison LALR(1) parsers in C++ @@ -38,8 +38,9 @@ // C++ LALR(1) parser skeleton written by Akim Demaille. -// Undocumented macros, especially those whose name start with YY_, -// are private implementation details. Do not rely on them. +// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, +// especially those whose name start with YY_ or yy_. They are +// private implementation details that can be changed or removed. #ifndef YY_YY_SECLANG_PARSER_HH_INCLUDED # define YY_YY_SECLANG_PARSER_HH_INCLUDED @@ -55,7 +56,9 @@ class Driver; } } -#include "modsecurity/rule_unconditional.h" +#include "src/rule_unconditional.h" +#include "src/rule_with_operator.h" +#include "src/rule_with_actions.h" #include "src/rule_script.h" #include "src/actions/accuracy.h" @@ -81,6 +84,7 @@ class Driver; #include "src/actions/disruptive/redirect.h" #include "src/actions/init_col.h" #include "src/actions/exec.h" +#include "src/actions/expire_var.h" #include "src/actions/log_data.h" #include "src/actions/log.h" #include "src/actions/maturity.h" @@ -348,7 +352,7 @@ using namespace modsecurity::operators; a = std::move(c); -#line 352 "seclang-parser.hh" +#line 356 "seclang-parser.hh" # include # include // std::abort @@ -482,7 +486,7 @@ using namespace modsecurity::operators; #endif namespace yy { -#line 486 "seclang-parser.hh" +#line 490 "seclang-parser.hh" @@ -518,6 +522,13 @@ namespace yy { new (yyas_ ()) T (YY_MOVE (t)); } +#if 201103L <= YY_CPLUSPLUS + /// Non copyable. + semantic_type (const self_type&) = delete; + /// Non copyable. + self_type& operator= (const self_type&) = delete; +#endif + /// Destruction, allowed only if empty. ~semantic_type () YY_NOEXCEPT { @@ -661,9 +672,12 @@ namespace yy { } private: - /// Prohibit blind copies. - self_type& operator= (const self_type&); +#if YY_CPLUSPLUS < 201103L + /// Non copyable. semantic_type (const self_type&); + /// Non copyable. + self_type& operator= (const self_type&); +#endif /// Accessor to raw memory as \a T. template @@ -949,370 +963,743 @@ namespace yy { location_type location; }; - /// Tokens. + /// Token kinds. struct token { - enum yytokentype - { - TOK_END = 0, - TOK_COMMA = 258, - TOK_CONFIG_CONTENT_INJECTION = 259, - TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR = 260, - TOK_PIPE = 261, - TOK_NEW_LINE = 262, - TOK_VAR_COUNT = 263, - TOK_VAR_EXCLUSION = 264, - TOK_VARIABLE_ARGS = 265, - TOK_VARIABLE_ARGS_POST = 266, - TOK_VARIABLE_ARGS_GET = 267, - TOK_VARIABLE_FILES_SIZES = 268, - TOK_VARIABLE_FILES_NAMES = 269, - TOK_VARIABLE_FILES_TMP_CONTENT = 270, - TOK_VARIABLE_MULTIPART_FILENAME = 271, - TOK_VARIABLE_MULTIPART_NAME = 272, - TOK_VARIABLE_MATCHED_VARS_NAMES = 273, - TOK_VARIABLE_MATCHED_VARS = 274, - TOK_VARIABLE_FILES = 275, - TOK_VARIABLE_REQUEST_COOKIES = 276, - TOK_VARIABLE_REQUEST_HEADERS = 277, - TOK_VARIABLE_RESPONSE_HEADERS = 278, - TOK_VARIABLE_GEO = 279, - TOK_VARIABLE_REQUEST_COOKIES_NAMES = 280, - TOK_VARIABLE_ARGS_COMBINED_SIZE = 281, - TOK_VARIABLE_ARGS_GET_NAMES = 282, - TOK_VARIABLE_RULE = 283, - TOK_VARIABLE_ARGS_NAMES = 284, - TOK_VARIABLE_ARGS_POST_NAMES = 285, - TOK_VARIABLE_AUTH_TYPE = 286, - TOK_VARIABLE_FILES_COMBINED_SIZE = 287, - TOK_VARIABLE_FILES_TMP_NAMES = 288, - TOK_VARIABLE_FULL_REQUEST = 289, - TOK_VARIABLE_FULL_REQUEST_LENGTH = 290, - TOK_VARIABLE_INBOUND_DATA_ERROR = 291, - TOK_VARIABLE_MATCHED_VAR = 292, - TOK_VARIABLE_MATCHED_VAR_NAME = 293, - TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 294, - TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 295, - TOK_VARIABLE_MULTIPART_CRLF_LF_LINES = 296, - TOK_VARIABLE_MULTIPART_DATA_AFTER = 297, - TOK_VARIABLE_MULTIPART_DATA_BEFORE = 298, - TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 299, - TOK_VARIABLE_MULTIPART_HEADER_FOLDING = 300, - TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 301, - TOK_VARIABLE_MULTIPART_INVALID_PART = 302, - TOK_VARIABLE_MULTIPART_INVALID_QUOTING = 303, - TOK_VARIABLE_MULTIPART_LF_LINE = 304, - TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON = 305, - TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING = 306, - TOK_VARIABLE_MULTIPART_STRICT_ERROR = 307, - TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 308, - TOK_VARIABLE_OUTBOUND_DATA_ERROR = 309, - TOK_VARIABLE_PATH_INFO = 310, - TOK_VARIABLE_QUERY_STRING = 311, - TOK_VARIABLE_REMOTE_ADDR = 312, - TOK_VARIABLE_REMOTE_HOST = 313, - TOK_VARIABLE_REMOTE_PORT = 314, - TOK_VARIABLE_REQBODY_ERROR_MSG = 315, - TOK_VARIABLE_REQBODY_ERROR = 316, - TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 317, - TOK_VARIABLE_REQBODY_PROCESSOR_ERROR = 318, - TOK_VARIABLE_REQBODY_PROCESSOR = 319, - TOK_VARIABLE_REQUEST_BASENAME = 320, - TOK_VARIABLE_REQUEST_BODY_LENGTH = 321, - TOK_VARIABLE_REQUEST_BODY = 322, - TOK_VARIABLE_REQUEST_FILE_NAME = 323, - TOK_VARIABLE_REQUEST_HEADERS_NAMES = 324, - TOK_VARIABLE_REQUEST_LINE = 325, - TOK_VARIABLE_REQUEST_METHOD = 326, - TOK_VARIABLE_REQUEST_PROTOCOL = 327, - TOK_VARIABLE_REQUEST_URI_RAW = 328, - TOK_VARIABLE_REQUEST_URI = 329, - TOK_VARIABLE_RESOURCE = 330, - TOK_VARIABLE_RESPONSE_BODY = 331, - TOK_VARIABLE_RESPONSE_CONTENT_LENGTH = 332, - TOK_VARIABLE_RESPONSE_CONTENT_TYPE = 333, - TOK_VARIABLE_RESPONSE_HEADERS_NAMES = 334, - TOK_VARIABLE_RESPONSE_PROTOCOL = 335, - TOK_VARIABLE_RESPONSE_STATUS = 336, - TOK_VARIABLE_SERVER_ADDR = 337, - TOK_VARIABLE_SERVER_NAME = 338, - TOK_VARIABLE_SERVER_PORT = 339, - TOK_VARIABLE_SESSION_ID = 340, - TOK_VARIABLE_UNIQUE_ID = 341, - TOK_VARIABLE_URL_ENCODED_ERROR = 342, - TOK_VARIABLE_USER_ID = 343, - TOK_VARIABLE_WEB_APP_ID = 344, - TOK_VARIABLE_STATUS = 345, - TOK_VARIABLE_STATUS_LINE = 346, - TOK_VARIABLE_IP = 347, - TOK_VARIABLE_GLOBAL = 348, - TOK_VARIABLE_TX = 349, - TOK_VARIABLE_SESSION = 350, - TOK_VARIABLE_USER = 351, - TOK_RUN_TIME_VAR_ENV = 352, - TOK_RUN_TIME_VAR_XML = 353, - TOK_ACTION_SETVAR = 354, - TOK_SETVAR_OPERATION_EQUALS = 355, - TOK_SETVAR_OPERATION_EQUALS_PLUS = 356, - TOK_SETVAR_OPERATION_EQUALS_MINUS = 357, - TOK_NOT = 358, - TOK_OPERATOR_BEGINS_WITH = 359, - TOK_OPERATOR_CONTAINS = 360, - TOK_OPERATOR_CONTAINS_WORD = 361, - TOK_OPERATOR_DETECT_SQLI = 362, - TOK_OPERATOR_DETECT_XSS = 363, - TOK_OPERATOR_ENDS_WITH = 364, - TOK_OPERATOR_EQ = 365, - TOK_OPERATOR_FUZZY_HASH = 366, - TOK_OPERATOR_GEOLOOKUP = 367, - TOK_OPERATOR_GE = 368, - TOK_OPERATOR_GSB_LOOKUP = 369, - TOK_OPERATOR_GT = 370, - TOK_OPERATOR_INSPECT_FILE = 371, - TOK_OPERATOR_IP_MATCH_FROM_FILE = 372, - TOK_OPERATOR_IP_MATCH = 373, - TOK_OPERATOR_LE = 374, - TOK_OPERATOR_LT = 375, - TOK_OPERATOR_PM_FROM_FILE = 376, - TOK_OPERATOR_PM = 377, - TOK_OPERATOR_RBL = 378, - TOK_OPERATOR_RSUB = 379, - TOK_OPERATOR_RX_CONTENT_ONLY = 380, - TOK_OPERATOR_RX = 381, - TOK_OPERATOR_STR_EQ = 382, - TOK_OPERATOR_STR_MATCH = 383, - TOK_OPERATOR_UNCONDITIONAL_MATCH = 384, - TOK_OPERATOR_VALIDATE_BYTE_RANGE = 385, - TOK_OPERATOR_VALIDATE_DTD = 386, - TOK_OPERATOR_VALIDATE_HASH = 387, - TOK_OPERATOR_VALIDATE_SCHEMA = 388, - TOK_OPERATOR_VALIDATE_URL_ENCODING = 389, - TOK_OPERATOR_VALIDATE_UTF8_ENCODING = 390, - TOK_OPERATOR_VERIFY_CC = 391, - TOK_OPERATOR_VERIFY_CPF = 392, - TOK_OPERATOR_VERIFY_SSN = 393, - TOK_OPERATOR_VERIFY_SVNR = 394, - TOK_OPERATOR_WITHIN = 395, - TOK_CONFIG_DIR_AUDIT_LOG_FMT = 396, - TOK_JSON = 397, - TOK_NATIVE = 398, - TOK_ACTION_CTL_RULE_ENGINE = 399, - TOK_ACTION_ACCURACY = 400, - TOK_ACTION_ALLOW = 401, - TOK_ACTION_APPEND = 402, - TOK_ACTION_AUDIT_LOG = 403, - TOK_ACTION_BLOCK = 404, - TOK_ACTION_CAPTURE = 405, - TOK_ACTION_CHAIN = 406, - TOK_ACTION_CTL_AUDIT_ENGINE = 407, - TOK_ACTION_CTL_AUDIT_LOG_PARTS = 408, - TOK_ACTION_CTL_BDY_JSON = 409, - TOK_ACTION_CTL_BDY_XML = 410, - TOK_ACTION_CTL_BDY_URLENCODED = 411, - TOK_ACTION_CTL_FORCE_REQ_BODY_VAR = 412, - TOK_ACTION_CTL_REQUEST_BODY_ACCESS = 413, - TOK_ACTION_CTL_RULE_REMOVE_BY_ID = 414, - TOK_ACTION_CTL_RULE_REMOVE_BY_TAG = 415, - TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 416, - TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 417, - TOK_ACTION_DENY = 418, - TOK_ACTION_DEPRECATE_VAR = 419, - TOK_ACTION_DROP = 420, - TOK_ACTION_EXEC = 421, - TOK_ACTION_EXPIRE_VAR = 422, - TOK_ACTION_ID = 423, - TOK_ACTION_INITCOL = 424, - TOK_ACTION_LOG = 425, - TOK_ACTION_LOG_DATA = 426, - TOK_ACTION_MATURITY = 427, - TOK_ACTION_MSG = 428, - TOK_ACTION_MULTI_MATCH = 429, - TOK_ACTION_NO_AUDIT_LOG = 430, - TOK_ACTION_NO_LOG = 431, - TOK_ACTION_PASS = 432, - TOK_ACTION_PAUSE = 433, - TOK_ACTION_PHASE = 434, - TOK_ACTION_PREPEND = 435, - TOK_ACTION_PROXY = 436, - TOK_ACTION_REDIRECT = 437, - TOK_ACTION_REV = 438, - TOK_ACTION_SANITISE_ARG = 439, - TOK_ACTION_SANITISE_MATCHED = 440, - TOK_ACTION_SANITISE_MATCHED_BYTES = 441, - TOK_ACTION_SANITISE_REQUEST_HEADER = 442, - TOK_ACTION_SANITISE_RESPONSE_HEADER = 443, - TOK_ACTION_SETENV = 444, - TOK_ACTION_SETRSC = 445, - TOK_ACTION_SETSID = 446, - TOK_ACTION_SETUID = 447, - TOK_ACTION_SEVERITY = 448, - TOK_ACTION_SKIP = 449, - TOK_ACTION_SKIP_AFTER = 450, - TOK_ACTION_STATUS = 451, - TOK_ACTION_TAG = 452, - TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE = 453, - TOK_ACTION_TRANSFORMATION_BASE_64_DECODE = 454, - TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 455, - TOK_ACTION_TRANSFORMATION_CMD_LINE = 456, - TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 457, - TOK_ACTION_TRANSFORMATION_CSS_DECODE = 458, - TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 459, - TOK_ACTION_TRANSFORMATION_HEX_ENCODE = 460, - TOK_ACTION_TRANSFORMATION_HEX_DECODE = 461, - TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 462, - TOK_ACTION_TRANSFORMATION_JS_DECODE = 463, - TOK_ACTION_TRANSFORMATION_LENGTH = 464, - TOK_ACTION_TRANSFORMATION_LOWERCASE = 465, - TOK_ACTION_TRANSFORMATION_MD5 = 466, - TOK_ACTION_TRANSFORMATION_NONE = 467, - TOK_ACTION_TRANSFORMATION_NORMALISE_PATH = 468, - TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 469, - TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 470, - TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 471, - TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 472, - TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 473, - TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 474, - TOK_ACTION_TRANSFORMATION_REMOVE_NULLS = 475, - TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 476, - TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 477, - TOK_ACTION_TRANSFORMATION_REPLACE_NULLS = 478, - TOK_ACTION_TRANSFORMATION_SHA1 = 479, - TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 480, - TOK_ACTION_TRANSFORMATION_TRIM = 481, - TOK_ACTION_TRANSFORMATION_TRIM_LEFT = 482, - TOK_ACTION_TRANSFORMATION_TRIM_RIGHT = 483, - TOK_ACTION_TRANSFORMATION_UPPERCASE = 484, - TOK_ACTION_TRANSFORMATION_URL_ENCODE = 485, - TOK_ACTION_TRANSFORMATION_URL_DECODE = 486, - TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI = 487, - TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 488, - TOK_ACTION_VER = 489, - TOK_ACTION_XMLNS = 490, - TOK_CONFIG_COMPONENT_SIG = 491, - TOK_CONFIG_CONN_ENGINE = 492, - TOK_CONFIG_SEC_ARGUMENT_SEPARATOR = 493, - TOK_CONFIG_SEC_WEB_APP_ID = 494, - TOK_CONFIG_SEC_SERVER_SIG = 495, - TOK_CONFIG_DIR_AUDIT_DIR = 496, - TOK_CONFIG_DIR_AUDIT_DIR_MOD = 497, - TOK_CONFIG_DIR_AUDIT_ENG = 498, - TOK_CONFIG_DIR_AUDIT_FLE_MOD = 499, - TOK_CONFIG_DIR_AUDIT_LOG = 500, - TOK_CONFIG_DIR_AUDIT_LOG2 = 501, - TOK_CONFIG_DIR_AUDIT_LOG_P = 502, - TOK_CONFIG_DIR_AUDIT_STS = 503, - TOK_CONFIG_DIR_AUDIT_TPE = 504, - TOK_CONFIG_DIR_DEBUG_LOG = 505, - TOK_CONFIG_DIR_DEBUG_LVL = 506, - TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS = 507, - TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 508, - TOK_CONFIG_SEC_HASH_ENGINE = 509, - TOK_CONFIG_SEC_HASH_KEY = 510, - TOK_CONFIG_SEC_HASH_PARAM = 511, - TOK_CONFIG_SEC_HASH_METHOD_RX = 512, - TOK_CONFIG_SEC_HASH_METHOD_PM = 513, - TOK_CONFIG_SEC_CHROOT_DIR = 514, - TOK_CONFIG_DIR_GEO_DB = 515, - TOK_CONFIG_DIR_GSB_DB = 516, - TOK_CONFIG_SEC_GUARDIAN_LOG = 517, - TOK_CONFIG_DIR_PCRE_MATCH_LIMIT = 518, - TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 519, - TOK_CONFIG_SEC_CONN_R_STATE_LIMIT = 520, - TOK_CONFIG_SEC_CONN_W_STATE_LIMIT = 521, - TOK_CONFIG_SEC_SENSOR_ID = 522, - TOK_CONFIG_DIR_ARGS_LIMIT = 523, - TOK_CONFIG_DIR_REQ_BODY = 524, - TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 525, - TOK_CONFIG_DIR_REQ_BODY_LIMIT = 526, - TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 527, - TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 528, - TOK_CONFIG_DIR_RES_BODY = 529, - TOK_CONFIG_DIR_RES_BODY_LIMIT = 530, - TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 531, - TOK_CONFIG_SEC_RULE_INHERITANCE = 532, - TOK_CONFIG_SEC_RULE_PERF_TIME = 533, - TOK_CONFIG_DIR_RULE_ENG = 534, - TOK_CONFIG_DIR_SEC_ACTION = 535, - TOK_CONFIG_DIR_SEC_DEFAULT_ACTION = 536, - TOK_CONFIG_DIR_SEC_MARKER = 537, - TOK_CONFIG_DIR_UNICODE_MAP_FILE = 538, - TOK_CONFIG_DIR_UNICODE_CODE_PAGE = 539, - TOK_CONFIG_SEC_COLLECTION_TIMEOUT = 540, - TOK_CONFIG_SEC_HTTP_BLKEY = 541, - TOK_CONFIG_SEC_INTERCEPT_ON_ERROR = 542, - TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 543, - TOK_CONFIG_SEC_RULE_REMOVE_BY_ID = 544, - TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG = 545, - TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG = 546, - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 547, - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 548, - TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 549, - TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 550, - TOK_CONFIG_UPDLOAD_KEEP_FILES = 551, - TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES = 552, - TOK_CONFIG_UPLOAD_DIR = 553, - TOK_CONFIG_UPLOAD_FILE_LIMIT = 554, - TOK_CONFIG_UPLOAD_FILE_MODE = 555, - TOK_CONFIG_VALUE_ABORT = 556, - TOK_CONFIG_VALUE_DETC = 557, - TOK_CONFIG_VALUE_HTTPS = 558, - TOK_CONFIG_VALUE_OFF = 559, - TOK_CONFIG_VALUE_ON = 560, - TOK_CONFIG_VALUE_PARALLEL = 561, - TOK_CONFIG_VALUE_PROCESS_PARTIAL = 562, - TOK_CONFIG_VALUE_REJECT = 563, - TOK_CONFIG_VALUE_RELEVANT_ONLY = 564, - TOK_CONFIG_VALUE_SERIAL = 565, - TOK_CONFIG_VALUE_WARN = 566, - TOK_CONFIG_XML_EXTERNAL_ENTITY = 567, - TOK_CONGIG_DIR_RESPONSE_BODY_MP = 568, - TOK_CONGIG_DIR_SEC_ARG_SEP = 569, - TOK_CONGIG_DIR_SEC_COOKIE_FORMAT = 570, - TOK_CONFIG_SEC_COOKIEV0_SEPARATOR = 571, - TOK_CONGIG_DIR_SEC_DATA_DIR = 572, - TOK_CONGIG_DIR_SEC_STATUS_ENGINE = 573, - TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 574, - TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 575, - TOK_CONGIG_DIR_SEC_TMP_DIR = 576, - TOK_DIRECTIVE = 577, - TOK_DIRECTIVE_SECRULESCRIPT = 578, - TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION = 579, - TOK_QUOTATION_MARK = 580, - TOK_RUN_TIME_VAR_BLD = 581, - TOK_RUN_TIME_VAR_DUR = 582, - TOK_RUN_TIME_VAR_HSV = 583, - TOK_RUN_TIME_VAR_REMOTE_USER = 584, - TOK_RUN_TIME_VAR_TIME = 585, - TOK_RUN_TIME_VAR_TIME_DAY = 586, - TOK_RUN_TIME_VAR_TIME_EPOCH = 587, - TOK_RUN_TIME_VAR_TIME_HOUR = 588, - TOK_RUN_TIME_VAR_TIME_MIN = 589, - TOK_RUN_TIME_VAR_TIME_MON = 590, - TOK_RUN_TIME_VAR_TIME_SEC = 591, - TOK_RUN_TIME_VAR_TIME_WDAY = 592, - TOK_RUN_TIME_VAR_TIME_YEAR = 593, - TOK_VARIABLE = 594, - TOK_DICT_ELEMENT = 595, - TOK_DICT_ELEMENT_REGEXP = 596 + enum token_kind_type + { + TOK_YYEMPTY = -2, + TOK_END = 0, // "end of file" + TOK_YYerror = 256, // error + TOK_YYUNDEF = 257, // "invalid token" + TOK_COMMA = 258, // "," + TOK_CONFIG_CONTENT_INJECTION = 259, // "CONFIG_CONTENT_INJECTION" + TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR = 260, // "CONGIG_DIR_RESPONSE_BODY_MP_CLEAR" + TOK_PIPE = 261, // PIPE + TOK_NEW_LINE = 262, // NEW_LINE + TOK_VAR_COUNT = 263, // VAR_COUNT + TOK_VAR_EXCLUSION = 264, // VAR_EXCLUSION + TOK_VARIABLE_ARGS = 265, // VARIABLE_ARGS + TOK_VARIABLE_ARGS_POST = 266, // VARIABLE_ARGS_POST + TOK_VARIABLE_ARGS_GET = 267, // VARIABLE_ARGS_GET + TOK_VARIABLE_FILES_SIZES = 268, // VARIABLE_FILES_SIZES + TOK_VARIABLE_FILES_NAMES = 269, // VARIABLE_FILES_NAMES + TOK_VARIABLE_FILES_TMP_CONTENT = 270, // VARIABLE_FILES_TMP_CONTENT + TOK_VARIABLE_MULTIPART_FILENAME = 271, // VARIABLE_MULTIPART_FILENAME + TOK_VARIABLE_MULTIPART_NAME = 272, // VARIABLE_MULTIPART_NAME + TOK_VARIABLE_MATCHED_VARS_NAMES = 273, // VARIABLE_MATCHED_VARS_NAMES + TOK_VARIABLE_MATCHED_VARS = 274, // VARIABLE_MATCHED_VARS + TOK_VARIABLE_FILES = 275, // VARIABLE_FILES + TOK_VARIABLE_REQUEST_COOKIES = 276, // VARIABLE_REQUEST_COOKIES + TOK_VARIABLE_REQUEST_HEADERS = 277, // VARIABLE_REQUEST_HEADERS + TOK_VARIABLE_RESPONSE_HEADERS = 278, // VARIABLE_RESPONSE_HEADERS + TOK_VARIABLE_GEO = 279, // VARIABLE_GEO + TOK_VARIABLE_REQUEST_COOKIES_NAMES = 280, // VARIABLE_REQUEST_COOKIES_NAMES + TOK_VARIABLE_ARGS_COMBINED_SIZE = 281, // VARIABLE_ARGS_COMBINED_SIZE + TOK_VARIABLE_ARGS_GET_NAMES = 282, // VARIABLE_ARGS_GET_NAMES + TOK_VARIABLE_RULE = 283, // VARIABLE_RULE + TOK_VARIABLE_ARGS_NAMES = 284, // "Variable ARGS_NAMES" + TOK_VARIABLE_ARGS_POST_NAMES = 285, // VARIABLE_ARGS_POST_NAMES + TOK_VARIABLE_AUTH_TYPE = 286, // "AUTH_TYPE" + TOK_VARIABLE_FILES_COMBINED_SIZE = 287, // "FILES_COMBINED_SIZE" + TOK_VARIABLE_FILES_TMP_NAMES = 288, // "FILES_TMPNAMES" + TOK_VARIABLE_FULL_REQUEST = 289, // "FULL_REQUEST" + TOK_VARIABLE_FULL_REQUEST_LENGTH = 290, // "FULL_REQUEST_LENGTH" + TOK_VARIABLE_INBOUND_DATA_ERROR = 291, // "INBOUND_DATA_ERROR" + TOK_VARIABLE_MATCHED_VAR = 292, // "MATCHED_VAR" + TOK_VARIABLE_MATCHED_VAR_NAME = 293, // "MATCHED_VAR_NAME" + TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 294, // VARIABLE_MULTIPART_BOUNDARY_QUOTED + TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 295, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE + TOK_VARIABLE_MULTIPART_CRLF_LF_LINES = 296, // "MULTIPART_CRLF_LF_LINES" + TOK_VARIABLE_MULTIPART_DATA_AFTER = 297, // "MULTIPART_DATA_AFTER" + TOK_VARIABLE_MULTIPART_DATA_BEFORE = 298, // VARIABLE_MULTIPART_DATA_BEFORE + TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 299, // "MULTIPART_FILE_LIMIT_EXCEEDED" + TOK_VARIABLE_MULTIPART_HEADER_FOLDING = 300, // "MULTIPART_HEADER_FOLDING" + TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 301, // "MULTIPART_INVALID_HEADER_FOLDING" + TOK_VARIABLE_MULTIPART_INVALID_PART = 302, // VARIABLE_MULTIPART_INVALID_PART + TOK_VARIABLE_MULTIPART_INVALID_QUOTING = 303, // "MULTIPART_INVALID_QUOTING" + TOK_VARIABLE_MULTIPART_LF_LINE = 304, // VARIABLE_MULTIPART_LF_LINE + TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON = 305, // VARIABLE_MULTIPART_MISSING_SEMICOLON + TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING = 306, // VARIABLE_MULTIPART_SEMICOLON_MISSING + TOK_VARIABLE_MULTIPART_STRICT_ERROR = 307, // "MULTIPART_STRICT_ERROR" + TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 308, // "MULTIPART_UNMATCHED_BOUNDARY" + TOK_VARIABLE_OUTBOUND_DATA_ERROR = 309, // "OUTBOUND_DATA_ERROR" + TOK_VARIABLE_PATH_INFO = 310, // "PATH_INFO" + TOK_VARIABLE_QUERY_STRING = 311, // "QUERY_STRING" + TOK_VARIABLE_REMOTE_ADDR = 312, // "REMOTE_ADDR" + TOK_VARIABLE_REMOTE_HOST = 313, // "REMOTE_HOST" + TOK_VARIABLE_REMOTE_PORT = 314, // "REMOTE_PORT" + TOK_VARIABLE_REQBODY_ERROR_MSG = 315, // "REQBODY_ERROR_MSG" + TOK_VARIABLE_REQBODY_ERROR = 316, // "REQBODY_ERROR" + TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 317, // "REQBODY_PROCESSOR_ERROR_MSG" + TOK_VARIABLE_REQBODY_PROCESSOR_ERROR = 318, // "REQBODY_PROCESSOR_ERROR" + TOK_VARIABLE_REQBODY_PROCESSOR = 319, // "REQBODY_PROCESSOR" + TOK_VARIABLE_REQUEST_BASENAME = 320, // "REQUEST_BASENAME" + TOK_VARIABLE_REQUEST_BODY_LENGTH = 321, // "REQUEST_BODY_LENGTH" + TOK_VARIABLE_REQUEST_BODY = 322, // "REQUEST_BODY" + TOK_VARIABLE_REQUEST_FILE_NAME = 323, // "REQUEST_FILENAME" + TOK_VARIABLE_REQUEST_HEADERS_NAMES = 324, // VARIABLE_REQUEST_HEADERS_NAMES + TOK_VARIABLE_REQUEST_LINE = 325, // "REQUEST_LINE" + TOK_VARIABLE_REQUEST_METHOD = 326, // "REQUEST_METHOD" + TOK_VARIABLE_REQUEST_PROTOCOL = 327, // "REQUEST_PROTOCOL" + TOK_VARIABLE_REQUEST_URI_RAW = 328, // "REQUEST_URI_RAW" + TOK_VARIABLE_REQUEST_URI = 329, // "REQUEST_URI" + TOK_VARIABLE_RESOURCE = 330, // "RESOURCE" + TOK_VARIABLE_RESPONSE_BODY = 331, // "RESPONSE_BODY" + TOK_VARIABLE_RESPONSE_CONTENT_LENGTH = 332, // "RESPONSE_CONTENT_LENGTH" + TOK_VARIABLE_RESPONSE_CONTENT_TYPE = 333, // VARIABLE_RESPONSE_CONTENT_TYPE + TOK_VARIABLE_RESPONSE_HEADERS_NAMES = 334, // VARIABLE_RESPONSE_HEADERS_NAMES + TOK_VARIABLE_RESPONSE_PROTOCOL = 335, // "RESPONSE_PROTOCOL" + TOK_VARIABLE_RESPONSE_STATUS = 336, // "RESPONSE_STATUS" + TOK_VARIABLE_SERVER_ADDR = 337, // "SERVER_ADDR" + TOK_VARIABLE_SERVER_NAME = 338, // "SERVER_NAME" + TOK_VARIABLE_SERVER_PORT = 339, // "SERVER_PORT" + TOK_VARIABLE_SESSION_ID = 340, // "SESSIONID" + TOK_VARIABLE_UNIQUE_ID = 341, // "UNIQUE_ID" + TOK_VARIABLE_URL_ENCODED_ERROR = 342, // "URLENCODED_ERROR" + TOK_VARIABLE_USER_ID = 343, // "USERID" + TOK_VARIABLE_WEB_APP_ID = 344, // "WEBAPPID" + TOK_VARIABLE_STATUS = 345, // "VARIABLE_STATUS" + TOK_VARIABLE_STATUS_LINE = 346, // "VARIABLE_STATUS_LINE" + TOK_VARIABLE_IP = 347, // "VARIABLE_IP" + TOK_VARIABLE_GLOBAL = 348, // "VARIABLE_GLOBAL" + TOK_VARIABLE_TX = 349, // "VARIABLE_TX" + TOK_VARIABLE_SESSION = 350, // "VARIABLE_SESSION" + TOK_VARIABLE_USER = 351, // "VARIABLE_USER" + TOK_RUN_TIME_VAR_ENV = 352, // "RUN_TIME_VAR_ENV" + TOK_RUN_TIME_VAR_XML = 353, // "RUN_TIME_VAR_XML" + TOK_ACTION_SETVAR = 354, // "SetVar" + TOK_SETVAR_OPERATION_EQUALS = 355, // SETVAR_OPERATION_EQUALS + TOK_SETVAR_OPERATION_EQUALS_PLUS = 356, // SETVAR_OPERATION_EQUALS_PLUS + TOK_SETVAR_OPERATION_EQUALS_MINUS = 357, // SETVAR_OPERATION_EQUALS_MINUS + TOK_NOT = 358, // "NOT" + TOK_OPERATOR_BEGINS_WITH = 359, // "OPERATOR_BEGINS_WITH" + TOK_OPERATOR_CONTAINS = 360, // "OPERATOR_CONTAINS" + TOK_OPERATOR_CONTAINS_WORD = 361, // "OPERATOR_CONTAINS_WORD" + TOK_OPERATOR_DETECT_SQLI = 362, // "OPERATOR_DETECT_SQLI" + TOK_OPERATOR_DETECT_XSS = 363, // "OPERATOR_DETECT_XSS" + TOK_OPERATOR_ENDS_WITH = 364, // "OPERATOR_ENDS_WITH" + TOK_OPERATOR_EQ = 365, // "OPERATOR_EQ" + TOK_OPERATOR_FUZZY_HASH = 366, // "OPERATOR_FUZZY_HASH" + TOK_OPERATOR_GEOLOOKUP = 367, // "OPERATOR_GEOLOOKUP" + TOK_OPERATOR_GE = 368, // "OPERATOR_GE" + TOK_OPERATOR_GSB_LOOKUP = 369, // "OPERATOR_GSB_LOOKUP" + TOK_OPERATOR_GT = 370, // "OPERATOR_GT" + TOK_OPERATOR_INSPECT_FILE = 371, // "OPERATOR_INSPECT_FILE" + TOK_OPERATOR_IP_MATCH_FROM_FILE = 372, // "OPERATOR_IP_MATCH_FROM_FILE" + TOK_OPERATOR_IP_MATCH = 373, // "OPERATOR_IP_MATCH" + TOK_OPERATOR_LE = 374, // "OPERATOR_LE" + TOK_OPERATOR_LT = 375, // "OPERATOR_LT" + TOK_OPERATOR_PM_FROM_FILE = 376, // "OPERATOR_PM_FROM_FILE" + TOK_OPERATOR_PM = 377, // "OPERATOR_PM" + TOK_OPERATOR_RBL = 378, // "OPERATOR_RBL" + TOK_OPERATOR_RSUB = 379, // "OPERATOR_RSUB" + TOK_OPERATOR_RX_CONTENT_ONLY = 380, // "Operator RX (content only)" + TOK_OPERATOR_RX = 381, // "OPERATOR_RX" + TOK_OPERATOR_STR_EQ = 382, // "OPERATOR_STR_EQ" + TOK_OPERATOR_STR_MATCH = 383, // "OPERATOR_STR_MATCH" + TOK_OPERATOR_UNCONDITIONAL_MATCH = 384, // "OPERATOR_UNCONDITIONAL_MATCH" + TOK_OPERATOR_VALIDATE_BYTE_RANGE = 385, // "OPERATOR_VALIDATE_BYTE_RANGE" + TOK_OPERATOR_VALIDATE_DTD = 386, // "OPERATOR_VALIDATE_DTD" + TOK_OPERATOR_VALIDATE_HASH = 387, // "OPERATOR_VALIDATE_HASH" + TOK_OPERATOR_VALIDATE_SCHEMA = 388, // "OPERATOR_VALIDATE_SCHEMA" + TOK_OPERATOR_VALIDATE_URL_ENCODING = 389, // "OPERATOR_VALIDATE_URL_ENCODING" + TOK_OPERATOR_VALIDATE_UTF8_ENCODING = 390, // "OPERATOR_VALIDATE_UTF8_ENCODING" + TOK_OPERATOR_VERIFY_CC = 391, // "OPERATOR_VERIFY_CC" + TOK_OPERATOR_VERIFY_CPF = 392, // "OPERATOR_VERIFY_CPF" + TOK_OPERATOR_VERIFY_SSN = 393, // "OPERATOR_VERIFY_SSN" + TOK_OPERATOR_VERIFY_SVNR = 394, // "OPERATOR_VERIFY_SVNR" + TOK_OPERATOR_WITHIN = 395, // "OPERATOR_WITHIN" + TOK_CONFIG_DIR_AUDIT_LOG_FMT = 396, // CONFIG_DIR_AUDIT_LOG_FMT + TOK_JSON = 397, // JSON + TOK_NATIVE = 398, // NATIVE + TOK_ACTION_CTL_RULE_ENGINE = 399, // "ACTION_CTL_RULE_ENGINE" + TOK_ACTION_ACCURACY = 400, // "Accuracy" + TOK_ACTION_ALLOW = 401, // "Allow" + TOK_ACTION_APPEND = 402, // "Append" + TOK_ACTION_AUDIT_LOG = 403, // "AuditLog" + TOK_ACTION_BLOCK = 404, // "Block" + TOK_ACTION_CAPTURE = 405, // "Capture" + TOK_ACTION_CHAIN = 406, // "Chain" + TOK_ACTION_CTL_AUDIT_ENGINE = 407, // "ACTION_CTL_AUDIT_ENGINE" + TOK_ACTION_CTL_AUDIT_LOG_PARTS = 408, // "ACTION_CTL_AUDIT_LOG_PARTS" + TOK_ACTION_CTL_BDY_JSON = 409, // "ACTION_CTL_BDY_JSON" + TOK_ACTION_CTL_BDY_XML = 410, // "ACTION_CTL_BDY_XML" + TOK_ACTION_CTL_BDY_URLENCODED = 411, // "ACTION_CTL_BDY_URLENCODED" + TOK_ACTION_CTL_FORCE_REQ_BODY_VAR = 412, // "ACTION_CTL_FORCE_REQ_BODY_VAR" + TOK_ACTION_CTL_REQUEST_BODY_ACCESS = 413, // "ACTION_CTL_REQUEST_BODY_ACCESS" + TOK_ACTION_CTL_RULE_REMOVE_BY_ID = 414, // "ACTION_CTL_RULE_REMOVE_BY_ID" + TOK_ACTION_CTL_RULE_REMOVE_BY_TAG = 415, // "ACTION_CTL_RULE_REMOVE_BY_TAG" + TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 416, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" + TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 417, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" + TOK_ACTION_DENY = 418, // "Deny" + TOK_ACTION_DEPRECATE_VAR = 419, // "DeprecateVar" + TOK_ACTION_DROP = 420, // "Drop" + TOK_ACTION_EXEC = 421, // "Exec" + TOK_ACTION_EXPIRE_VAR = 422, // "ExpireVar" + TOK_ACTION_ID = 423, // "Id" + TOK_ACTION_INITCOL = 424, // "InitCol" + TOK_ACTION_LOG = 425, // "Log" + TOK_ACTION_LOG_DATA = 426, // "LogData" + TOK_ACTION_MATURITY = 427, // "Maturity" + TOK_ACTION_MSG = 428, // "Msg" + TOK_ACTION_MULTI_MATCH = 429, // "MultiMatch" + TOK_ACTION_NO_AUDIT_LOG = 430, // "NoAuditLog" + TOK_ACTION_NO_LOG = 431, // "NoLog" + TOK_ACTION_PASS = 432, // "Pass" + TOK_ACTION_PAUSE = 433, // "Pause" + TOK_ACTION_PHASE = 434, // "Phase" + TOK_ACTION_PREPEND = 435, // "Prepend" + TOK_ACTION_PROXY = 436, // "Proxy" + TOK_ACTION_REDIRECT = 437, // "Redirect" + TOK_ACTION_REV = 438, // "Rev" + TOK_ACTION_SANITISE_ARG = 439, // "SanitiseArg" + TOK_ACTION_SANITISE_MATCHED = 440, // "SanitiseMatched" + TOK_ACTION_SANITISE_MATCHED_BYTES = 441, // "SanitiseMatchedBytes" + TOK_ACTION_SANITISE_REQUEST_HEADER = 442, // "SanitiseRequestHeader" + TOK_ACTION_SANITISE_RESPONSE_HEADER = 443, // "SanitiseResponseHeader" + TOK_ACTION_SETENV = 444, // "SetEnv" + TOK_ACTION_SETRSC = 445, // "SetRsc" + TOK_ACTION_SETSID = 446, // "SetSid" + TOK_ACTION_SETUID = 447, // "SetUID" + TOK_ACTION_SEVERITY = 448, // "Severity" + TOK_ACTION_SKIP = 449, // "Skip" + TOK_ACTION_SKIP_AFTER = 450, // "SkipAfter" + TOK_ACTION_STATUS = 451, // "Status" + TOK_ACTION_TAG = 452, // "Tag" + TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE = 453, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" + TOK_ACTION_TRANSFORMATION_BASE_64_DECODE = 454, // "ACTION_TRANSFORMATION_BASE_64_DECODE" + TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 455, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" + TOK_ACTION_TRANSFORMATION_CMD_LINE = 456, // "ACTION_TRANSFORMATION_CMD_LINE" + TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 457, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" + TOK_ACTION_TRANSFORMATION_CSS_DECODE = 458, // "ACTION_TRANSFORMATION_CSS_DECODE" + TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 459, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" + TOK_ACTION_TRANSFORMATION_HEX_ENCODE = 460, // "ACTION_TRANSFORMATION_HEX_ENCODE" + TOK_ACTION_TRANSFORMATION_HEX_DECODE = 461, // "ACTION_TRANSFORMATION_HEX_DECODE" + TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 462, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" + TOK_ACTION_TRANSFORMATION_JS_DECODE = 463, // "ACTION_TRANSFORMATION_JS_DECODE" + TOK_ACTION_TRANSFORMATION_LENGTH = 464, // "ACTION_TRANSFORMATION_LENGTH" + TOK_ACTION_TRANSFORMATION_LOWERCASE = 465, // "ACTION_TRANSFORMATION_LOWERCASE" + TOK_ACTION_TRANSFORMATION_MD5 = 466, // "ACTION_TRANSFORMATION_MD5" + TOK_ACTION_TRANSFORMATION_NONE = 467, // "ACTION_TRANSFORMATION_NONE" + TOK_ACTION_TRANSFORMATION_NORMALISE_PATH = 468, // "ACTION_TRANSFORMATION_NORMALISE_PATH" + TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 469, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" + TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 470, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" + TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 471, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" + TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 472, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" + TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 473, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" + TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 474, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" + TOK_ACTION_TRANSFORMATION_REMOVE_NULLS = 475, // "ACTION_TRANSFORMATION_REMOVE_NULLS" + TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 476, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" + TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 477, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" + TOK_ACTION_TRANSFORMATION_REPLACE_NULLS = 478, // "ACTION_TRANSFORMATION_REPLACE_NULLS" + TOK_ACTION_TRANSFORMATION_SHA1 = 479, // "ACTION_TRANSFORMATION_SHA1" + TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 480, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" + TOK_ACTION_TRANSFORMATION_TRIM = 481, // "ACTION_TRANSFORMATION_TRIM" + TOK_ACTION_TRANSFORMATION_TRIM_LEFT = 482, // "ACTION_TRANSFORMATION_TRIM_LEFT" + TOK_ACTION_TRANSFORMATION_TRIM_RIGHT = 483, // "ACTION_TRANSFORMATION_TRIM_RIGHT" + TOK_ACTION_TRANSFORMATION_UPPERCASE = 484, // "ACTION_TRANSFORMATION_UPPERCASE" + TOK_ACTION_TRANSFORMATION_URL_ENCODE = 485, // "ACTION_TRANSFORMATION_URL_ENCODE" + TOK_ACTION_TRANSFORMATION_URL_DECODE = 486, // "ACTION_TRANSFORMATION_URL_DECODE" + TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI = 487, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" + TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 488, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" + TOK_ACTION_VER = 489, // "Ver" + TOK_ACTION_XMLNS = 490, // "xmlns" + TOK_CONFIG_COMPONENT_SIG = 491, // "CONFIG_COMPONENT_SIG" + TOK_CONFIG_CONN_ENGINE = 492, // "CONFIG_CONN_ENGINE" + TOK_CONFIG_SEC_ARGUMENT_SEPARATOR = 493, // "CONFIG_SEC_ARGUMENT_SEPARATOR" + TOK_CONFIG_SEC_WEB_APP_ID = 494, // "CONFIG_SEC_WEB_APP_ID" + TOK_CONFIG_SEC_SERVER_SIG = 495, // "CONFIG_SEC_SERVER_SIG" + TOK_CONFIG_DIR_AUDIT_DIR = 496, // "CONFIG_DIR_AUDIT_DIR" + TOK_CONFIG_DIR_AUDIT_DIR_MOD = 497, // "CONFIG_DIR_AUDIT_DIR_MOD" + TOK_CONFIG_DIR_AUDIT_ENG = 498, // "CONFIG_DIR_AUDIT_ENG" + TOK_CONFIG_DIR_AUDIT_FLE_MOD = 499, // "CONFIG_DIR_AUDIT_FLE_MOD" + TOK_CONFIG_DIR_AUDIT_LOG = 500, // "CONFIG_DIR_AUDIT_LOG" + TOK_CONFIG_DIR_AUDIT_LOG2 = 501, // "CONFIG_DIR_AUDIT_LOG2" + TOK_CONFIG_DIR_AUDIT_LOG_P = 502, // "CONFIG_DIR_AUDIT_LOG_P" + TOK_CONFIG_DIR_AUDIT_STS = 503, // "CONFIG_DIR_AUDIT_STS" + TOK_CONFIG_DIR_AUDIT_TPE = 504, // "CONFIG_DIR_AUDIT_TPE" + TOK_CONFIG_DIR_DEBUG_LOG = 505, // "CONFIG_DIR_DEBUG_LOG" + TOK_CONFIG_DIR_DEBUG_LVL = 506, // "CONFIG_DIR_DEBUG_LVL" + TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS = 507, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" + TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 508, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" + TOK_CONFIG_SEC_HASH_ENGINE = 509, // "CONFIG_SEC_HASH_ENGINE" + TOK_CONFIG_SEC_HASH_KEY = 510, // "CONFIG_SEC_HASH_KEY" + TOK_CONFIG_SEC_HASH_PARAM = 511, // "CONFIG_SEC_HASH_PARAM" + TOK_CONFIG_SEC_HASH_METHOD_RX = 512, // "CONFIG_SEC_HASH_METHOD_RX" + TOK_CONFIG_SEC_HASH_METHOD_PM = 513, // "CONFIG_SEC_HASH_METHOD_PM" + TOK_CONFIG_SEC_CHROOT_DIR = 514, // "CONFIG_SEC_CHROOT_DIR" + TOK_CONFIG_DIR_GEO_DB = 515, // "CONFIG_DIR_GEO_DB" + TOK_CONFIG_DIR_GSB_DB = 516, // "CONFIG_DIR_GSB_DB" + TOK_CONFIG_SEC_GUARDIAN_LOG = 517, // "CONFIG_SEC_GUARDIAN_LOG" + TOK_CONFIG_DIR_PCRE_MATCH_LIMIT = 518, // "CONFIG_DIR_PCRE_MATCH_LIMIT" + TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 519, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" + TOK_CONFIG_SEC_CONN_R_STATE_LIMIT = 520, // "CONFIG_SEC_CONN_R_STATE_LIMIT" + TOK_CONFIG_SEC_CONN_W_STATE_LIMIT = 521, // "CONFIG_SEC_CONN_W_STATE_LIMIT" + TOK_CONFIG_SEC_SENSOR_ID = 522, // "CONFIG_SEC_SENSOR_ID" + TOK_CONFIG_DIR_ARGS_LIMIT = 523, // "CONFIG_DIR_ARGS_LIMIT" + TOK_CONFIG_DIR_REQ_BODY = 524, // "CONFIG_DIR_REQ_BODY" + TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 525, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" + TOK_CONFIG_DIR_REQ_BODY_LIMIT = 526, // "CONFIG_DIR_REQ_BODY_LIMIT" + TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 527, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" + TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 528, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" + TOK_CONFIG_DIR_RES_BODY = 529, // "CONFIG_DIR_RES_BODY" + TOK_CONFIG_DIR_RES_BODY_LIMIT = 530, // "CONFIG_DIR_RES_BODY_LIMIT" + TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 531, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" + TOK_CONFIG_SEC_RULE_INHERITANCE = 532, // "CONFIG_SEC_RULE_INHERITANCE" + TOK_CONFIG_SEC_RULE_PERF_TIME = 533, // "CONFIG_SEC_RULE_PERF_TIME" + TOK_CONFIG_DIR_RULE_ENG = 534, // "CONFIG_DIR_RULE_ENG" + TOK_CONFIG_DIR_SEC_ACTION = 535, // "CONFIG_DIR_SEC_ACTION" + TOK_CONFIG_DIR_SEC_DEFAULT_ACTION = 536, // "CONFIG_DIR_SEC_DEFAULT_ACTION" + TOK_CONFIG_DIR_SEC_MARKER = 537, // "CONFIG_DIR_SEC_MARKER" + TOK_CONFIG_DIR_UNICODE_MAP_FILE = 538, // "CONFIG_DIR_UNICODE_MAP_FILE" + TOK_CONFIG_DIR_UNICODE_CODE_PAGE = 539, // "CONFIG_DIR_UNICODE_CODE_PAGE" + TOK_CONFIG_SEC_COLLECTION_TIMEOUT = 540, // "CONFIG_SEC_COLLECTION_TIMEOUT" + TOK_CONFIG_SEC_HTTP_BLKEY = 541, // "CONFIG_SEC_HTTP_BLKEY" + TOK_CONFIG_SEC_INTERCEPT_ON_ERROR = 542, // "CONFIG_SEC_INTERCEPT_ON_ERROR" + TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 543, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" + TOK_CONFIG_SEC_RULE_REMOVE_BY_ID = 544, // "CONFIG_SEC_RULE_REMOVE_BY_ID" + TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG = 545, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" + TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG = 546, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 547, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 548, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" + TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 549, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" + TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 550, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" + TOK_CONFIG_UPDLOAD_KEEP_FILES = 551, // "CONFIG_UPDLOAD_KEEP_FILES" + TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES = 552, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" + TOK_CONFIG_UPLOAD_DIR = 553, // "CONFIG_UPLOAD_DIR" + TOK_CONFIG_UPLOAD_FILE_LIMIT = 554, // "CONFIG_UPLOAD_FILE_LIMIT" + TOK_CONFIG_UPLOAD_FILE_MODE = 555, // "CONFIG_UPLOAD_FILE_MODE" + TOK_CONFIG_VALUE_ABORT = 556, // "CONFIG_VALUE_ABORT" + TOK_CONFIG_VALUE_DETC = 557, // "CONFIG_VALUE_DETC" + TOK_CONFIG_VALUE_HTTPS = 558, // "CONFIG_VALUE_HTTPS" + TOK_CONFIG_VALUE_OFF = 559, // "CONFIG_VALUE_OFF" + TOK_CONFIG_VALUE_ON = 560, // "CONFIG_VALUE_ON" + TOK_CONFIG_VALUE_PARALLEL = 561, // "CONFIG_VALUE_PARALLEL" + TOK_CONFIG_VALUE_PROCESS_PARTIAL = 562, // "CONFIG_VALUE_PROCESS_PARTIAL" + TOK_CONFIG_VALUE_REJECT = 563, // "CONFIG_VALUE_REJECT" + TOK_CONFIG_VALUE_RELEVANT_ONLY = 564, // "CONFIG_VALUE_RELEVANT_ONLY" + TOK_CONFIG_VALUE_SERIAL = 565, // "CONFIG_VALUE_SERIAL" + TOK_CONFIG_VALUE_WARN = 566, // "CONFIG_VALUE_WARN" + TOK_CONFIG_XML_EXTERNAL_ENTITY = 567, // "CONFIG_XML_EXTERNAL_ENTITY" + TOK_CONGIG_DIR_RESPONSE_BODY_MP = 568, // "CONGIG_DIR_RESPONSE_BODY_MP" + TOK_CONGIG_DIR_SEC_ARG_SEP = 569, // "CONGIG_DIR_SEC_ARG_SEP" + TOK_CONGIG_DIR_SEC_COOKIE_FORMAT = 570, // "CONGIG_DIR_SEC_COOKIE_FORMAT" + TOK_CONFIG_SEC_COOKIEV0_SEPARATOR = 571, // "CONFIG_SEC_COOKIEV0_SEPARATOR" + TOK_CONGIG_DIR_SEC_DATA_DIR = 572, // "CONGIG_DIR_SEC_DATA_DIR" + TOK_CONGIG_DIR_SEC_STATUS_ENGINE = 573, // "CONGIG_DIR_SEC_STATUS_ENGINE" + TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 574, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" + TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 575, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" + TOK_CONGIG_DIR_SEC_TMP_DIR = 576, // "CONGIG_DIR_SEC_TMP_DIR" + TOK_DIRECTIVE = 577, // "DIRECTIVE" + TOK_DIRECTIVE_SECRULESCRIPT = 578, // "DIRECTIVE_SECRULESCRIPT" + TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION = 579, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" + TOK_QUOTATION_MARK = 580, // "QUOTATION_MARK" + TOK_RUN_TIME_VAR_BLD = 581, // "RUN_TIME_VAR_BLD" + TOK_RUN_TIME_VAR_DUR = 582, // "RUN_TIME_VAR_DUR" + TOK_RUN_TIME_VAR_HSV = 583, // "RUN_TIME_VAR_HSV" + TOK_RUN_TIME_VAR_REMOTE_USER = 584, // "RUN_TIME_VAR_REMOTE_USER" + TOK_RUN_TIME_VAR_TIME = 585, // "RUN_TIME_VAR_TIME" + TOK_RUN_TIME_VAR_TIME_DAY = 586, // "RUN_TIME_VAR_TIME_DAY" + TOK_RUN_TIME_VAR_TIME_EPOCH = 587, // "RUN_TIME_VAR_TIME_EPOCH" + TOK_RUN_TIME_VAR_TIME_HOUR = 588, // "RUN_TIME_VAR_TIME_HOUR" + TOK_RUN_TIME_VAR_TIME_MIN = 589, // "RUN_TIME_VAR_TIME_MIN" + TOK_RUN_TIME_VAR_TIME_MON = 590, // "RUN_TIME_VAR_TIME_MON" + TOK_RUN_TIME_VAR_TIME_SEC = 591, // "RUN_TIME_VAR_TIME_SEC" + TOK_RUN_TIME_VAR_TIME_WDAY = 592, // "RUN_TIME_VAR_TIME_WDAY" + TOK_RUN_TIME_VAR_TIME_YEAR = 593, // "RUN_TIME_VAR_TIME_YEAR" + TOK_VARIABLE = 594, // "VARIABLE" + TOK_DICT_ELEMENT = 595, // "Dictionary element" + TOK_DICT_ELEMENT_REGEXP = 596 // "Dictionary element, selected by regexp" }; + /// Backward compatibility alias (Bison 3.6). + typedef token_kind_type yytokentype; }; - /// (External) token type, as returned by yylex. - typedef token::yytokentype token_type; + /// Token kind, as returned by yylex. + typedef token::yytokentype token_kind_type; + + /// Backward compatibility alias (Bison 3.6). + typedef token_kind_type token_type; - /// Symbol type: an internal symbol number. - typedef int symbol_number_type; + /// Symbol kinds. + struct symbol_kind + { + enum symbol_kind_type + { + YYNTOKENS = 342, ///< Number of tokens. + S_YYEMPTY = -2, + S_YYEOF = 0, // "end of file" + S_YYerror = 1, // error + S_YYUNDEF = 2, // "invalid token" + S_COMMA = 3, // "," + S_CONFIG_CONTENT_INJECTION = 4, // "CONFIG_CONTENT_INJECTION" + S_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR = 5, // "CONGIG_DIR_RESPONSE_BODY_MP_CLEAR" + S_PIPE = 6, // PIPE + S_NEW_LINE = 7, // NEW_LINE + S_VAR_COUNT = 8, // VAR_COUNT + S_VAR_EXCLUSION = 9, // VAR_EXCLUSION + S_VARIABLE_ARGS = 10, // VARIABLE_ARGS + S_VARIABLE_ARGS_POST = 11, // VARIABLE_ARGS_POST + S_VARIABLE_ARGS_GET = 12, // VARIABLE_ARGS_GET + S_VARIABLE_FILES_SIZES = 13, // VARIABLE_FILES_SIZES + S_VARIABLE_FILES_NAMES = 14, // VARIABLE_FILES_NAMES + S_VARIABLE_FILES_TMP_CONTENT = 15, // VARIABLE_FILES_TMP_CONTENT + S_VARIABLE_MULTIPART_FILENAME = 16, // VARIABLE_MULTIPART_FILENAME + S_VARIABLE_MULTIPART_NAME = 17, // VARIABLE_MULTIPART_NAME + S_VARIABLE_MATCHED_VARS_NAMES = 18, // VARIABLE_MATCHED_VARS_NAMES + S_VARIABLE_MATCHED_VARS = 19, // VARIABLE_MATCHED_VARS + S_VARIABLE_FILES = 20, // VARIABLE_FILES + S_VARIABLE_REQUEST_COOKIES = 21, // VARIABLE_REQUEST_COOKIES + S_VARIABLE_REQUEST_HEADERS = 22, // VARIABLE_REQUEST_HEADERS + S_VARIABLE_RESPONSE_HEADERS = 23, // VARIABLE_RESPONSE_HEADERS + S_VARIABLE_GEO = 24, // VARIABLE_GEO + S_VARIABLE_REQUEST_COOKIES_NAMES = 25, // VARIABLE_REQUEST_COOKIES_NAMES + S_VARIABLE_ARGS_COMBINED_SIZE = 26, // VARIABLE_ARGS_COMBINED_SIZE + S_VARIABLE_ARGS_GET_NAMES = 27, // VARIABLE_ARGS_GET_NAMES + S_VARIABLE_RULE = 28, // VARIABLE_RULE + S_VARIABLE_ARGS_NAMES = 29, // "Variable ARGS_NAMES" + S_VARIABLE_ARGS_POST_NAMES = 30, // VARIABLE_ARGS_POST_NAMES + S_VARIABLE_AUTH_TYPE = 31, // "AUTH_TYPE" + S_VARIABLE_FILES_COMBINED_SIZE = 32, // "FILES_COMBINED_SIZE" + S_VARIABLE_FILES_TMP_NAMES = 33, // "FILES_TMPNAMES" + S_VARIABLE_FULL_REQUEST = 34, // "FULL_REQUEST" + S_VARIABLE_FULL_REQUEST_LENGTH = 35, // "FULL_REQUEST_LENGTH" + S_VARIABLE_INBOUND_DATA_ERROR = 36, // "INBOUND_DATA_ERROR" + S_VARIABLE_MATCHED_VAR = 37, // "MATCHED_VAR" + S_VARIABLE_MATCHED_VAR_NAME = 38, // "MATCHED_VAR_NAME" + S_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 39, // VARIABLE_MULTIPART_BOUNDARY_QUOTED + S_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 40, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE + S_VARIABLE_MULTIPART_CRLF_LF_LINES = 41, // "MULTIPART_CRLF_LF_LINES" + S_VARIABLE_MULTIPART_DATA_AFTER = 42, // "MULTIPART_DATA_AFTER" + S_VARIABLE_MULTIPART_DATA_BEFORE = 43, // VARIABLE_MULTIPART_DATA_BEFORE + S_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 44, // "MULTIPART_FILE_LIMIT_EXCEEDED" + S_VARIABLE_MULTIPART_HEADER_FOLDING = 45, // "MULTIPART_HEADER_FOLDING" + S_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 46, // "MULTIPART_INVALID_HEADER_FOLDING" + S_VARIABLE_MULTIPART_INVALID_PART = 47, // VARIABLE_MULTIPART_INVALID_PART + S_VARIABLE_MULTIPART_INVALID_QUOTING = 48, // "MULTIPART_INVALID_QUOTING" + S_VARIABLE_MULTIPART_LF_LINE = 49, // VARIABLE_MULTIPART_LF_LINE + S_VARIABLE_MULTIPART_MISSING_SEMICOLON = 50, // VARIABLE_MULTIPART_MISSING_SEMICOLON + S_VARIABLE_MULTIPART_SEMICOLON_MISSING = 51, // VARIABLE_MULTIPART_SEMICOLON_MISSING + S_VARIABLE_MULTIPART_STRICT_ERROR = 52, // "MULTIPART_STRICT_ERROR" + S_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 53, // "MULTIPART_UNMATCHED_BOUNDARY" + S_VARIABLE_OUTBOUND_DATA_ERROR = 54, // "OUTBOUND_DATA_ERROR" + S_VARIABLE_PATH_INFO = 55, // "PATH_INFO" + S_VARIABLE_QUERY_STRING = 56, // "QUERY_STRING" + S_VARIABLE_REMOTE_ADDR = 57, // "REMOTE_ADDR" + S_VARIABLE_REMOTE_HOST = 58, // "REMOTE_HOST" + S_VARIABLE_REMOTE_PORT = 59, // "REMOTE_PORT" + S_VARIABLE_REQBODY_ERROR_MSG = 60, // "REQBODY_ERROR_MSG" + S_VARIABLE_REQBODY_ERROR = 61, // "REQBODY_ERROR" + S_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 62, // "REQBODY_PROCESSOR_ERROR_MSG" + S_VARIABLE_REQBODY_PROCESSOR_ERROR = 63, // "REQBODY_PROCESSOR_ERROR" + S_VARIABLE_REQBODY_PROCESSOR = 64, // "REQBODY_PROCESSOR" + S_VARIABLE_REQUEST_BASENAME = 65, // "REQUEST_BASENAME" + S_VARIABLE_REQUEST_BODY_LENGTH = 66, // "REQUEST_BODY_LENGTH" + S_VARIABLE_REQUEST_BODY = 67, // "REQUEST_BODY" + S_VARIABLE_REQUEST_FILE_NAME = 68, // "REQUEST_FILENAME" + S_VARIABLE_REQUEST_HEADERS_NAMES = 69, // VARIABLE_REQUEST_HEADERS_NAMES + S_VARIABLE_REQUEST_LINE = 70, // "REQUEST_LINE" + S_VARIABLE_REQUEST_METHOD = 71, // "REQUEST_METHOD" + S_VARIABLE_REQUEST_PROTOCOL = 72, // "REQUEST_PROTOCOL" + S_VARIABLE_REQUEST_URI_RAW = 73, // "REQUEST_URI_RAW" + S_VARIABLE_REQUEST_URI = 74, // "REQUEST_URI" + S_VARIABLE_RESOURCE = 75, // "RESOURCE" + S_VARIABLE_RESPONSE_BODY = 76, // "RESPONSE_BODY" + S_VARIABLE_RESPONSE_CONTENT_LENGTH = 77, // "RESPONSE_CONTENT_LENGTH" + S_VARIABLE_RESPONSE_CONTENT_TYPE = 78, // VARIABLE_RESPONSE_CONTENT_TYPE + S_VARIABLE_RESPONSE_HEADERS_NAMES = 79, // VARIABLE_RESPONSE_HEADERS_NAMES + S_VARIABLE_RESPONSE_PROTOCOL = 80, // "RESPONSE_PROTOCOL" + S_VARIABLE_RESPONSE_STATUS = 81, // "RESPONSE_STATUS" + S_VARIABLE_SERVER_ADDR = 82, // "SERVER_ADDR" + S_VARIABLE_SERVER_NAME = 83, // "SERVER_NAME" + S_VARIABLE_SERVER_PORT = 84, // "SERVER_PORT" + S_VARIABLE_SESSION_ID = 85, // "SESSIONID" + S_VARIABLE_UNIQUE_ID = 86, // "UNIQUE_ID" + S_VARIABLE_URL_ENCODED_ERROR = 87, // "URLENCODED_ERROR" + S_VARIABLE_USER_ID = 88, // "USERID" + S_VARIABLE_WEB_APP_ID = 89, // "WEBAPPID" + S_VARIABLE_STATUS = 90, // "VARIABLE_STATUS" + S_VARIABLE_STATUS_LINE = 91, // "VARIABLE_STATUS_LINE" + S_VARIABLE_IP = 92, // "VARIABLE_IP" + S_VARIABLE_GLOBAL = 93, // "VARIABLE_GLOBAL" + S_VARIABLE_TX = 94, // "VARIABLE_TX" + S_VARIABLE_SESSION = 95, // "VARIABLE_SESSION" + S_VARIABLE_USER = 96, // "VARIABLE_USER" + S_RUN_TIME_VAR_ENV = 97, // "RUN_TIME_VAR_ENV" + S_RUN_TIME_VAR_XML = 98, // "RUN_TIME_VAR_XML" + S_ACTION_SETVAR = 99, // "SetVar" + S_SETVAR_OPERATION_EQUALS = 100, // SETVAR_OPERATION_EQUALS + S_SETVAR_OPERATION_EQUALS_PLUS = 101, // SETVAR_OPERATION_EQUALS_PLUS + S_SETVAR_OPERATION_EQUALS_MINUS = 102, // SETVAR_OPERATION_EQUALS_MINUS + S_NOT = 103, // "NOT" + S_OPERATOR_BEGINS_WITH = 104, // "OPERATOR_BEGINS_WITH" + S_OPERATOR_CONTAINS = 105, // "OPERATOR_CONTAINS" + S_OPERATOR_CONTAINS_WORD = 106, // "OPERATOR_CONTAINS_WORD" + S_OPERATOR_DETECT_SQLI = 107, // "OPERATOR_DETECT_SQLI" + S_OPERATOR_DETECT_XSS = 108, // "OPERATOR_DETECT_XSS" + S_OPERATOR_ENDS_WITH = 109, // "OPERATOR_ENDS_WITH" + S_OPERATOR_EQ = 110, // "OPERATOR_EQ" + S_OPERATOR_FUZZY_HASH = 111, // "OPERATOR_FUZZY_HASH" + S_OPERATOR_GEOLOOKUP = 112, // "OPERATOR_GEOLOOKUP" + S_OPERATOR_GE = 113, // "OPERATOR_GE" + S_OPERATOR_GSB_LOOKUP = 114, // "OPERATOR_GSB_LOOKUP" + S_OPERATOR_GT = 115, // "OPERATOR_GT" + S_OPERATOR_INSPECT_FILE = 116, // "OPERATOR_INSPECT_FILE" + S_OPERATOR_IP_MATCH_FROM_FILE = 117, // "OPERATOR_IP_MATCH_FROM_FILE" + S_OPERATOR_IP_MATCH = 118, // "OPERATOR_IP_MATCH" + S_OPERATOR_LE = 119, // "OPERATOR_LE" + S_OPERATOR_LT = 120, // "OPERATOR_LT" + S_OPERATOR_PM_FROM_FILE = 121, // "OPERATOR_PM_FROM_FILE" + S_OPERATOR_PM = 122, // "OPERATOR_PM" + S_OPERATOR_RBL = 123, // "OPERATOR_RBL" + S_OPERATOR_RSUB = 124, // "OPERATOR_RSUB" + S_OPERATOR_RX_CONTENT_ONLY = 125, // "Operator RX (content only)" + S_OPERATOR_RX = 126, // "OPERATOR_RX" + S_OPERATOR_STR_EQ = 127, // "OPERATOR_STR_EQ" + S_OPERATOR_STR_MATCH = 128, // "OPERATOR_STR_MATCH" + S_OPERATOR_UNCONDITIONAL_MATCH = 129, // "OPERATOR_UNCONDITIONAL_MATCH" + S_OPERATOR_VALIDATE_BYTE_RANGE = 130, // "OPERATOR_VALIDATE_BYTE_RANGE" + S_OPERATOR_VALIDATE_DTD = 131, // "OPERATOR_VALIDATE_DTD" + S_OPERATOR_VALIDATE_HASH = 132, // "OPERATOR_VALIDATE_HASH" + S_OPERATOR_VALIDATE_SCHEMA = 133, // "OPERATOR_VALIDATE_SCHEMA" + S_OPERATOR_VALIDATE_URL_ENCODING = 134, // "OPERATOR_VALIDATE_URL_ENCODING" + S_OPERATOR_VALIDATE_UTF8_ENCODING = 135, // "OPERATOR_VALIDATE_UTF8_ENCODING" + S_OPERATOR_VERIFY_CC = 136, // "OPERATOR_VERIFY_CC" + S_OPERATOR_VERIFY_CPF = 137, // "OPERATOR_VERIFY_CPF" + S_OPERATOR_VERIFY_SSN = 138, // "OPERATOR_VERIFY_SSN" + S_OPERATOR_VERIFY_SVNR = 139, // "OPERATOR_VERIFY_SVNR" + S_OPERATOR_WITHIN = 140, // "OPERATOR_WITHIN" + S_CONFIG_DIR_AUDIT_LOG_FMT = 141, // CONFIG_DIR_AUDIT_LOG_FMT + S_JSON = 142, // JSON + S_NATIVE = 143, // NATIVE + S_ACTION_CTL_RULE_ENGINE = 144, // "ACTION_CTL_RULE_ENGINE" + S_ACTION_ACCURACY = 145, // "Accuracy" + S_ACTION_ALLOW = 146, // "Allow" + S_ACTION_APPEND = 147, // "Append" + S_ACTION_AUDIT_LOG = 148, // "AuditLog" + S_ACTION_BLOCK = 149, // "Block" + S_ACTION_CAPTURE = 150, // "Capture" + S_ACTION_CHAIN = 151, // "Chain" + S_ACTION_CTL_AUDIT_ENGINE = 152, // "ACTION_CTL_AUDIT_ENGINE" + S_ACTION_CTL_AUDIT_LOG_PARTS = 153, // "ACTION_CTL_AUDIT_LOG_PARTS" + S_ACTION_CTL_BDY_JSON = 154, // "ACTION_CTL_BDY_JSON" + S_ACTION_CTL_BDY_XML = 155, // "ACTION_CTL_BDY_XML" + S_ACTION_CTL_BDY_URLENCODED = 156, // "ACTION_CTL_BDY_URLENCODED" + S_ACTION_CTL_FORCE_REQ_BODY_VAR = 157, // "ACTION_CTL_FORCE_REQ_BODY_VAR" + S_ACTION_CTL_REQUEST_BODY_ACCESS = 158, // "ACTION_CTL_REQUEST_BODY_ACCESS" + S_ACTION_CTL_RULE_REMOVE_BY_ID = 159, // "ACTION_CTL_RULE_REMOVE_BY_ID" + S_ACTION_CTL_RULE_REMOVE_BY_TAG = 160, // "ACTION_CTL_RULE_REMOVE_BY_TAG" + S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 161, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" + S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 162, // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" + S_ACTION_DENY = 163, // "Deny" + S_ACTION_DEPRECATE_VAR = 164, // "DeprecateVar" + S_ACTION_DROP = 165, // "Drop" + S_ACTION_EXEC = 166, // "Exec" + S_ACTION_EXPIRE_VAR = 167, // "ExpireVar" + S_ACTION_ID = 168, // "Id" + S_ACTION_INITCOL = 169, // "InitCol" + S_ACTION_LOG = 170, // "Log" + S_ACTION_LOG_DATA = 171, // "LogData" + S_ACTION_MATURITY = 172, // "Maturity" + S_ACTION_MSG = 173, // "Msg" + S_ACTION_MULTI_MATCH = 174, // "MultiMatch" + S_ACTION_NO_AUDIT_LOG = 175, // "NoAuditLog" + S_ACTION_NO_LOG = 176, // "NoLog" + S_ACTION_PASS = 177, // "Pass" + S_ACTION_PAUSE = 178, // "Pause" + S_ACTION_PHASE = 179, // "Phase" + S_ACTION_PREPEND = 180, // "Prepend" + S_ACTION_PROXY = 181, // "Proxy" + S_ACTION_REDIRECT = 182, // "Redirect" + S_ACTION_REV = 183, // "Rev" + S_ACTION_SANITISE_ARG = 184, // "SanitiseArg" + S_ACTION_SANITISE_MATCHED = 185, // "SanitiseMatched" + S_ACTION_SANITISE_MATCHED_BYTES = 186, // "SanitiseMatchedBytes" + S_ACTION_SANITISE_REQUEST_HEADER = 187, // "SanitiseRequestHeader" + S_ACTION_SANITISE_RESPONSE_HEADER = 188, // "SanitiseResponseHeader" + S_ACTION_SETENV = 189, // "SetEnv" + S_ACTION_SETRSC = 190, // "SetRsc" + S_ACTION_SETSID = 191, // "SetSid" + S_ACTION_SETUID = 192, // "SetUID" + S_ACTION_SEVERITY = 193, // "Severity" + S_ACTION_SKIP = 194, // "Skip" + S_ACTION_SKIP_AFTER = 195, // "SkipAfter" + S_ACTION_STATUS = 196, // "Status" + S_ACTION_TAG = 197, // "Tag" + S_ACTION_TRANSFORMATION_BASE_64_ENCODE = 198, // "ACTION_TRANSFORMATION_BASE_64_ENCODE" + S_ACTION_TRANSFORMATION_BASE_64_DECODE = 199, // "ACTION_TRANSFORMATION_BASE_64_DECODE" + S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 200, // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" + S_ACTION_TRANSFORMATION_CMD_LINE = 201, // "ACTION_TRANSFORMATION_CMD_LINE" + S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 202, // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" + S_ACTION_TRANSFORMATION_CSS_DECODE = 203, // "ACTION_TRANSFORMATION_CSS_DECODE" + S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 204, // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" + S_ACTION_TRANSFORMATION_HEX_ENCODE = 205, // "ACTION_TRANSFORMATION_HEX_ENCODE" + S_ACTION_TRANSFORMATION_HEX_DECODE = 206, // "ACTION_TRANSFORMATION_HEX_DECODE" + S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 207, // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" + S_ACTION_TRANSFORMATION_JS_DECODE = 208, // "ACTION_TRANSFORMATION_JS_DECODE" + S_ACTION_TRANSFORMATION_LENGTH = 209, // "ACTION_TRANSFORMATION_LENGTH" + S_ACTION_TRANSFORMATION_LOWERCASE = 210, // "ACTION_TRANSFORMATION_LOWERCASE" + S_ACTION_TRANSFORMATION_MD5 = 211, // "ACTION_TRANSFORMATION_MD5" + S_ACTION_TRANSFORMATION_NONE = 212, // "ACTION_TRANSFORMATION_NONE" + S_ACTION_TRANSFORMATION_NORMALISE_PATH = 213, // "ACTION_TRANSFORMATION_NORMALISE_PATH" + S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 214, // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" + S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 215, // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" + S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 216, // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" + S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 217, // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" + S_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 218, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" + S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 219, // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" + S_ACTION_TRANSFORMATION_REMOVE_NULLS = 220, // "ACTION_TRANSFORMATION_REMOVE_NULLS" + S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 221, // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" + S_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 222, // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" + S_ACTION_TRANSFORMATION_REPLACE_NULLS = 223, // "ACTION_TRANSFORMATION_REPLACE_NULLS" + S_ACTION_TRANSFORMATION_SHA1 = 224, // "ACTION_TRANSFORMATION_SHA1" + S_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 225, // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" + S_ACTION_TRANSFORMATION_TRIM = 226, // "ACTION_TRANSFORMATION_TRIM" + S_ACTION_TRANSFORMATION_TRIM_LEFT = 227, // "ACTION_TRANSFORMATION_TRIM_LEFT" + S_ACTION_TRANSFORMATION_TRIM_RIGHT = 228, // "ACTION_TRANSFORMATION_TRIM_RIGHT" + S_ACTION_TRANSFORMATION_UPPERCASE = 229, // "ACTION_TRANSFORMATION_UPPERCASE" + S_ACTION_TRANSFORMATION_URL_ENCODE = 230, // "ACTION_TRANSFORMATION_URL_ENCODE" + S_ACTION_TRANSFORMATION_URL_DECODE = 231, // "ACTION_TRANSFORMATION_URL_DECODE" + S_ACTION_TRANSFORMATION_URL_DECODE_UNI = 232, // "ACTION_TRANSFORMATION_URL_DECODE_UNI" + S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 233, // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" + S_ACTION_VER = 234, // "Ver" + S_ACTION_XMLNS = 235, // "xmlns" + S_CONFIG_COMPONENT_SIG = 236, // "CONFIG_COMPONENT_SIG" + S_CONFIG_CONN_ENGINE = 237, // "CONFIG_CONN_ENGINE" + S_CONFIG_SEC_ARGUMENT_SEPARATOR = 238, // "CONFIG_SEC_ARGUMENT_SEPARATOR" + S_CONFIG_SEC_WEB_APP_ID = 239, // "CONFIG_SEC_WEB_APP_ID" + S_CONFIG_SEC_SERVER_SIG = 240, // "CONFIG_SEC_SERVER_SIG" + S_CONFIG_DIR_AUDIT_DIR = 241, // "CONFIG_DIR_AUDIT_DIR" + S_CONFIG_DIR_AUDIT_DIR_MOD = 242, // "CONFIG_DIR_AUDIT_DIR_MOD" + S_CONFIG_DIR_AUDIT_ENG = 243, // "CONFIG_DIR_AUDIT_ENG" + S_CONFIG_DIR_AUDIT_FLE_MOD = 244, // "CONFIG_DIR_AUDIT_FLE_MOD" + S_CONFIG_DIR_AUDIT_LOG = 245, // "CONFIG_DIR_AUDIT_LOG" + S_CONFIG_DIR_AUDIT_LOG2 = 246, // "CONFIG_DIR_AUDIT_LOG2" + S_CONFIG_DIR_AUDIT_LOG_P = 247, // "CONFIG_DIR_AUDIT_LOG_P" + S_CONFIG_DIR_AUDIT_STS = 248, // "CONFIG_DIR_AUDIT_STS" + S_CONFIG_DIR_AUDIT_TPE = 249, // "CONFIG_DIR_AUDIT_TPE" + S_CONFIG_DIR_DEBUG_LOG = 250, // "CONFIG_DIR_DEBUG_LOG" + S_CONFIG_DIR_DEBUG_LVL = 251, // "CONFIG_DIR_DEBUG_LVL" + S_CONFIG_SEC_CACHE_TRANSFORMATIONS = 252, // "CONFIG_SEC_CACHE_TRANSFORMATIONS" + S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 253, // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" + S_CONFIG_SEC_HASH_ENGINE = 254, // "CONFIG_SEC_HASH_ENGINE" + S_CONFIG_SEC_HASH_KEY = 255, // "CONFIG_SEC_HASH_KEY" + S_CONFIG_SEC_HASH_PARAM = 256, // "CONFIG_SEC_HASH_PARAM" + S_CONFIG_SEC_HASH_METHOD_RX = 257, // "CONFIG_SEC_HASH_METHOD_RX" + S_CONFIG_SEC_HASH_METHOD_PM = 258, // "CONFIG_SEC_HASH_METHOD_PM" + S_CONFIG_SEC_CHROOT_DIR = 259, // "CONFIG_SEC_CHROOT_DIR" + S_CONFIG_DIR_GEO_DB = 260, // "CONFIG_DIR_GEO_DB" + S_CONFIG_DIR_GSB_DB = 261, // "CONFIG_DIR_GSB_DB" + S_CONFIG_SEC_GUARDIAN_LOG = 262, // "CONFIG_SEC_GUARDIAN_LOG" + S_CONFIG_DIR_PCRE_MATCH_LIMIT = 263, // "CONFIG_DIR_PCRE_MATCH_LIMIT" + S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 264, // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" + S_CONFIG_SEC_CONN_R_STATE_LIMIT = 265, // "CONFIG_SEC_CONN_R_STATE_LIMIT" + S_CONFIG_SEC_CONN_W_STATE_LIMIT = 266, // "CONFIG_SEC_CONN_W_STATE_LIMIT" + S_CONFIG_SEC_SENSOR_ID = 267, // "CONFIG_SEC_SENSOR_ID" + S_CONFIG_DIR_ARGS_LIMIT = 268, // "CONFIG_DIR_ARGS_LIMIT" + S_CONFIG_DIR_REQ_BODY = 269, // "CONFIG_DIR_REQ_BODY" + S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 270, // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" + S_CONFIG_DIR_REQ_BODY_LIMIT = 271, // "CONFIG_DIR_REQ_BODY_LIMIT" + S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 272, // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" + S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 273, // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" + S_CONFIG_DIR_RES_BODY = 274, // "CONFIG_DIR_RES_BODY" + S_CONFIG_DIR_RES_BODY_LIMIT = 275, // "CONFIG_DIR_RES_BODY_LIMIT" + S_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 276, // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" + S_CONFIG_SEC_RULE_INHERITANCE = 277, // "CONFIG_SEC_RULE_INHERITANCE" + S_CONFIG_SEC_RULE_PERF_TIME = 278, // "CONFIG_SEC_RULE_PERF_TIME" + S_CONFIG_DIR_RULE_ENG = 279, // "CONFIG_DIR_RULE_ENG" + S_CONFIG_DIR_SEC_ACTION = 280, // "CONFIG_DIR_SEC_ACTION" + S_CONFIG_DIR_SEC_DEFAULT_ACTION = 281, // "CONFIG_DIR_SEC_DEFAULT_ACTION" + S_CONFIG_DIR_SEC_MARKER = 282, // "CONFIG_DIR_SEC_MARKER" + S_CONFIG_DIR_UNICODE_MAP_FILE = 283, // "CONFIG_DIR_UNICODE_MAP_FILE" + S_CONFIG_DIR_UNICODE_CODE_PAGE = 284, // "CONFIG_DIR_UNICODE_CODE_PAGE" + S_CONFIG_SEC_COLLECTION_TIMEOUT = 285, // "CONFIG_SEC_COLLECTION_TIMEOUT" + S_CONFIG_SEC_HTTP_BLKEY = 286, // "CONFIG_SEC_HTTP_BLKEY" + S_CONFIG_SEC_INTERCEPT_ON_ERROR = 287, // "CONFIG_SEC_INTERCEPT_ON_ERROR" + S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 288, // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" + S_CONFIG_SEC_RULE_REMOVE_BY_ID = 289, // "CONFIG_SEC_RULE_REMOVE_BY_ID" + S_CONFIG_SEC_RULE_REMOVE_BY_MSG = 290, // "CONFIG_SEC_RULE_REMOVE_BY_MSG" + S_CONFIG_SEC_RULE_REMOVE_BY_TAG = 291, // "CONFIG_SEC_RULE_REMOVE_BY_TAG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 292, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 293, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" + S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 294, // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" + S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 295, // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" + S_CONFIG_UPDLOAD_KEEP_FILES = 296, // "CONFIG_UPDLOAD_KEEP_FILES" + S_CONFIG_UPDLOAD_SAVE_TMP_FILES = 297, // "CONFIG_UPDLOAD_SAVE_TMP_FILES" + S_CONFIG_UPLOAD_DIR = 298, // "CONFIG_UPLOAD_DIR" + S_CONFIG_UPLOAD_FILE_LIMIT = 299, // "CONFIG_UPLOAD_FILE_LIMIT" + S_CONFIG_UPLOAD_FILE_MODE = 300, // "CONFIG_UPLOAD_FILE_MODE" + S_CONFIG_VALUE_ABORT = 301, // "CONFIG_VALUE_ABORT" + S_CONFIG_VALUE_DETC = 302, // "CONFIG_VALUE_DETC" + S_CONFIG_VALUE_HTTPS = 303, // "CONFIG_VALUE_HTTPS" + S_CONFIG_VALUE_OFF = 304, // "CONFIG_VALUE_OFF" + S_CONFIG_VALUE_ON = 305, // "CONFIG_VALUE_ON" + S_CONFIG_VALUE_PARALLEL = 306, // "CONFIG_VALUE_PARALLEL" + S_CONFIG_VALUE_PROCESS_PARTIAL = 307, // "CONFIG_VALUE_PROCESS_PARTIAL" + S_CONFIG_VALUE_REJECT = 308, // "CONFIG_VALUE_REJECT" + S_CONFIG_VALUE_RELEVANT_ONLY = 309, // "CONFIG_VALUE_RELEVANT_ONLY" + S_CONFIG_VALUE_SERIAL = 310, // "CONFIG_VALUE_SERIAL" + S_CONFIG_VALUE_WARN = 311, // "CONFIG_VALUE_WARN" + S_CONFIG_XML_EXTERNAL_ENTITY = 312, // "CONFIG_XML_EXTERNAL_ENTITY" + S_CONGIG_DIR_RESPONSE_BODY_MP = 313, // "CONGIG_DIR_RESPONSE_BODY_MP" + S_CONGIG_DIR_SEC_ARG_SEP = 314, // "CONGIG_DIR_SEC_ARG_SEP" + S_CONGIG_DIR_SEC_COOKIE_FORMAT = 315, // "CONGIG_DIR_SEC_COOKIE_FORMAT" + S_CONFIG_SEC_COOKIEV0_SEPARATOR = 316, // "CONFIG_SEC_COOKIEV0_SEPARATOR" + S_CONGIG_DIR_SEC_DATA_DIR = 317, // "CONGIG_DIR_SEC_DATA_DIR" + S_CONGIG_DIR_SEC_STATUS_ENGINE = 318, // "CONGIG_DIR_SEC_STATUS_ENGINE" + S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 319, // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" + S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 320, // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" + S_CONGIG_DIR_SEC_TMP_DIR = 321, // "CONGIG_DIR_SEC_TMP_DIR" + S_DIRECTIVE = 322, // "DIRECTIVE" + S_DIRECTIVE_SECRULESCRIPT = 323, // "DIRECTIVE_SECRULESCRIPT" + S_FREE_TEXT_QUOTE_MACRO_EXPANSION = 324, // "FREE_TEXT_QUOTE_MACRO_EXPANSION" + S_QUOTATION_MARK = 325, // "QUOTATION_MARK" + S_RUN_TIME_VAR_BLD = 326, // "RUN_TIME_VAR_BLD" + S_RUN_TIME_VAR_DUR = 327, // "RUN_TIME_VAR_DUR" + S_RUN_TIME_VAR_HSV = 328, // "RUN_TIME_VAR_HSV" + S_RUN_TIME_VAR_REMOTE_USER = 329, // "RUN_TIME_VAR_REMOTE_USER" + S_RUN_TIME_VAR_TIME = 330, // "RUN_TIME_VAR_TIME" + S_RUN_TIME_VAR_TIME_DAY = 331, // "RUN_TIME_VAR_TIME_DAY" + S_RUN_TIME_VAR_TIME_EPOCH = 332, // "RUN_TIME_VAR_TIME_EPOCH" + S_RUN_TIME_VAR_TIME_HOUR = 333, // "RUN_TIME_VAR_TIME_HOUR" + S_RUN_TIME_VAR_TIME_MIN = 334, // "RUN_TIME_VAR_TIME_MIN" + S_RUN_TIME_VAR_TIME_MON = 335, // "RUN_TIME_VAR_TIME_MON" + S_RUN_TIME_VAR_TIME_SEC = 336, // "RUN_TIME_VAR_TIME_SEC" + S_RUN_TIME_VAR_TIME_WDAY = 337, // "RUN_TIME_VAR_TIME_WDAY" + S_RUN_TIME_VAR_TIME_YEAR = 338, // "RUN_TIME_VAR_TIME_YEAR" + S_VARIABLE = 339, // "VARIABLE" + S_DICT_ELEMENT = 340, // "Dictionary element" + S_DICT_ELEMENT_REGEXP = 341, // "Dictionary element, selected by regexp" + S_YYACCEPT = 342, // $accept + S_input = 343, // input + S_line = 344, // line + S_audit_log = 345, // audit_log + S_actions = 346, // actions + S_actions_may_quoted = 347, // actions_may_quoted + S_op = 348, // op + S_op_before_init = 349, // op_before_init + S_expression = 350, // expression + S_variables = 351, // variables + S_variables_pre_process = 352, // variables_pre_process + S_variables_may_be_quoted = 353, // variables_may_be_quoted + S_var = 354, // var + S_act = 355, // act + S_setvar_action = 356, // setvar_action + S_run_time_string = 357 // run_time_string + }; + }; - /// The symbol type number to denote an empty symbol. - enum { empty_symbol = -2 }; + /// (Internal) symbol kind. + typedef symbol_kind::symbol_kind_type symbol_kind_type; - /// Internal symbol number for tokens (subsumed by symbol_number_type). - typedef short token_number_type; + /// The number of tokens. + static const symbol_kind_type YYNTOKENS = symbol_kind::YYNTOKENS; /// A complete symbol. /// - /// Expects its Base type to provide access to the symbol type - /// via type_get (). + /// Expects its Base type to provide access to the symbol kind + /// via kind (). /// /// Provide access to semantic value and location. template @@ -1329,7 +1716,247 @@ namespace yy { #if 201103L <= YY_CPLUSPLUS /// Move constructor. - basic_symbol (basic_symbol&& that); + basic_symbol (basic_symbol&& that) + : Base (std::move (that)) + , value () + , location (std::move (that.location)) + { + switch (this->kind ()) + { + case 145: // "Accuracy" + case 146: // "Allow" + case 147: // "Append" + case 148: // "AuditLog" + case 149: // "Block" + case 150: // "Capture" + case 151: // "Chain" + case 152: // "ACTION_CTL_AUDIT_ENGINE" + case 153: // "ACTION_CTL_AUDIT_LOG_PARTS" + case 154: // "ACTION_CTL_BDY_JSON" + case 155: // "ACTION_CTL_BDY_XML" + case 156: // "ACTION_CTL_BDY_URLENCODED" + case 157: // "ACTION_CTL_FORCE_REQ_BODY_VAR" + case 158: // "ACTION_CTL_REQUEST_BODY_ACCESS" + case 159: // "ACTION_CTL_RULE_REMOVE_BY_ID" + case 160: // "ACTION_CTL_RULE_REMOVE_BY_TAG" + case 161: // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" + case 162: // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" + case 163: // "Deny" + case 164: // "DeprecateVar" + case 165: // "Drop" + case 166: // "Exec" + case 167: // "ExpireVar" + case 168: // "Id" + case 169: // "InitCol" + case 170: // "Log" + case 171: // "LogData" + case 172: // "Maturity" + case 173: // "Msg" + case 174: // "MultiMatch" + case 175: // "NoAuditLog" + case 176: // "NoLog" + case 177: // "Pass" + case 178: // "Pause" + case 179: // "Phase" + case 180: // "Prepend" + case 181: // "Proxy" + case 182: // "Redirect" + case 183: // "Rev" + case 184: // "SanitiseArg" + case 185: // "SanitiseMatched" + case 186: // "SanitiseMatchedBytes" + case 187: // "SanitiseRequestHeader" + case 188: // "SanitiseResponseHeader" + case 189: // "SetEnv" + case 190: // "SetRsc" + case 191: // "SetSid" + case 192: // "SetUID" + case 193: // "Severity" + case 194: // "Skip" + case 195: // "SkipAfter" + case 196: // "Status" + case 197: // "Tag" + case 198: // "ACTION_TRANSFORMATION_BASE_64_ENCODE" + case 199: // "ACTION_TRANSFORMATION_BASE_64_DECODE" + case 200: // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" + case 201: // "ACTION_TRANSFORMATION_CMD_LINE" + case 202: // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" + case 203: // "ACTION_TRANSFORMATION_CSS_DECODE" + case 204: // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" + case 205: // "ACTION_TRANSFORMATION_HEX_ENCODE" + case 206: // "ACTION_TRANSFORMATION_HEX_DECODE" + case 207: // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" + case 208: // "ACTION_TRANSFORMATION_JS_DECODE" + case 209: // "ACTION_TRANSFORMATION_LENGTH" + case 210: // "ACTION_TRANSFORMATION_LOWERCASE" + case 211: // "ACTION_TRANSFORMATION_MD5" + case 212: // "ACTION_TRANSFORMATION_NONE" + case 213: // "ACTION_TRANSFORMATION_NORMALISE_PATH" + case 214: // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" + case 215: // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" + case 216: // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" + case 217: // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" + case 218: // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" + case 219: // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" + case 220: // "ACTION_TRANSFORMATION_REMOVE_NULLS" + case 221: // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" + case 222: // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" + case 223: // "ACTION_TRANSFORMATION_REPLACE_NULLS" + case 224: // "ACTION_TRANSFORMATION_SHA1" + case 225: // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" + case 226: // "ACTION_TRANSFORMATION_TRIM" + case 227: // "ACTION_TRANSFORMATION_TRIM_LEFT" + case 228: // "ACTION_TRANSFORMATION_TRIM_RIGHT" + case 229: // "ACTION_TRANSFORMATION_UPPERCASE" + case 230: // "ACTION_TRANSFORMATION_URL_ENCODE" + case 231: // "ACTION_TRANSFORMATION_URL_DECODE" + case 232: // "ACTION_TRANSFORMATION_URL_DECODE_UNI" + case 233: // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" + case 234: // "Ver" + case 235: // "xmlns" + case 236: // "CONFIG_COMPONENT_SIG" + case 237: // "CONFIG_CONN_ENGINE" + case 238: // "CONFIG_SEC_ARGUMENT_SEPARATOR" + case 239: // "CONFIG_SEC_WEB_APP_ID" + case 240: // "CONFIG_SEC_SERVER_SIG" + case 241: // "CONFIG_DIR_AUDIT_DIR" + case 242: // "CONFIG_DIR_AUDIT_DIR_MOD" + case 243: // "CONFIG_DIR_AUDIT_ENG" + case 244: // "CONFIG_DIR_AUDIT_FLE_MOD" + case 245: // "CONFIG_DIR_AUDIT_LOG" + case 246: // "CONFIG_DIR_AUDIT_LOG2" + case 247: // "CONFIG_DIR_AUDIT_LOG_P" + case 248: // "CONFIG_DIR_AUDIT_STS" + case 249: // "CONFIG_DIR_AUDIT_TPE" + case 250: // "CONFIG_DIR_DEBUG_LOG" + case 251: // "CONFIG_DIR_DEBUG_LVL" + case 252: // "CONFIG_SEC_CACHE_TRANSFORMATIONS" + case 253: // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" + case 254: // "CONFIG_SEC_HASH_ENGINE" + case 255: // "CONFIG_SEC_HASH_KEY" + case 256: // "CONFIG_SEC_HASH_PARAM" + case 257: // "CONFIG_SEC_HASH_METHOD_RX" + case 258: // "CONFIG_SEC_HASH_METHOD_PM" + case 259: // "CONFIG_SEC_CHROOT_DIR" + case 260: // "CONFIG_DIR_GEO_DB" + case 261: // "CONFIG_DIR_GSB_DB" + case 262: // "CONFIG_SEC_GUARDIAN_LOG" + case 263: // "CONFIG_DIR_PCRE_MATCH_LIMIT" + case 264: // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" + case 265: // "CONFIG_SEC_CONN_R_STATE_LIMIT" + case 266: // "CONFIG_SEC_CONN_W_STATE_LIMIT" + case 267: // "CONFIG_SEC_SENSOR_ID" + case 268: // "CONFIG_DIR_ARGS_LIMIT" + case 269: // "CONFIG_DIR_REQ_BODY" + case 270: // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" + case 271: // "CONFIG_DIR_REQ_BODY_LIMIT" + case 272: // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" + case 273: // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" + case 274: // "CONFIG_DIR_RES_BODY" + case 275: // "CONFIG_DIR_RES_BODY_LIMIT" + case 276: // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" + case 277: // "CONFIG_SEC_RULE_INHERITANCE" + case 278: // "CONFIG_SEC_RULE_PERF_TIME" + case 279: // "CONFIG_DIR_RULE_ENG" + case 280: // "CONFIG_DIR_SEC_ACTION" + case 281: // "CONFIG_DIR_SEC_DEFAULT_ACTION" + case 282: // "CONFIG_DIR_SEC_MARKER" + case 283: // "CONFIG_DIR_UNICODE_MAP_FILE" + case 284: // "CONFIG_DIR_UNICODE_CODE_PAGE" + case 285: // "CONFIG_SEC_COLLECTION_TIMEOUT" + case 286: // "CONFIG_SEC_HTTP_BLKEY" + case 287: // "CONFIG_SEC_INTERCEPT_ON_ERROR" + case 288: // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" + case 289: // "CONFIG_SEC_RULE_REMOVE_BY_ID" + case 290: // "CONFIG_SEC_RULE_REMOVE_BY_MSG" + case 291: // "CONFIG_SEC_RULE_REMOVE_BY_TAG" + case 292: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" + case 293: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" + case 294: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" + case 295: // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" + case 296: // "CONFIG_UPDLOAD_KEEP_FILES" + case 297: // "CONFIG_UPDLOAD_SAVE_TMP_FILES" + case 298: // "CONFIG_UPLOAD_DIR" + case 299: // "CONFIG_UPLOAD_FILE_LIMIT" + case 300: // "CONFIG_UPLOAD_FILE_MODE" + case 301: // "CONFIG_VALUE_ABORT" + case 302: // "CONFIG_VALUE_DETC" + case 303: // "CONFIG_VALUE_HTTPS" + case 304: // "CONFIG_VALUE_OFF" + case 305: // "CONFIG_VALUE_ON" + case 306: // "CONFIG_VALUE_PARALLEL" + case 307: // "CONFIG_VALUE_PROCESS_PARTIAL" + case 308: // "CONFIG_VALUE_REJECT" + case 309: // "CONFIG_VALUE_RELEVANT_ONLY" + case 310: // "CONFIG_VALUE_SERIAL" + case 311: // "CONFIG_VALUE_WARN" + case 312: // "CONFIG_XML_EXTERNAL_ENTITY" + case 313: // "CONGIG_DIR_RESPONSE_BODY_MP" + case 314: // "CONGIG_DIR_SEC_ARG_SEP" + case 315: // "CONGIG_DIR_SEC_COOKIE_FORMAT" + case 316: // "CONFIG_SEC_COOKIEV0_SEPARATOR" + case 317: // "CONGIG_DIR_SEC_DATA_DIR" + case 318: // "CONGIG_DIR_SEC_STATUS_ENGINE" + case 319: // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" + case 320: // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" + case 321: // "CONGIG_DIR_SEC_TMP_DIR" + case 322: // "DIRECTIVE" + case 323: // "DIRECTIVE_SECRULESCRIPT" + case 324: // "FREE_TEXT_QUOTE_MACRO_EXPANSION" + case 325: // "QUOTATION_MARK" + case 326: // "RUN_TIME_VAR_BLD" + case 327: // "RUN_TIME_VAR_DUR" + case 328: // "RUN_TIME_VAR_HSV" + case 329: // "RUN_TIME_VAR_REMOTE_USER" + case 330: // "RUN_TIME_VAR_TIME" + case 331: // "RUN_TIME_VAR_TIME_DAY" + case 332: // "RUN_TIME_VAR_TIME_EPOCH" + case 333: // "RUN_TIME_VAR_TIME_HOUR" + case 334: // "RUN_TIME_VAR_TIME_MIN" + case 335: // "RUN_TIME_VAR_TIME_MON" + case 336: // "RUN_TIME_VAR_TIME_SEC" + case 337: // "RUN_TIME_VAR_TIME_WDAY" + case 338: // "RUN_TIME_VAR_TIME_YEAR" + case 339: // "VARIABLE" + case 340: // "Dictionary element" + case 341: // "Dictionary element, selected by regexp" + value.move< std::string > (std::move (that.value)); + break; + + case 348: // op + case 349: // op_before_init + value.move< std::unique_ptr > (std::move (that.value)); + break; + + case 357: // run_time_string + value.move< std::unique_ptr > (std::move (that.value)); + break; + + case 354: // var + value.move< std::unique_ptr > (std::move (that.value)); + break; + + case 355: // act + case 356: // setvar_action + value.move< std::unique_ptr > (std::move (that.value)); + break; + + case 351: // variables + case 352: // variables_pre_process + case 353: // variables_may_be_quoted + value.move< std::unique_ptr > > > (std::move (that.value)); + break; + + case 346: // actions + case 347: // actions_may_quoted + value.move< std::unique_ptr > > > (std::move (that.value)); + break; + + default: + break; + } + + } #endif /// Copy constructor. @@ -1449,17 +2076,17 @@ namespace yy { void clear () { // User destructor. - symbol_number_type yytype = this->type_get (); + symbol_kind_type yykind = this->kind (); basic_symbol& yysym = *this; (void) yysym; - switch (yytype) + switch (yykind) { default: break; } - // Type destructor. -switch (yytype) + // Value type destructor. +switch (yykind) { case 145: // "Accuracy" case 146: // "Allow" @@ -1697,6 +2324,15 @@ switch (yytype) Base::clear (); } + /// The user-facing name of this symbol. + std::string name () const YY_NOEXCEPT + { + return seclang_parser::symbol_name (this->kind ()); + } + + /// Backward compatibility (Bison 3.6). + symbol_kind_type type_get () const YY_NOEXCEPT; + /// Whether empty. bool empty () const YY_NOEXCEPT; @@ -1717,46 +2353,51 @@ switch (yytype) }; /// Type access provider for token (enum) based symbols. - struct by_type + struct by_kind { /// Default constructor. - by_type (); + by_kind (); #if 201103L <= YY_CPLUSPLUS /// Move constructor. - by_type (by_type&& that); + by_kind (by_kind&& that); #endif /// Copy constructor. - by_type (const by_type& that); + by_kind (const by_kind& that); - /// The symbol type as needed by the constructor. - typedef token_type kind_type; + /// The symbol kind as needed by the constructor. + typedef token_kind_type kind_type; /// Constructor from (external) token numbers. - by_type (kind_type t); + by_kind (kind_type t); /// Record that this symbol is empty. void clear (); - /// Steal the symbol type from \a that. - void move (by_type& that); + /// Steal the symbol kind from \a that. + void move (by_kind& that); /// The (internal) type number (corresponding to \a type). /// \a empty when empty. - symbol_number_type type_get () const YY_NOEXCEPT; + symbol_kind_type kind () const YY_NOEXCEPT; + + /// Backward compatibility (Bison 3.6). + symbol_kind_type type_get () const YY_NOEXCEPT; - /// The symbol type. - /// \a empty_symbol when empty. - /// An int, not token_number_type, to be able to store empty_symbol. - int type; + /// The symbol kind. + /// \a S_YYEMPTY when empty. + symbol_kind_type kind_; }; + /// Backward compatibility for a private implementation detail (Bison 3.6). + typedef by_kind by_type; + /// "External" symbols: returned by the scanner. - struct symbol_type : basic_symbol + struct symbol_type : basic_symbol { /// Superclass. - typedef basic_symbol super_type; + typedef basic_symbol super_type; /// Empty symbol. symbol_type () {} @@ -1766,13 +2407,13 @@ switch (yytype) symbol_type (int tok, location_type l) : super_type(token_type (tok), std::move (l)) { - YY_ASSERT (tok == token::TOK_END || tok == token::TOK_COMMA || tok == token::TOK_CONFIG_CONTENT_INJECTION || tok == token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR || tok == token::TOK_PIPE || tok == token::TOK_NEW_LINE || tok == token::TOK_VAR_COUNT || tok == token::TOK_VAR_EXCLUSION || tok == token::TOK_VARIABLE_ARGS || tok == token::TOK_VARIABLE_ARGS_POST || tok == token::TOK_VARIABLE_ARGS_GET || tok == token::TOK_VARIABLE_FILES_SIZES || tok == token::TOK_VARIABLE_FILES_NAMES || tok == token::TOK_VARIABLE_FILES_TMP_CONTENT || tok == token::TOK_VARIABLE_MULTIPART_FILENAME || tok == token::TOK_VARIABLE_MULTIPART_NAME || tok == token::TOK_VARIABLE_MATCHED_VARS_NAMES || tok == token::TOK_VARIABLE_MATCHED_VARS || tok == token::TOK_VARIABLE_FILES || tok == token::TOK_VARIABLE_REQUEST_COOKIES || tok == token::TOK_VARIABLE_REQUEST_HEADERS || tok == token::TOK_VARIABLE_RESPONSE_HEADERS || tok == token::TOK_VARIABLE_GEO || tok == token::TOK_VARIABLE_REQUEST_COOKIES_NAMES || tok == token::TOK_VARIABLE_ARGS_COMBINED_SIZE || tok == token::TOK_VARIABLE_ARGS_GET_NAMES || tok == token::TOK_VARIABLE_RULE || tok == token::TOK_VARIABLE_ARGS_NAMES || tok == token::TOK_VARIABLE_ARGS_POST_NAMES || tok == token::TOK_VARIABLE_AUTH_TYPE || tok == token::TOK_VARIABLE_FILES_COMBINED_SIZE || tok == token::TOK_VARIABLE_FILES_TMP_NAMES || tok == token::TOK_VARIABLE_FULL_REQUEST || tok == token::TOK_VARIABLE_FULL_REQUEST_LENGTH || tok == token::TOK_VARIABLE_INBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_MATCHED_VAR || tok == token::TOK_VARIABLE_MATCHED_VAR_NAME || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE || tok == token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES || tok == token::TOK_VARIABLE_MULTIPART_DATA_AFTER || tok == token::TOK_VARIABLE_MULTIPART_DATA_BEFORE || tok == token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED || tok == token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_PART || tok == token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING || tok == token::TOK_VARIABLE_MULTIPART_LF_LINE || tok == token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON || tok == token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING || tok == token::TOK_VARIABLE_MULTIPART_STRICT_ERROR || tok == token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY || tok == token::TOK_VARIABLE_OUTBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_PATH_INFO || tok == token::TOK_VARIABLE_QUERY_STRING || tok == token::TOK_VARIABLE_REMOTE_ADDR || tok == token::TOK_VARIABLE_REMOTE_HOST || tok == token::TOK_VARIABLE_REMOTE_PORT || tok == token::TOK_VARIABLE_REQBODY_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR || tok == token::TOK_VARIABLE_REQUEST_BASENAME || tok == token::TOK_VARIABLE_REQUEST_BODY_LENGTH || tok == token::TOK_VARIABLE_REQUEST_BODY || tok == token::TOK_VARIABLE_REQUEST_FILE_NAME || tok == token::TOK_VARIABLE_REQUEST_HEADERS_NAMES || tok == token::TOK_VARIABLE_REQUEST_LINE || tok == token::TOK_VARIABLE_REQUEST_METHOD || tok == token::TOK_VARIABLE_REQUEST_PROTOCOL || tok == token::TOK_VARIABLE_REQUEST_URI_RAW || tok == token::TOK_VARIABLE_REQUEST_URI || tok == token::TOK_VARIABLE_RESOURCE || tok == token::TOK_VARIABLE_RESPONSE_BODY || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE || tok == token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES || tok == token::TOK_VARIABLE_RESPONSE_PROTOCOL || tok == token::TOK_VARIABLE_RESPONSE_STATUS || tok == token::TOK_VARIABLE_SERVER_ADDR || tok == token::TOK_VARIABLE_SERVER_NAME || tok == token::TOK_VARIABLE_SERVER_PORT || tok == token::TOK_VARIABLE_SESSION_ID || tok == token::TOK_VARIABLE_UNIQUE_ID || tok == token::TOK_VARIABLE_URL_ENCODED_ERROR || tok == token::TOK_VARIABLE_USER_ID || tok == token::TOK_VARIABLE_WEB_APP_ID || tok == token::TOK_VARIABLE_STATUS || tok == token::TOK_VARIABLE_STATUS_LINE || tok == token::TOK_VARIABLE_IP || tok == token::TOK_VARIABLE_GLOBAL || tok == token::TOK_VARIABLE_TX || tok == token::TOK_VARIABLE_SESSION || tok == token::TOK_VARIABLE_USER || tok == token::TOK_RUN_TIME_VAR_ENV || tok == token::TOK_RUN_TIME_VAR_XML || tok == token::TOK_ACTION_SETVAR || tok == token::TOK_SETVAR_OPERATION_EQUALS || tok == token::TOK_SETVAR_OPERATION_EQUALS_PLUS || tok == token::TOK_SETVAR_OPERATION_EQUALS_MINUS || tok == token::TOK_NOT || tok == token::TOK_OPERATOR_BEGINS_WITH || tok == token::TOK_OPERATOR_CONTAINS || tok == token::TOK_OPERATOR_CONTAINS_WORD || tok == token::TOK_OPERATOR_DETECT_SQLI || tok == token::TOK_OPERATOR_DETECT_XSS || tok == token::TOK_OPERATOR_ENDS_WITH || tok == token::TOK_OPERATOR_EQ || tok == token::TOK_OPERATOR_FUZZY_HASH || tok == token::TOK_OPERATOR_GEOLOOKUP || tok == token::TOK_OPERATOR_GE || tok == token::TOK_OPERATOR_GSB_LOOKUP || tok == token::TOK_OPERATOR_GT || tok == token::TOK_OPERATOR_INSPECT_FILE || tok == token::TOK_OPERATOR_IP_MATCH_FROM_FILE || tok == token::TOK_OPERATOR_IP_MATCH || tok == token::TOK_OPERATOR_LE || tok == token::TOK_OPERATOR_LT || tok == token::TOK_OPERATOR_PM_FROM_FILE || tok == token::TOK_OPERATOR_PM || tok == token::TOK_OPERATOR_RBL || tok == token::TOK_OPERATOR_RSUB || tok == token::TOK_OPERATOR_RX_CONTENT_ONLY || tok == token::TOK_OPERATOR_RX || tok == token::TOK_OPERATOR_STR_EQ || tok == token::TOK_OPERATOR_STR_MATCH || tok == token::TOK_OPERATOR_UNCONDITIONAL_MATCH || tok == token::TOK_OPERATOR_VALIDATE_BYTE_RANGE || tok == token::TOK_OPERATOR_VALIDATE_DTD || tok == token::TOK_OPERATOR_VALIDATE_HASH || tok == token::TOK_OPERATOR_VALIDATE_SCHEMA || tok == token::TOK_OPERATOR_VALIDATE_URL_ENCODING || tok == token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING || tok == token::TOK_OPERATOR_VERIFY_CC || tok == token::TOK_OPERATOR_VERIFY_CPF || tok == token::TOK_OPERATOR_VERIFY_SSN || tok == token::TOK_OPERATOR_VERIFY_SVNR || tok == token::TOK_OPERATOR_WITHIN || tok == token::TOK_CONFIG_DIR_AUDIT_LOG_FMT || tok == token::TOK_JSON || tok == token::TOK_NATIVE || tok == token::TOK_ACTION_CTL_RULE_ENGINE); + YY_ASSERT (tok == token::TOK_END || tok == token::TOK_YYerror || tok == token::TOK_YYUNDEF || tok == token::TOK_COMMA || tok == token::TOK_CONFIG_CONTENT_INJECTION || tok == token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR || tok == token::TOK_PIPE || tok == token::TOK_NEW_LINE || tok == token::TOK_VAR_COUNT || tok == token::TOK_VAR_EXCLUSION || tok == token::TOK_VARIABLE_ARGS || tok == token::TOK_VARIABLE_ARGS_POST || tok == token::TOK_VARIABLE_ARGS_GET || tok == token::TOK_VARIABLE_FILES_SIZES || tok == token::TOK_VARIABLE_FILES_NAMES || tok == token::TOK_VARIABLE_FILES_TMP_CONTENT || tok == token::TOK_VARIABLE_MULTIPART_FILENAME || tok == token::TOK_VARIABLE_MULTIPART_NAME || tok == token::TOK_VARIABLE_MATCHED_VARS_NAMES || tok == token::TOK_VARIABLE_MATCHED_VARS || tok == token::TOK_VARIABLE_FILES || tok == token::TOK_VARIABLE_REQUEST_COOKIES || tok == token::TOK_VARIABLE_REQUEST_HEADERS || tok == token::TOK_VARIABLE_RESPONSE_HEADERS || tok == token::TOK_VARIABLE_GEO || tok == token::TOK_VARIABLE_REQUEST_COOKIES_NAMES || tok == token::TOK_VARIABLE_ARGS_COMBINED_SIZE || tok == token::TOK_VARIABLE_ARGS_GET_NAMES || tok == token::TOK_VARIABLE_RULE || tok == token::TOK_VARIABLE_ARGS_NAMES || tok == token::TOK_VARIABLE_ARGS_POST_NAMES || tok == token::TOK_VARIABLE_AUTH_TYPE || tok == token::TOK_VARIABLE_FILES_COMBINED_SIZE || tok == token::TOK_VARIABLE_FILES_TMP_NAMES || tok == token::TOK_VARIABLE_FULL_REQUEST || tok == token::TOK_VARIABLE_FULL_REQUEST_LENGTH || tok == token::TOK_VARIABLE_INBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_MATCHED_VAR || tok == token::TOK_VARIABLE_MATCHED_VAR_NAME || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE || tok == token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES || tok == token::TOK_VARIABLE_MULTIPART_DATA_AFTER || tok == token::TOK_VARIABLE_MULTIPART_DATA_BEFORE || tok == token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED || tok == token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_PART || tok == token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING || tok == token::TOK_VARIABLE_MULTIPART_LF_LINE || tok == token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON || tok == token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING || tok == token::TOK_VARIABLE_MULTIPART_STRICT_ERROR || tok == token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY || tok == token::TOK_VARIABLE_OUTBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_PATH_INFO || tok == token::TOK_VARIABLE_QUERY_STRING || tok == token::TOK_VARIABLE_REMOTE_ADDR || tok == token::TOK_VARIABLE_REMOTE_HOST || tok == token::TOK_VARIABLE_REMOTE_PORT || tok == token::TOK_VARIABLE_REQBODY_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR || tok == token::TOK_VARIABLE_REQUEST_BASENAME || tok == token::TOK_VARIABLE_REQUEST_BODY_LENGTH || tok == token::TOK_VARIABLE_REQUEST_BODY || tok == token::TOK_VARIABLE_REQUEST_FILE_NAME || tok == token::TOK_VARIABLE_REQUEST_HEADERS_NAMES || tok == token::TOK_VARIABLE_REQUEST_LINE || tok == token::TOK_VARIABLE_REQUEST_METHOD || tok == token::TOK_VARIABLE_REQUEST_PROTOCOL || tok == token::TOK_VARIABLE_REQUEST_URI_RAW || tok == token::TOK_VARIABLE_REQUEST_URI || tok == token::TOK_VARIABLE_RESOURCE || tok == token::TOK_VARIABLE_RESPONSE_BODY || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE || tok == token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES || tok == token::TOK_VARIABLE_RESPONSE_PROTOCOL || tok == token::TOK_VARIABLE_RESPONSE_STATUS || tok == token::TOK_VARIABLE_SERVER_ADDR || tok == token::TOK_VARIABLE_SERVER_NAME || tok == token::TOK_VARIABLE_SERVER_PORT || tok == token::TOK_VARIABLE_SESSION_ID || tok == token::TOK_VARIABLE_UNIQUE_ID || tok == token::TOK_VARIABLE_URL_ENCODED_ERROR || tok == token::TOK_VARIABLE_USER_ID || tok == token::TOK_VARIABLE_WEB_APP_ID || tok == token::TOK_VARIABLE_STATUS || tok == token::TOK_VARIABLE_STATUS_LINE || tok == token::TOK_VARIABLE_IP || tok == token::TOK_VARIABLE_GLOBAL || tok == token::TOK_VARIABLE_TX || tok == token::TOK_VARIABLE_SESSION || tok == token::TOK_VARIABLE_USER || tok == token::TOK_RUN_TIME_VAR_ENV || tok == token::TOK_RUN_TIME_VAR_XML || tok == token::TOK_ACTION_SETVAR || tok == token::TOK_SETVAR_OPERATION_EQUALS || tok == token::TOK_SETVAR_OPERATION_EQUALS_PLUS || tok == token::TOK_SETVAR_OPERATION_EQUALS_MINUS || tok == token::TOK_NOT || tok == token::TOK_OPERATOR_BEGINS_WITH || tok == token::TOK_OPERATOR_CONTAINS || tok == token::TOK_OPERATOR_CONTAINS_WORD || tok == token::TOK_OPERATOR_DETECT_SQLI || tok == token::TOK_OPERATOR_DETECT_XSS || tok == token::TOK_OPERATOR_ENDS_WITH || tok == token::TOK_OPERATOR_EQ || tok == token::TOK_OPERATOR_FUZZY_HASH || tok == token::TOK_OPERATOR_GEOLOOKUP || tok == token::TOK_OPERATOR_GE || tok == token::TOK_OPERATOR_GSB_LOOKUP || tok == token::TOK_OPERATOR_GT || tok == token::TOK_OPERATOR_INSPECT_FILE || tok == token::TOK_OPERATOR_IP_MATCH_FROM_FILE || tok == token::TOK_OPERATOR_IP_MATCH || tok == token::TOK_OPERATOR_LE || tok == token::TOK_OPERATOR_LT || tok == token::TOK_OPERATOR_PM_FROM_FILE || tok == token::TOK_OPERATOR_PM || tok == token::TOK_OPERATOR_RBL || tok == token::TOK_OPERATOR_RSUB || tok == token::TOK_OPERATOR_RX_CONTENT_ONLY || tok == token::TOK_OPERATOR_RX || tok == token::TOK_OPERATOR_STR_EQ || tok == token::TOK_OPERATOR_STR_MATCH || tok == token::TOK_OPERATOR_UNCONDITIONAL_MATCH || tok == token::TOK_OPERATOR_VALIDATE_BYTE_RANGE || tok == token::TOK_OPERATOR_VALIDATE_DTD || tok == token::TOK_OPERATOR_VALIDATE_HASH || tok == token::TOK_OPERATOR_VALIDATE_SCHEMA || tok == token::TOK_OPERATOR_VALIDATE_URL_ENCODING || tok == token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING || tok == token::TOK_OPERATOR_VERIFY_CC || tok == token::TOK_OPERATOR_VERIFY_CPF || tok == token::TOK_OPERATOR_VERIFY_SSN || tok == token::TOK_OPERATOR_VERIFY_SVNR || tok == token::TOK_OPERATOR_WITHIN || tok == token::TOK_CONFIG_DIR_AUDIT_LOG_FMT || tok == token::TOK_JSON || tok == token::TOK_NATIVE || tok == token::TOK_ACTION_CTL_RULE_ENGINE); } #else symbol_type (int tok, const location_type& l) : super_type(token_type (tok), l) { - YY_ASSERT (tok == token::TOK_END || tok == token::TOK_COMMA || tok == token::TOK_CONFIG_CONTENT_INJECTION || tok == token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR || tok == token::TOK_PIPE || tok == token::TOK_NEW_LINE || tok == token::TOK_VAR_COUNT || tok == token::TOK_VAR_EXCLUSION || tok == token::TOK_VARIABLE_ARGS || tok == token::TOK_VARIABLE_ARGS_POST || tok == token::TOK_VARIABLE_ARGS_GET || tok == token::TOK_VARIABLE_FILES_SIZES || tok == token::TOK_VARIABLE_FILES_NAMES || tok == token::TOK_VARIABLE_FILES_TMP_CONTENT || tok == token::TOK_VARIABLE_MULTIPART_FILENAME || tok == token::TOK_VARIABLE_MULTIPART_NAME || tok == token::TOK_VARIABLE_MATCHED_VARS_NAMES || tok == token::TOK_VARIABLE_MATCHED_VARS || tok == token::TOK_VARIABLE_FILES || tok == token::TOK_VARIABLE_REQUEST_COOKIES || tok == token::TOK_VARIABLE_REQUEST_HEADERS || tok == token::TOK_VARIABLE_RESPONSE_HEADERS || tok == token::TOK_VARIABLE_GEO || tok == token::TOK_VARIABLE_REQUEST_COOKIES_NAMES || tok == token::TOK_VARIABLE_ARGS_COMBINED_SIZE || tok == token::TOK_VARIABLE_ARGS_GET_NAMES || tok == token::TOK_VARIABLE_RULE || tok == token::TOK_VARIABLE_ARGS_NAMES || tok == token::TOK_VARIABLE_ARGS_POST_NAMES || tok == token::TOK_VARIABLE_AUTH_TYPE || tok == token::TOK_VARIABLE_FILES_COMBINED_SIZE || tok == token::TOK_VARIABLE_FILES_TMP_NAMES || tok == token::TOK_VARIABLE_FULL_REQUEST || tok == token::TOK_VARIABLE_FULL_REQUEST_LENGTH || tok == token::TOK_VARIABLE_INBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_MATCHED_VAR || tok == token::TOK_VARIABLE_MATCHED_VAR_NAME || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE || tok == token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES || tok == token::TOK_VARIABLE_MULTIPART_DATA_AFTER || tok == token::TOK_VARIABLE_MULTIPART_DATA_BEFORE || tok == token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED || tok == token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_PART || tok == token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING || tok == token::TOK_VARIABLE_MULTIPART_LF_LINE || tok == token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON || tok == token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING || tok == token::TOK_VARIABLE_MULTIPART_STRICT_ERROR || tok == token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY || tok == token::TOK_VARIABLE_OUTBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_PATH_INFO || tok == token::TOK_VARIABLE_QUERY_STRING || tok == token::TOK_VARIABLE_REMOTE_ADDR || tok == token::TOK_VARIABLE_REMOTE_HOST || tok == token::TOK_VARIABLE_REMOTE_PORT || tok == token::TOK_VARIABLE_REQBODY_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR || tok == token::TOK_VARIABLE_REQUEST_BASENAME || tok == token::TOK_VARIABLE_REQUEST_BODY_LENGTH || tok == token::TOK_VARIABLE_REQUEST_BODY || tok == token::TOK_VARIABLE_REQUEST_FILE_NAME || tok == token::TOK_VARIABLE_REQUEST_HEADERS_NAMES || tok == token::TOK_VARIABLE_REQUEST_LINE || tok == token::TOK_VARIABLE_REQUEST_METHOD || tok == token::TOK_VARIABLE_REQUEST_PROTOCOL || tok == token::TOK_VARIABLE_REQUEST_URI_RAW || tok == token::TOK_VARIABLE_REQUEST_URI || tok == token::TOK_VARIABLE_RESOURCE || tok == token::TOK_VARIABLE_RESPONSE_BODY || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE || tok == token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES || tok == token::TOK_VARIABLE_RESPONSE_PROTOCOL || tok == token::TOK_VARIABLE_RESPONSE_STATUS || tok == token::TOK_VARIABLE_SERVER_ADDR || tok == token::TOK_VARIABLE_SERVER_NAME || tok == token::TOK_VARIABLE_SERVER_PORT || tok == token::TOK_VARIABLE_SESSION_ID || tok == token::TOK_VARIABLE_UNIQUE_ID || tok == token::TOK_VARIABLE_URL_ENCODED_ERROR || tok == token::TOK_VARIABLE_USER_ID || tok == token::TOK_VARIABLE_WEB_APP_ID || tok == token::TOK_VARIABLE_STATUS || tok == token::TOK_VARIABLE_STATUS_LINE || tok == token::TOK_VARIABLE_IP || tok == token::TOK_VARIABLE_GLOBAL || tok == token::TOK_VARIABLE_TX || tok == token::TOK_VARIABLE_SESSION || tok == token::TOK_VARIABLE_USER || tok == token::TOK_RUN_TIME_VAR_ENV || tok == token::TOK_RUN_TIME_VAR_XML || tok == token::TOK_ACTION_SETVAR || tok == token::TOK_SETVAR_OPERATION_EQUALS || tok == token::TOK_SETVAR_OPERATION_EQUALS_PLUS || tok == token::TOK_SETVAR_OPERATION_EQUALS_MINUS || tok == token::TOK_NOT || tok == token::TOK_OPERATOR_BEGINS_WITH || tok == token::TOK_OPERATOR_CONTAINS || tok == token::TOK_OPERATOR_CONTAINS_WORD || tok == token::TOK_OPERATOR_DETECT_SQLI || tok == token::TOK_OPERATOR_DETECT_XSS || tok == token::TOK_OPERATOR_ENDS_WITH || tok == token::TOK_OPERATOR_EQ || tok == token::TOK_OPERATOR_FUZZY_HASH || tok == token::TOK_OPERATOR_GEOLOOKUP || tok == token::TOK_OPERATOR_GE || tok == token::TOK_OPERATOR_GSB_LOOKUP || tok == token::TOK_OPERATOR_GT || tok == token::TOK_OPERATOR_INSPECT_FILE || tok == token::TOK_OPERATOR_IP_MATCH_FROM_FILE || tok == token::TOK_OPERATOR_IP_MATCH || tok == token::TOK_OPERATOR_LE || tok == token::TOK_OPERATOR_LT || tok == token::TOK_OPERATOR_PM_FROM_FILE || tok == token::TOK_OPERATOR_PM || tok == token::TOK_OPERATOR_RBL || tok == token::TOK_OPERATOR_RSUB || tok == token::TOK_OPERATOR_RX_CONTENT_ONLY || tok == token::TOK_OPERATOR_RX || tok == token::TOK_OPERATOR_STR_EQ || tok == token::TOK_OPERATOR_STR_MATCH || tok == token::TOK_OPERATOR_UNCONDITIONAL_MATCH || tok == token::TOK_OPERATOR_VALIDATE_BYTE_RANGE || tok == token::TOK_OPERATOR_VALIDATE_DTD || tok == token::TOK_OPERATOR_VALIDATE_HASH || tok == token::TOK_OPERATOR_VALIDATE_SCHEMA || tok == token::TOK_OPERATOR_VALIDATE_URL_ENCODING || tok == token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING || tok == token::TOK_OPERATOR_VERIFY_CC || tok == token::TOK_OPERATOR_VERIFY_CPF || tok == token::TOK_OPERATOR_VERIFY_SSN || tok == token::TOK_OPERATOR_VERIFY_SVNR || tok == token::TOK_OPERATOR_WITHIN || tok == token::TOK_CONFIG_DIR_AUDIT_LOG_FMT || tok == token::TOK_JSON || tok == token::TOK_NATIVE || tok == token::TOK_ACTION_CTL_RULE_ENGINE); + YY_ASSERT (tok == token::TOK_END || tok == token::TOK_YYerror || tok == token::TOK_YYUNDEF || tok == token::TOK_COMMA || tok == token::TOK_CONFIG_CONTENT_INJECTION || tok == token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR || tok == token::TOK_PIPE || tok == token::TOK_NEW_LINE || tok == token::TOK_VAR_COUNT || tok == token::TOK_VAR_EXCLUSION || tok == token::TOK_VARIABLE_ARGS || tok == token::TOK_VARIABLE_ARGS_POST || tok == token::TOK_VARIABLE_ARGS_GET || tok == token::TOK_VARIABLE_FILES_SIZES || tok == token::TOK_VARIABLE_FILES_NAMES || tok == token::TOK_VARIABLE_FILES_TMP_CONTENT || tok == token::TOK_VARIABLE_MULTIPART_FILENAME || tok == token::TOK_VARIABLE_MULTIPART_NAME || tok == token::TOK_VARIABLE_MATCHED_VARS_NAMES || tok == token::TOK_VARIABLE_MATCHED_VARS || tok == token::TOK_VARIABLE_FILES || tok == token::TOK_VARIABLE_REQUEST_COOKIES || tok == token::TOK_VARIABLE_REQUEST_HEADERS || tok == token::TOK_VARIABLE_RESPONSE_HEADERS || tok == token::TOK_VARIABLE_GEO || tok == token::TOK_VARIABLE_REQUEST_COOKIES_NAMES || tok == token::TOK_VARIABLE_ARGS_COMBINED_SIZE || tok == token::TOK_VARIABLE_ARGS_GET_NAMES || tok == token::TOK_VARIABLE_RULE || tok == token::TOK_VARIABLE_ARGS_NAMES || tok == token::TOK_VARIABLE_ARGS_POST_NAMES || tok == token::TOK_VARIABLE_AUTH_TYPE || tok == token::TOK_VARIABLE_FILES_COMBINED_SIZE || tok == token::TOK_VARIABLE_FILES_TMP_NAMES || tok == token::TOK_VARIABLE_FULL_REQUEST || tok == token::TOK_VARIABLE_FULL_REQUEST_LENGTH || tok == token::TOK_VARIABLE_INBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_MATCHED_VAR || tok == token::TOK_VARIABLE_MATCHED_VAR_NAME || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED || tok == token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE || tok == token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES || tok == token::TOK_VARIABLE_MULTIPART_DATA_AFTER || tok == token::TOK_VARIABLE_MULTIPART_DATA_BEFORE || tok == token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED || tok == token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING || tok == token::TOK_VARIABLE_MULTIPART_INVALID_PART || tok == token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING || tok == token::TOK_VARIABLE_MULTIPART_LF_LINE || tok == token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON || tok == token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING || tok == token::TOK_VARIABLE_MULTIPART_STRICT_ERROR || tok == token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY || tok == token::TOK_VARIABLE_OUTBOUND_DATA_ERROR || tok == token::TOK_VARIABLE_PATH_INFO || tok == token::TOK_VARIABLE_QUERY_STRING || tok == token::TOK_VARIABLE_REMOTE_ADDR || tok == token::TOK_VARIABLE_REMOTE_HOST || tok == token::TOK_VARIABLE_REMOTE_PORT || tok == token::TOK_VARIABLE_REQBODY_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR || tok == token::TOK_VARIABLE_REQBODY_PROCESSOR || tok == token::TOK_VARIABLE_REQUEST_BASENAME || tok == token::TOK_VARIABLE_REQUEST_BODY_LENGTH || tok == token::TOK_VARIABLE_REQUEST_BODY || tok == token::TOK_VARIABLE_REQUEST_FILE_NAME || tok == token::TOK_VARIABLE_REQUEST_HEADERS_NAMES || tok == token::TOK_VARIABLE_REQUEST_LINE || tok == token::TOK_VARIABLE_REQUEST_METHOD || tok == token::TOK_VARIABLE_REQUEST_PROTOCOL || tok == token::TOK_VARIABLE_REQUEST_URI_RAW || tok == token::TOK_VARIABLE_REQUEST_URI || tok == token::TOK_VARIABLE_RESOURCE || tok == token::TOK_VARIABLE_RESPONSE_BODY || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH || tok == token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE || tok == token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES || tok == token::TOK_VARIABLE_RESPONSE_PROTOCOL || tok == token::TOK_VARIABLE_RESPONSE_STATUS || tok == token::TOK_VARIABLE_SERVER_ADDR || tok == token::TOK_VARIABLE_SERVER_NAME || tok == token::TOK_VARIABLE_SERVER_PORT || tok == token::TOK_VARIABLE_SESSION_ID || tok == token::TOK_VARIABLE_UNIQUE_ID || tok == token::TOK_VARIABLE_URL_ENCODED_ERROR || tok == token::TOK_VARIABLE_USER_ID || tok == token::TOK_VARIABLE_WEB_APP_ID || tok == token::TOK_VARIABLE_STATUS || tok == token::TOK_VARIABLE_STATUS_LINE || tok == token::TOK_VARIABLE_IP || tok == token::TOK_VARIABLE_GLOBAL || tok == token::TOK_VARIABLE_TX || tok == token::TOK_VARIABLE_SESSION || tok == token::TOK_VARIABLE_USER || tok == token::TOK_RUN_TIME_VAR_ENV || tok == token::TOK_RUN_TIME_VAR_XML || tok == token::TOK_ACTION_SETVAR || tok == token::TOK_SETVAR_OPERATION_EQUALS || tok == token::TOK_SETVAR_OPERATION_EQUALS_PLUS || tok == token::TOK_SETVAR_OPERATION_EQUALS_MINUS || tok == token::TOK_NOT || tok == token::TOK_OPERATOR_BEGINS_WITH || tok == token::TOK_OPERATOR_CONTAINS || tok == token::TOK_OPERATOR_CONTAINS_WORD || tok == token::TOK_OPERATOR_DETECT_SQLI || tok == token::TOK_OPERATOR_DETECT_XSS || tok == token::TOK_OPERATOR_ENDS_WITH || tok == token::TOK_OPERATOR_EQ || tok == token::TOK_OPERATOR_FUZZY_HASH || tok == token::TOK_OPERATOR_GEOLOOKUP || tok == token::TOK_OPERATOR_GE || tok == token::TOK_OPERATOR_GSB_LOOKUP || tok == token::TOK_OPERATOR_GT || tok == token::TOK_OPERATOR_INSPECT_FILE || tok == token::TOK_OPERATOR_IP_MATCH_FROM_FILE || tok == token::TOK_OPERATOR_IP_MATCH || tok == token::TOK_OPERATOR_LE || tok == token::TOK_OPERATOR_LT || tok == token::TOK_OPERATOR_PM_FROM_FILE || tok == token::TOK_OPERATOR_PM || tok == token::TOK_OPERATOR_RBL || tok == token::TOK_OPERATOR_RSUB || tok == token::TOK_OPERATOR_RX_CONTENT_ONLY || tok == token::TOK_OPERATOR_RX || tok == token::TOK_OPERATOR_STR_EQ || tok == token::TOK_OPERATOR_STR_MATCH || tok == token::TOK_OPERATOR_UNCONDITIONAL_MATCH || tok == token::TOK_OPERATOR_VALIDATE_BYTE_RANGE || tok == token::TOK_OPERATOR_VALIDATE_DTD || tok == token::TOK_OPERATOR_VALIDATE_HASH || tok == token::TOK_OPERATOR_VALIDATE_SCHEMA || tok == token::TOK_OPERATOR_VALIDATE_URL_ENCODING || tok == token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING || tok == token::TOK_OPERATOR_VERIFY_CC || tok == token::TOK_OPERATOR_VERIFY_CPF || tok == token::TOK_OPERATOR_VERIFY_SSN || tok == token::TOK_OPERATOR_VERIFY_SVNR || tok == token::TOK_OPERATOR_WITHIN || tok == token::TOK_CONFIG_DIR_AUDIT_LOG_FMT || tok == token::TOK_JSON || tok == token::TOK_NATIVE || tok == token::TOK_ACTION_CTL_RULE_ENGINE); } #endif #if 201103L <= YY_CPLUSPLUS @@ -1794,6 +2435,13 @@ switch (yytype) seclang_parser (modsecurity::Parser::Driver& driver_yyarg); virtual ~seclang_parser (); +#if 201103L <= YY_CPLUSPLUS + /// Non copyable. + seclang_parser (const seclang_parser&) = delete; + /// Non copyable. + seclang_parser& operator= (const seclang_parser&) = delete; +#endif + /// Parse. An alias for parse (). /// \returns 0 iff parsing succeeded. int operator() (); @@ -1824,6 +2472,10 @@ switch (yytype) /// Report a syntax error. void error (const syntax_error& err); + /// The user-facing name of the symbol whose (internal) number is + /// YYSYMBOL. No bounds checking. + static std::string symbol_name (symbol_kind_type yysymbol); + // Implementation of make_symbol for each symbol type. #if 201103L <= YY_CPLUSPLUS static @@ -1840,6 +2492,36 @@ switch (yytype) return symbol_type (token::TOK_END, l); } #endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_YYerror (location_type l) + { + return symbol_type (token::TOK_YYerror, std::move (l)); + } +#else + static + symbol_type + make_YYerror (const location_type& l) + { + return symbol_type (token::TOK_YYerror, l); + } +#endif +#if 201103L <= YY_CPLUSPLUS + static + symbol_type + make_YYUNDEF (location_type l) + { + return symbol_type (token::TOK_YYUNDEF, std::move (l)); + } +#else + static + symbol_type + make_YYUNDEF (const location_type& l) + { + return symbol_type (token::TOK_YYUNDEF, l); + } +#endif #if 201103L <= YY_CPLUSPLUS static symbol_type @@ -6927,20 +7609,43 @@ switch (yytype) #endif + class context + { + public: + context (const seclang_parser& yyparser, const symbol_type& yyla); + const symbol_type& lookahead () const { return yyla_; } + symbol_kind_type token () const { return yyla_.kind (); } + const location_type& location () const { return yyla_.location; } + + /// Put in YYARG at most YYARGN of the expected tokens, and return the + /// number of tokens stored in YYARG. If YYARG is null, return the + /// number of expected tokens (guaranteed to be less than YYNTOKENS). + int expected_tokens (symbol_kind_type yyarg[], int yyargn) const; + + private: + const seclang_parser& yyparser_; + const symbol_type& yyla_; + }; + private: - /// This class is not copyable. +#if YY_CPLUSPLUS < 201103L + /// Non copyable. seclang_parser (const seclang_parser&); + /// Non copyable. seclang_parser& operator= (const seclang_parser&); +#endif + /// Stored state numbers (used for stacks). typedef short state_type; - /// Generate an error message. - /// \param yystate the state where the error occurred. - /// \param yyla the lookahead token. - virtual std::string yysyntax_error_ (state_type yystate, - const symbol_type& yyla) const; + /// The arguments of the error message. + int yy_syntax_error_arguments_ (const context& yyctx, + symbol_kind_type yyarg[], int yyargn) const; + /// Generate an error message. + /// \param yyctx the context in which the error occurred. + virtual std::string yysyntax_error_ (const context& yyctx) const; /// Compute post-reduction state. /// \param yystate the current state /// \param yysym the nonterminal to push on the stack @@ -6957,65 +7662,66 @@ switch (yytype) static const short yypact_ninf_; static const signed char yytable_ninf_; - /// Convert a scanner token number \a t to a symbol number. - /// In theory \a t should be a token_type, but character literals + /// Convert a scanner token kind \a t to a symbol kind. + /// In theory \a t should be a token_kind_type, but character literals /// are valid, yet not members of the token_type enum. - static token_number_type yytranslate_ (int t); + static symbol_kind_type yytranslate_ (int t); + + /// Convert the symbol name \a n to a form suitable for a diagnostic. + static std::string yytnamerr_ (const char *yystr); + + /// For a symbol, its name in clear. + static const char* const yytname_[]; + // Tables. - // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + // YYPACTSTATE-NUM -- Index in YYTABLE of the portion describing // STATE-NUM. static const short yypact_[]; - // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + // YYDEFACTSTATE-NUM -- Default reduction number in state STATE-NUM. // Performed when YYTABLE does not specify something else to do. Zero // means the default is an error. static const short yydefact_[]; - // YYPGOTO[NTERM-NUM]. + // YYPGOTONTERM-NUM. static const short yypgoto_[]; - // YYDEFGOTO[NTERM-NUM]. + // YYDEFGOTONTERM-NUM. static const short yydefgoto_[]; - // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + // YYTABLEYYPACT[STATE-NUM] -- What to do in state STATE-NUM. If // positive, shift that token. If negative, reduce the rule whose // number is the opposite. If YYTABLE_NINF, syntax error. static const short yytable_[]; static const short yycheck_[]; - // YYSTOS[STATE-NUM] -- The (internal number of the) accessing + // YYSTOSSTATE-NUM -- The (internal number of the) accessing // symbol of state STATE-NUM. static const short yystos_[]; - // YYR1[YYN] -- Symbol number of symbol that rule YYN derives. + // YYR1YYN -- Symbol number of symbol that rule YYN derives. static const short yyr1_[]; - // YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. + // YYR2YYN -- Number of symbols on the right hand side of rule YYN. static const signed char yyr2_[]; - /// Convert the symbol name \a n to a form suitable for a diagnostic. - static std::string yytnamerr_ (const char *n); - - - /// For a symbol, its name in clear. - static const char* const yytname_[]; #if YYDEBUG - // YYRLINE[YYN] -- Source line where rule number YYN was defined. + // YYRLINEYYN -- Source line where rule number YYN was defined. static const short yyrline_[]; /// Report on the debug stream that the rule \a r is going to be reduced. - virtual void yy_reduce_print_ (int r); + virtual void yy_reduce_print_ (int r) const; /// Print the state stack on the debug stream. - virtual void yystack_print_ (); + virtual void yy_stack_print_ () const; /// Debugging level. int yydebug_; /// Debug stream. std::ostream* yycdebug_; - /// \brief Display a symbol type, value and location. + /// \brief Display a symbol kind, value and location. /// \param yyo The output stream. /// \param yysym The symbol. template @@ -7036,7 +7742,7 @@ switch (yytype) /// Default constructor. by_state () YY_NOEXCEPT; - /// The symbol type as needed by the constructor. + /// The symbol kind as needed by the constructor. typedef state_type kind_type; /// Constructor. @@ -7048,12 +7754,12 @@ switch (yytype) /// Record that this symbol is empty. void clear () YY_NOEXCEPT; - /// Steal the symbol type from \a that. + /// Steal the symbol kind from \a that. void move (by_state& that); - /// The (internal) type number (corresponding to \a state). - /// \a empty_symbol when empty. - symbol_number_type type_get () const YY_NOEXCEPT; + /// The symbol kind (corresponding to \a state). + /// \a S_YYEMPTY when empty. + symbol_kind_type kind () const YY_NOEXCEPT; /// The state number used to denote an empty symbol. /// We use the initial state, as it does not have a value. @@ -7092,8 +7798,8 @@ switch (yytype) { public: // Hide our reversed order. - typedef typename S::reverse_iterator iterator; - typedef typename S::const_reverse_iterator const_iterator; + typedef typename S::iterator iterator; + typedef typename S::const_iterator const_iterator; typedef typename S::size_type size_type; typedef typename std::ptrdiff_t index_type; @@ -7101,6 +7807,13 @@ switch (yytype) : seq_ (n) {} +#if 201103L <= YY_CPLUSPLUS + /// Non copyable. + stack (const stack&) = delete; + /// Non copyable. + stack& operator= (const stack&) = delete; +#endif + /// Random access. /// /// Index 0 returns the topmost element. @@ -7151,24 +7864,18 @@ switch (yytype) return index_type (seq_.size ()); } - std::ptrdiff_t - ssize () const YY_NOEXCEPT - { - return std::ptrdiff_t (size ()); - } - /// Iterator on top of the stack (going downwards). const_iterator begin () const YY_NOEXCEPT { - return seq_.rbegin (); + return seq_.begin (); } /// Bottom of the stack. const_iterator end () const YY_NOEXCEPT { - return seq_.rend (); + return seq_.end (); } /// Present a slice of the top of a stack. @@ -7192,8 +7899,12 @@ switch (yytype) }; private: +#if YY_CPLUSPLUS < 201103L + /// Non copyable. stack (const stack&); + /// Non copyable. stack& operator= (const stack&); +#endif /// The wrapped container. S seq_; }; @@ -7223,33 +7934,28 @@ switch (yytype) /// Pop \a n symbols from the stack. void yypop_ (int n = 1); - /// Some specific tokens. - static const token_number_type yy_error_token_ = 1; - static const token_number_type yy_undef_token_ = 2; - /// Constants. enum { - yyeof_ = 0, yylast_ = 3260, ///< Last index in yytable_. yynnts_ = 16, ///< Number of nonterminal symbols. - yyfinal_ = 337, ///< Termination state number. - yyntokens_ = 342 ///< Number of tokens. + yyfinal_ = 337 ///< Termination state number. }; // User arguments. modsecurity::Parser::Driver& driver; + }; inline - seclang_parser::token_number_type + seclang_parser::symbol_kind_type seclang_parser::yytranslate_ (int t) { // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to // TOKEN-NUM as returned by yylex. static - const token_number_type + const short translate_table[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -7316,266 +8022,21 @@ switch (yytype) const int user_token_number_max_ = 596; if (t <= 0) - return yyeof_; + return symbol_kind::S_YYEOF; else if (t <= user_token_number_max_) - return translate_table[t]; + return YY_CAST (symbol_kind_type, translate_table[t]); else - return yy_undef_token_; + return symbol_kind::S_YYUNDEF; } // basic_symbol. -#if 201103L <= YY_CPLUSPLUS - template - seclang_parser::basic_symbol::basic_symbol (basic_symbol&& that) - : Base (std::move (that)) - , value () - , location (std::move (that.location)) - { - switch (this->type_get ()) - { - case 145: // "Accuracy" - case 146: // "Allow" - case 147: // "Append" - case 148: // "AuditLog" - case 149: // "Block" - case 150: // "Capture" - case 151: // "Chain" - case 152: // "ACTION_CTL_AUDIT_ENGINE" - case 153: // "ACTION_CTL_AUDIT_LOG_PARTS" - case 154: // "ACTION_CTL_BDY_JSON" - case 155: // "ACTION_CTL_BDY_XML" - case 156: // "ACTION_CTL_BDY_URLENCODED" - case 157: // "ACTION_CTL_FORCE_REQ_BODY_VAR" - case 158: // "ACTION_CTL_REQUEST_BODY_ACCESS" - case 159: // "ACTION_CTL_RULE_REMOVE_BY_ID" - case 160: // "ACTION_CTL_RULE_REMOVE_BY_TAG" - case 161: // "ACTION_CTL_RULE_REMOVE_TARGET_BY_ID" - case 162: // "ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG" - case 163: // "Deny" - case 164: // "DeprecateVar" - case 165: // "Drop" - case 166: // "Exec" - case 167: // "ExpireVar" - case 168: // "Id" - case 169: // "InitCol" - case 170: // "Log" - case 171: // "LogData" - case 172: // "Maturity" - case 173: // "Msg" - case 174: // "MultiMatch" - case 175: // "NoAuditLog" - case 176: // "NoLog" - case 177: // "Pass" - case 178: // "Pause" - case 179: // "Phase" - case 180: // "Prepend" - case 181: // "Proxy" - case 182: // "Redirect" - case 183: // "Rev" - case 184: // "SanitiseArg" - case 185: // "SanitiseMatched" - case 186: // "SanitiseMatchedBytes" - case 187: // "SanitiseRequestHeader" - case 188: // "SanitiseResponseHeader" - case 189: // "SetEnv" - case 190: // "SetRsc" - case 191: // "SetSid" - case 192: // "SetUID" - case 193: // "Severity" - case 194: // "Skip" - case 195: // "SkipAfter" - case 196: // "Status" - case 197: // "Tag" - case 198: // "ACTION_TRANSFORMATION_BASE_64_ENCODE" - case 199: // "ACTION_TRANSFORMATION_BASE_64_DECODE" - case 200: // "ACTION_TRANSFORMATION_BASE_64_DECODE_EXT" - case 201: // "ACTION_TRANSFORMATION_CMD_LINE" - case 202: // "ACTION_TRANSFORMATION_COMPRESS_WHITESPACE" - case 203: // "ACTION_TRANSFORMATION_CSS_DECODE" - case 204: // "ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE" - case 205: // "ACTION_TRANSFORMATION_HEX_ENCODE" - case 206: // "ACTION_TRANSFORMATION_HEX_DECODE" - case 207: // "ACTION_TRANSFORMATION_HTML_ENTITY_DECODE" - case 208: // "ACTION_TRANSFORMATION_JS_DECODE" - case 209: // "ACTION_TRANSFORMATION_LENGTH" - case 210: // "ACTION_TRANSFORMATION_LOWERCASE" - case 211: // "ACTION_TRANSFORMATION_MD5" - case 212: // "ACTION_TRANSFORMATION_NONE" - case 213: // "ACTION_TRANSFORMATION_NORMALISE_PATH" - case 214: // "ACTION_TRANSFORMATION_NORMALISE_PATH_WIN" - case 215: // "ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT" - case 216: // "ACTION_TRANSFORMATION_PARITY_ODD_7_BIT" - case 217: // "ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT" - case 218: // "ACTION_TRANSFORMATION_REMOVE_COMMENTS" - case 219: // "ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR" - case 220: // "ACTION_TRANSFORMATION_REMOVE_NULLS" - case 221: // "ACTION_TRANSFORMATION_REMOVE_WHITESPACE" - case 222: // "ACTION_TRANSFORMATION_REPLACE_COMMENTS" - case 223: // "ACTION_TRANSFORMATION_REPLACE_NULLS" - case 224: // "ACTION_TRANSFORMATION_SHA1" - case 225: // "ACTION_TRANSFORMATION_SQL_HEX_DECODE" - case 226: // "ACTION_TRANSFORMATION_TRIM" - case 227: // "ACTION_TRANSFORMATION_TRIM_LEFT" - case 228: // "ACTION_TRANSFORMATION_TRIM_RIGHT" - case 229: // "ACTION_TRANSFORMATION_UPPERCASE" - case 230: // "ACTION_TRANSFORMATION_URL_ENCODE" - case 231: // "ACTION_TRANSFORMATION_URL_DECODE" - case 232: // "ACTION_TRANSFORMATION_URL_DECODE_UNI" - case 233: // "ACTION_TRANSFORMATION_UTF8_TO_UNICODE" - case 234: // "Ver" - case 235: // "xmlns" - case 236: // "CONFIG_COMPONENT_SIG" - case 237: // "CONFIG_CONN_ENGINE" - case 238: // "CONFIG_SEC_ARGUMENT_SEPARATOR" - case 239: // "CONFIG_SEC_WEB_APP_ID" - case 240: // "CONFIG_SEC_SERVER_SIG" - case 241: // "CONFIG_DIR_AUDIT_DIR" - case 242: // "CONFIG_DIR_AUDIT_DIR_MOD" - case 243: // "CONFIG_DIR_AUDIT_ENG" - case 244: // "CONFIG_DIR_AUDIT_FLE_MOD" - case 245: // "CONFIG_DIR_AUDIT_LOG" - case 246: // "CONFIG_DIR_AUDIT_LOG2" - case 247: // "CONFIG_DIR_AUDIT_LOG_P" - case 248: // "CONFIG_DIR_AUDIT_STS" - case 249: // "CONFIG_DIR_AUDIT_TPE" - case 250: // "CONFIG_DIR_DEBUG_LOG" - case 251: // "CONFIG_DIR_DEBUG_LVL" - case 252: // "CONFIG_SEC_CACHE_TRANSFORMATIONS" - case 253: // "CONFIG_SEC_DISABLE_BACKEND_COMPRESS" - case 254: // "CONFIG_SEC_HASH_ENGINE" - case 255: // "CONFIG_SEC_HASH_KEY" - case 256: // "CONFIG_SEC_HASH_PARAM" - case 257: // "CONFIG_SEC_HASH_METHOD_RX" - case 258: // "CONFIG_SEC_HASH_METHOD_PM" - case 259: // "CONFIG_SEC_CHROOT_DIR" - case 260: // "CONFIG_DIR_GEO_DB" - case 261: // "CONFIG_DIR_GSB_DB" - case 262: // "CONFIG_SEC_GUARDIAN_LOG" - case 263: // "CONFIG_DIR_PCRE_MATCH_LIMIT" - case 264: // "CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION" - case 265: // "CONFIG_SEC_CONN_R_STATE_LIMIT" - case 266: // "CONFIG_SEC_CONN_W_STATE_LIMIT" - case 267: // "CONFIG_SEC_SENSOR_ID" - case 268: // "CONFIG_DIR_ARGS_LIMIT" - case 269: // "CONFIG_DIR_REQ_BODY" - case 270: // "CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT" - case 271: // "CONFIG_DIR_REQ_BODY_LIMIT" - case 272: // "CONFIG_DIR_REQ_BODY_LIMIT_ACTION" - case 273: // "CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT" - case 274: // "CONFIG_DIR_RES_BODY" - case 275: // "CONFIG_DIR_RES_BODY_LIMIT" - case 276: // "CONFIG_DIR_RES_BODY_LIMIT_ACTION" - case 277: // "CONFIG_SEC_RULE_INHERITANCE" - case 278: // "CONFIG_SEC_RULE_PERF_TIME" - case 279: // "CONFIG_DIR_RULE_ENG" - case 280: // "CONFIG_DIR_SEC_ACTION" - case 281: // "CONFIG_DIR_SEC_DEFAULT_ACTION" - case 282: // "CONFIG_DIR_SEC_MARKER" - case 283: // "CONFIG_DIR_UNICODE_MAP_FILE" - case 284: // "CONFIG_DIR_UNICODE_CODE_PAGE" - case 285: // "CONFIG_SEC_COLLECTION_TIMEOUT" - case 286: // "CONFIG_SEC_HTTP_BLKEY" - case 287: // "CONFIG_SEC_INTERCEPT_ON_ERROR" - case 288: // "CONFIG_SEC_REMOTE_RULES_FAIL_ACTION" - case 289: // "CONFIG_SEC_RULE_REMOVE_BY_ID" - case 290: // "CONFIG_SEC_RULE_REMOVE_BY_MSG" - case 291: // "CONFIG_SEC_RULE_REMOVE_BY_TAG" - case 292: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG" - case 293: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG" - case 294: // "CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID" - case 295: // "CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID" - case 296: // "CONFIG_UPDLOAD_KEEP_FILES" - case 297: // "CONFIG_UPDLOAD_SAVE_TMP_FILES" - case 298: // "CONFIG_UPLOAD_DIR" - case 299: // "CONFIG_UPLOAD_FILE_LIMIT" - case 300: // "CONFIG_UPLOAD_FILE_MODE" - case 301: // "CONFIG_VALUE_ABORT" - case 302: // "CONFIG_VALUE_DETC" - case 303: // "CONFIG_VALUE_HTTPS" - case 304: // "CONFIG_VALUE_OFF" - case 305: // "CONFIG_VALUE_ON" - case 306: // "CONFIG_VALUE_PARALLEL" - case 307: // "CONFIG_VALUE_PROCESS_PARTIAL" - case 308: // "CONFIG_VALUE_REJECT" - case 309: // "CONFIG_VALUE_RELEVANT_ONLY" - case 310: // "CONFIG_VALUE_SERIAL" - case 311: // "CONFIG_VALUE_WARN" - case 312: // "CONFIG_XML_EXTERNAL_ENTITY" - case 313: // "CONGIG_DIR_RESPONSE_BODY_MP" - case 314: // "CONGIG_DIR_SEC_ARG_SEP" - case 315: // "CONGIG_DIR_SEC_COOKIE_FORMAT" - case 316: // "CONFIG_SEC_COOKIEV0_SEPARATOR" - case 317: // "CONGIG_DIR_SEC_DATA_DIR" - case 318: // "CONGIG_DIR_SEC_STATUS_ENGINE" - case 319: // "CONFIG_SEC_STREAM_IN_BODY_INSPECTION" - case 320: // "CONFIG_SEC_STREAM_OUT_BODY_INSPECTION" - case 321: // "CONGIG_DIR_SEC_TMP_DIR" - case 322: // "DIRECTIVE" - case 323: // "DIRECTIVE_SECRULESCRIPT" - case 324: // "FREE_TEXT_QUOTE_MACRO_EXPANSION" - case 325: // "QUOTATION_MARK" - case 326: // "RUN_TIME_VAR_BLD" - case 327: // "RUN_TIME_VAR_DUR" - case 328: // "RUN_TIME_VAR_HSV" - case 329: // "RUN_TIME_VAR_REMOTE_USER" - case 330: // "RUN_TIME_VAR_TIME" - case 331: // "RUN_TIME_VAR_TIME_DAY" - case 332: // "RUN_TIME_VAR_TIME_EPOCH" - case 333: // "RUN_TIME_VAR_TIME_HOUR" - case 334: // "RUN_TIME_VAR_TIME_MIN" - case 335: // "RUN_TIME_VAR_TIME_MON" - case 336: // "RUN_TIME_VAR_TIME_SEC" - case 337: // "RUN_TIME_VAR_TIME_WDAY" - case 338: // "RUN_TIME_VAR_TIME_YEAR" - case 339: // "VARIABLE" - case 340: // "Dictionary element" - case 341: // "Dictionary element, selected by regexp" - value.move< std::string > (std::move (that.value)); - break; - - case 348: // op - case 349: // op_before_init - value.move< std::unique_ptr > (std::move (that.value)); - break; - - case 357: // run_time_string - value.move< std::unique_ptr > (std::move (that.value)); - break; - - case 354: // var - value.move< std::unique_ptr > (std::move (that.value)); - break; - - case 355: // act - case 356: // setvar_action - value.move< std::unique_ptr > (std::move (that.value)); - break; - - case 351: // variables - case 352: // variables_pre_process - case 353: // variables_may_be_quoted - value.move< std::unique_ptr > > > (std::move (that.value)); - break; - - case 346: // actions - case 347: // actions_may_quoted - value.move< std::unique_ptr > > > (std::move (that.value)); - break; - - default: - break; - } - - } -#endif - template seclang_parser::basic_symbol::basic_symbol (const basic_symbol& that) : Base (that) , value () , location (that.location) { - switch (this->type_get ()) + switch (this->kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -7814,11 +8275,18 @@ switch (yytype) + template + seclang_parser::symbol_kind_type + seclang_parser::basic_symbol::type_get () const YY_NOEXCEPT + { + return this->kind (); + } + template bool seclang_parser::basic_symbol::empty () const YY_NOEXCEPT { - return Base::type_get () == empty_symbol; + return this->kind () == symbol_kind::S_YYEMPTY; } template @@ -7826,7 +8294,7 @@ switch (yytype) seclang_parser::basic_symbol::move (basic_symbol& s) { super_type::move (s); - switch (this->type_get ()) + switch (this->kind ()) { case 145: // "Accuracy" case 146: // "Allow" @@ -8064,55 +8532,62 @@ switch (yytype) location = YY_MOVE (s.location); } - // by_type. + // by_kind. inline - seclang_parser::by_type::by_type () - : type (empty_symbol) + seclang_parser::by_kind::by_kind () + : kind_ (symbol_kind::S_YYEMPTY) {} #if 201103L <= YY_CPLUSPLUS inline - seclang_parser::by_type::by_type (by_type&& that) - : type (that.type) + seclang_parser::by_kind::by_kind (by_kind&& that) + : kind_ (that.kind_) { that.clear (); } #endif inline - seclang_parser::by_type::by_type (const by_type& that) - : type (that.type) + seclang_parser::by_kind::by_kind (const by_kind& that) + : kind_ (that.kind_) {} inline - seclang_parser::by_type::by_type (token_type t) - : type (yytranslate_ (t)) + seclang_parser::by_kind::by_kind (token_kind_type t) + : kind_ (yytranslate_ (t)) {} inline void - seclang_parser::by_type::clear () + seclang_parser::by_kind::clear () { - type = empty_symbol; + kind_ = symbol_kind::S_YYEMPTY; } inline void - seclang_parser::by_type::move (by_type& that) + seclang_parser::by_kind::move (by_kind& that) { - type = that.type; + kind_ = that.kind_; that.clear (); } inline - int - seclang_parser::by_type::type_get () const YY_NOEXCEPT + seclang_parser::symbol_kind_type + seclang_parser::by_kind::kind () const YY_NOEXCEPT + { + return kind_; + } + + inline + seclang_parser::symbol_kind_type + seclang_parser::by_kind::type_get () const YY_NOEXCEPT { - return type; + return this->kind (); } } // yy -#line 8116 "seclang-parser.hh" +#line 8591 "seclang-parser.hh" diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index 02e8e9eab9..6feb7e7b75 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -17,7 +17,9 @@ class Driver; } } -#include "modsecurity/rule_unconditional.h" +#include "src/rule_unconditional.h" +#include "src/rule_with_operator.h" +#include "src/rule_with_actions.h" #include "src/rule_script.h" #include "src/actions/accuracy.h" @@ -43,6 +45,7 @@ class Driver; #include "src/actions/disruptive/redirect.h" #include "src/actions/init_col.h" #include "src/actions/exec.h" +#include "src/actions/expire_var.h" #include "src/actions/log_data.h" #include "src/actions/log.h" #include "src/actions/maturity.h" @@ -1067,10 +1070,12 @@ expression: | DIRECTIVE variables op actions { std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *$4.get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -1116,10 +1121,12 @@ expression: | CONFIG_DIR_SEC_ACTION actions { std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *$2.get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -1136,10 +1143,12 @@ expression: { std::string err; std::vector *a = new std::vector(); - std::vector *t = new std::vector(); + std::vector > *t = new std::vector >(); for (auto &i : *$2.get()) { if (dynamic_cast(i.get())) { - t->push_back(dynamic_cast(i.release())); + std::shared_ptr at = std::move(i); + std::shared_ptr t2 = std::dynamic_pointer_cast(std::move(at)); + t->push_back(std::move(t2)); } else { a->push_back(i.release()); } @@ -1172,23 +1181,19 @@ expression: int secRuleDefinedPhase = -1; for (actions::Action *a : *actions) { actions::Phase *phase = dynamic_cast(a); - if (a->isDisruptive() == true && dynamic_cast(a) == NULL) { + if (dynamic_cast(a) != NULL + && dynamic_cast(a) == NULL) { hasDisruptive = true; } if (phase != NULL) { - definedPhase = phase->m_phase; - secRuleDefinedPhase = phase->m_secRulesPhase; + definedPhase = phase->getPhase(); + secRuleDefinedPhase = phase->getSecRulePhase(); delete phase; - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind || - a->action_kind == actions::Action::RunTimeBeforeMatchAttemptKind) { - actions::transformations::None *none = dynamic_cast(a); - if (none != NULL) { - driver.error(@0, "The transformation none is not suitable to be part of the SecDefaultActions"); - YYERROR; - } + } else if (dynamic_cast(a) + && !dynamic_cast(a)) { checkedActions.push_back(a); } else { - driver.error(@0, "The action '" + *a->m_name.get() + "' is not suitable to be part of the SecDefaultActions"); + driver.error(@0, "The action '" + *a->getName() + "' is not suitable to be part of the SecDefaultActions"); YYERROR; } } @@ -1201,7 +1206,7 @@ expression: YYERROR; } - if (!driver.m_defaultActions[definedPhase].empty()) { + if (!driver.m_rulesSetPhases[definedPhase]->m_defaultActions.empty()) { std::stringstream ss; ss << "SecDefaultActions can only be placed once per phase and configuration context. Phase "; ss << secRuleDefinedPhase; @@ -1211,8 +1216,13 @@ expression: } for (actions::Action *a : checkedActions) { - driver.m_defaultActions[definedPhase].push_back( - std::unique_ptr(a)); + if (dynamic_cast(a)) { + driver.m_rulesSetPhases[definedPhase]->m_defaultTransformations.push_back( + std::shared_ptr( + dynamic_cast(a))); + } else { + driver.m_rulesSetPhases[definedPhase]->m_defaultActions.push_back(std::unique_ptr(a)); + } } delete actions; @@ -2597,19 +2607,19 @@ act: } | ACTION_AUDIT_LOG { - ACTION_CONTAINER($$, new actions::AuditLog($1)); + ACTION_CONTAINER($$, new actions::AuditLog()); } | ACTION_BLOCK { - ACTION_CONTAINER($$, new actions::Block($1)); + ACTION_CONTAINER($$, new actions::Block()); } | ACTION_CAPTURE { - ACTION_CONTAINER($$, new actions::Capture($1)); + ACTION_CONTAINER($$, new actions::Capture()); } | ACTION_CHAIN { - ACTION_CONTAINER($$, new actions::Chain($1)); + ACTION_CONTAINER($$, new actions::Chain()); } | ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_ON { @@ -2690,7 +2700,7 @@ act: } | ACTION_DENY { - ACTION_CONTAINER($$, new actions::disruptive::Deny($1)); + ACTION_CONTAINER($$, new actions::disruptive::Deny()); } | ACTION_DEPRECATE_VAR { @@ -2698,7 +2708,7 @@ act: } | ACTION_DROP { - ACTION_CONTAINER($$, new actions::disruptive::Drop($1)); + ACTION_CONTAINER($$, new actions::disruptive::Drop()); } | ACTION_EXEC { @@ -2706,8 +2716,7 @@ act: } | ACTION_EXPIRE_VAR { - //ACTION_NOT_SUPPORTED("ExpireVar", @0); - ACTION_CONTAINER($$, new actions::Action($1)); + ACTION_CONTAINER($$, new actions::ExpireVar($1)); } | ACTION_ID { @@ -2723,7 +2732,7 @@ act: } | ACTION_LOG { - ACTION_CONTAINER($$, new actions::Log($1)); + ACTION_CONTAINER($$, new actions::Log()); } | ACTION_MATURITY { @@ -2735,19 +2744,19 @@ act: } | ACTION_MULTI_MATCH { - ACTION_CONTAINER($$, new actions::MultiMatch($1)); + ACTION_CONTAINER($$, new actions::MultiMatch()); } | ACTION_NO_AUDIT_LOG { - ACTION_CONTAINER($$, new actions::NoAuditLog($1)); + ACTION_CONTAINER($$, new actions::NoAuditLog()); } | ACTION_NO_LOG { - ACTION_CONTAINER($$, new actions::NoLog($1)); + ACTION_CONTAINER($$, new actions::NoLog()); } | ACTION_PASS { - ACTION_CONTAINER($$, new actions::disruptive::Pass($1)); + ACTION_CONTAINER($$, new actions::disruptive::Pass()); } | ACTION_PAUSE { @@ -2843,147 +2852,147 @@ act: } | ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT { - ACTION_CONTAINER($$, new actions::transformations::ParityZero7bit($1)); + ACTION_CONTAINER($$, new actions::transformations::ParityZero7bit()); } | ACTION_TRANSFORMATION_PARITY_ODD_7_BIT { - ACTION_CONTAINER($$, new actions::transformations::ParityOdd7bit($1)); + ACTION_CONTAINER($$, new actions::transformations::ParityOdd7bit()); } | ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT { - ACTION_CONTAINER($$, new actions::transformations::ParityEven7bit($1)); + ACTION_CONTAINER($$, new actions::transformations::ParityEven7bit()); } | ACTION_TRANSFORMATION_SQL_HEX_DECODE { - ACTION_CONTAINER($$, new actions::transformations::SqlHexDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::SqlHexDecode()); } | ACTION_TRANSFORMATION_BASE_64_ENCODE { - ACTION_CONTAINER($$, new actions::transformations::Base64Encode($1)); + ACTION_CONTAINER($$, new actions::transformations::Base64Encode()); } | ACTION_TRANSFORMATION_BASE_64_DECODE { - ACTION_CONTAINER($$, new actions::transformations::Base64Decode($1)); + ACTION_CONTAINER($$, new actions::transformations::Base64Decode()); } | ACTION_TRANSFORMATION_BASE_64_DECODE_EXT { - ACTION_CONTAINER($$, new actions::transformations::Base64DecodeExt($1)); + ACTION_CONTAINER($$, new actions::transformations::Base64DecodeExt()); } | ACTION_TRANSFORMATION_CMD_LINE { - ACTION_CONTAINER($$, new actions::transformations::CmdLine($1)); + ACTION_CONTAINER($$, new actions::transformations::CmdLine()); } | ACTION_TRANSFORMATION_SHA1 { - ACTION_CONTAINER($$, new actions::transformations::Sha1($1)); + ACTION_CONTAINER($$, new actions::transformations::Sha1()); } | ACTION_TRANSFORMATION_MD5 { - ACTION_CONTAINER($$, new actions::transformations::Md5($1)); + ACTION_CONTAINER($$, new actions::transformations::Md5()); } | ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE { - ACTION_CONTAINER($$, new actions::transformations::EscapeSeqDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::EscapeSeqDecode()); } | ACTION_TRANSFORMATION_HEX_ENCODE { - ACTION_CONTAINER($$, new actions::transformations::HexEncode($1)); + ACTION_CONTAINER($$, new actions::transformations::HexEncode()); } | ACTION_TRANSFORMATION_HEX_DECODE { - ACTION_CONTAINER($$, new actions::transformations::HexDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::HexDecode()); } | ACTION_TRANSFORMATION_LOWERCASE { - ACTION_CONTAINER($$, new actions::transformations::LowerCase($1)); + ACTION_CONTAINER($$, new actions::transformations::LowerCase()); } | ACTION_TRANSFORMATION_UPPERCASE { - ACTION_CONTAINER($$, new actions::transformations::UpperCase($1)); + ACTION_CONTAINER($$, new actions::transformations::UpperCase()); } | ACTION_TRANSFORMATION_URL_DECODE_UNI { - ACTION_CONTAINER($$, new actions::transformations::UrlDecodeUni($1)); + ACTION_CONTAINER($$, new actions::transformations::UrlDecodeUni()); } | ACTION_TRANSFORMATION_URL_DECODE { - ACTION_CONTAINER($$, new actions::transformations::UrlDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::UrlDecode()); } | ACTION_TRANSFORMATION_URL_ENCODE { - ACTION_CONTAINER($$, new actions::transformations::UrlEncode($1)); + ACTION_CONTAINER($$, new actions::transformations::UrlEncode()); } | ACTION_TRANSFORMATION_NONE { - ACTION_CONTAINER($$, new actions::transformations::None($1)); + ACTION_CONTAINER($$, new actions::transformations::None()); } | ACTION_TRANSFORMATION_COMPRESS_WHITESPACE { - ACTION_CONTAINER($$, new actions::transformations::CompressWhitespace($1)); + ACTION_CONTAINER($$, new actions::transformations::CompressWhitespace()); } | ACTION_TRANSFORMATION_REMOVE_WHITESPACE { - ACTION_CONTAINER($$, new actions::transformations::RemoveWhitespace($1)); + ACTION_CONTAINER($$, new actions::transformations::RemoveWhitespace()); } | ACTION_TRANSFORMATION_REPLACE_NULLS { - ACTION_CONTAINER($$, new actions::transformations::ReplaceNulls($1)); + ACTION_CONTAINER($$, new actions::transformations::ReplaceNulls()); } | ACTION_TRANSFORMATION_REMOVE_NULLS { - ACTION_CONTAINER($$, new actions::transformations::RemoveNulls($1)); + ACTION_CONTAINER($$, new actions::transformations::RemoveNulls()); } | ACTION_TRANSFORMATION_HTML_ENTITY_DECODE { - ACTION_CONTAINER($$, new actions::transformations::HtmlEntityDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::HtmlEntityDecode()); } | ACTION_TRANSFORMATION_JS_DECODE { - ACTION_CONTAINER($$, new actions::transformations::JsDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::JsDecode()); } | ACTION_TRANSFORMATION_CSS_DECODE { - ACTION_CONTAINER($$, new actions::transformations::CssDecode($1)); + ACTION_CONTAINER($$, new actions::transformations::CssDecode()); } | ACTION_TRANSFORMATION_TRIM { - ACTION_CONTAINER($$, new actions::transformations::Trim($1)); + ACTION_CONTAINER($$, new actions::transformations::Trim()); } | ACTION_TRANSFORMATION_TRIM_LEFT { - ACTION_CONTAINER($$, new actions::transformations::TrimLeft($1)); + ACTION_CONTAINER($$, new actions::transformations::TrimLeft()); } | ACTION_TRANSFORMATION_TRIM_RIGHT { - ACTION_CONTAINER($$, new actions::transformations::TrimRight($1)); + ACTION_CONTAINER($$, new actions::transformations::TrimRight()); } | ACTION_TRANSFORMATION_NORMALISE_PATH_WIN { - ACTION_CONTAINER($$, new actions::transformations::NormalisePathWin($1)); + ACTION_CONTAINER($$, new actions::transformations::NormalisePathWin()); } | ACTION_TRANSFORMATION_NORMALISE_PATH { - ACTION_CONTAINER($$, new actions::transformations::NormalisePath($1)); + ACTION_CONTAINER($$, new actions::transformations::NormalisePath()); } | ACTION_TRANSFORMATION_LENGTH { - ACTION_CONTAINER($$, new actions::transformations::Length($1)); + ACTION_CONTAINER($$, new actions::transformations::Length()); } | ACTION_TRANSFORMATION_UTF8_TO_UNICODE { - ACTION_CONTAINER($$, new actions::transformations::Utf8ToUnicode($1)); + ACTION_CONTAINER($$, new actions::transformations::Utf8ToUnicode()); } | ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR { - ACTION_CONTAINER($$, new actions::transformations::RemoveCommentsChar($1)); + ACTION_CONTAINER($$, new actions::transformations::RemoveCommentsChar()); } | ACTION_TRANSFORMATION_REMOVE_COMMENTS { - ACTION_CONTAINER($$, new actions::transformations::RemoveComments($1)); + ACTION_CONTAINER($$, new actions::transformations::RemoveComments()); } | ACTION_TRANSFORMATION_REPLACE_COMMENTS { - ACTION_CONTAINER($$, new actions::transformations::ReplaceComments($1)); + ACTION_CONTAINER($$, new actions::transformations::ReplaceComments()); } ; diff --git a/src/parser/stack.hh b/src/parser/stack.hh index e83ba35f3f..d37a04b6f5 100644 --- a/src/parser/stack.hh +++ b/src/parser/stack.hh @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.5.3. +// A Bison parser, made by GNU Bison 3.6.2. // Starting with Bison 3.2, this file is useless: the structure it // used to define is now defined with the parser itself. diff --git a/headers/modsecurity/rule_marker.h b/src/rule_marker.h similarity index 78% rename from headers/modsecurity/rule_marker.h rename to src/rule_marker.h index 06d5b499fa..280cacb69f 100644 --- a/headers/modsecurity/rule_marker.h +++ b/src/rule_marker.h @@ -44,13 +44,17 @@ class RuleMarker : public Rule { : Rule(std::move(fileName), lineNumber), m_name(std::make_shared(name)) { } + RuleMarker(RuleMarker &&r) : + Rule(r), + m_name(std::move(r.m_name)) + { }; - virtual bool evaluate(Transaction *transaction, - std::shared_ptr rm) override { - return evaluate(transaction); - } + RuleMarker(const RuleMarker &r) : + Rule(r), + m_name(std::move(r.m_name)) + { }; - virtual bool evaluate(Transaction *transaction) override { + virtual bool evaluate(Transaction *transaction) const override { if (transaction->isInsideAMarker()) { if (*transaction->getCurrentMarker() == *m_name) { transaction->removeMarker(); @@ -63,11 +67,14 @@ class RuleMarker : public Rule { }; - std::shared_ptr getName() { + std::shared_ptr getName() const { return m_name; } - bool isMarker() override { return true; } + virtual void dump(std::stringstream &out) const override { + Rule::dump(out); + out << "SecMarker \"" << *getName() << "\"" << std::endl; + } private: std::shared_ptr m_name; diff --git a/src/rule_message.cc b/src/rule_message.cc index 7e394c14b4..4046a58138 100644 --- a/src/rule_message.cc +++ b/src/rule_message.cc @@ -19,6 +19,9 @@ #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" #include "src/utils/string.h" +#include "src/actions/tag.h" +#include "src/rule_with_actions.h" + namespace modsecurity { @@ -26,27 +29,25 @@ namespace modsecurity { std::string RuleMessage::_details(const RuleMessage *rm) { std::string msg; - msg.append(" [file \"" + std::string(*rm->m_ruleFile.get()) + "\"]"); - msg.append(" [line \"" + std::to_string(rm->m_ruleLine) + "\"]"); - msg.append(" [id \"" + std::to_string(rm->m_ruleId) + "\"]"); - msg.append(" [rev \"" + rm->m_rev + "\"]"); + msg.append(" [file \"" + rm->getFileName() + "\"]"); + msg.append(" [line \"" + std::to_string(rm->getLineNumber()) + "\"]"); + msg.append(" [id \"" + std::to_string(rm->getRuleId()) + "\"]"); + msg.append(" [rev \"" + rm->getRev() + "\"]"); msg.append(" [msg \"" + rm->m_message + "\"]"); msg.append(" [data \"" + utils::string::limitTo(200, rm->m_data) + "\"]"); msg.append(" [severity \"" + std::to_string(rm->m_severity) + "\"]"); - msg.append(" [ver \"" + rm->m_ver + "\"]"); - msg.append(" [maturity \"" + std::to_string(rm->m_maturity) + "\"]"); - msg.append(" [accuracy \"" + std::to_string(rm->m_accuracy) + "\"]"); - for (auto &a : rm->m_tags) { + msg.append(" [ver \"" + rm->getVer() + "\"]"); + msg.append(" [maturity \"" + std::to_string(rm->getMaturity()) + "\"]"); + msg.append(" [accuracy \"" + std::to_string(rm->getAccuracy()) + "\"]"); + for (auto a : rm->m_tags) { msg.append(" [tag \"" + a + "\"]"); } - - msg.append(" [hostname \"" + *rm->m_serverIpAddress.get() \ - + "\"]"); - msg.append(" [uri \"" + utils::string::limitTo(200, *rm->m_uriNoQueryStringDecoded.get()) + "\"]"); - msg.append(" [unique_id \"" + *rm->m_id + "\"]"); - msg.append(" [ref \"" + utils::string::limitTo(200, rm->m_reference) + "\"]"); + msg.append(" [hostname \"" + rm->getServerIpAddress() + "\"]"); + msg.append(" [uri \"" + utils::string::limitTo(200, rm->getUri()) + "\"]"); + msg.append(" [unique_id \"" + rm->getRequestId() + "\"]"); + msg.append(" [ref \"" + rm->m_reference + "\"]"); return msg; } @@ -55,9 +56,9 @@ std::string RuleMessage::_details(const RuleMessage *rm) { std::string RuleMessage::_errorLogTail(const RuleMessage *rm) { std::string msg; - msg.append("[hostname \"" + *rm->m_serverIpAddress.get() + "\"]"); - msg.append(" [uri \"" + utils::string::limitTo(200, *rm->m_uriNoQueryStringDecoded.get()) + "\"]"); - msg.append(" [unique_id \"" + *rm->m_id + "\"]"); + msg.append("[hostname \"" + rm->getServerIpAddress() + "\"]"); + msg.append(" [uri \"" + rm->getUri() + "\"]"); + msg.append(" [unique_id \"" + rm->getRequestId() + "\"]"); return msg; } @@ -68,10 +69,11 @@ std::string RuleMessage::log(const RuleMessage *rm, int props, int code) { msg.reserve(2048); if (props & ClientLogMessageInfo) { - msg.append("[client " + std::string(*rm->m_clientIpAddress.get()) + "] "); + msg.append("[client " + rm->getClientIpAddress() + "] "); } - if (rm->m_isDisruptive) { + if (rm->isDisruptive() + && (rm->m_transaction->getRuleEngineState() == RulesSet::EnabledRuleEngine)) { msg.append("ModSecurity: Access denied with code "); if (code == -1) { msg.append("%d"); @@ -79,7 +81,7 @@ std::string RuleMessage::log(const RuleMessage *rm, int props, int code) { msg.append(std::to_string(code)); } msg.append(" (phase "); - msg.append(std::to_string(rm->m_rule->getPhase() - 1) + "). "); + msg.append(std::to_string(rm->getPhase() - 1) + "). "); } else { msg.append("ModSecurity: Warning. "); } @@ -95,4 +97,131 @@ std::string RuleMessage::log(const RuleMessage *rm, int props, int code) { } -} // namespace modsecurity +const RuleWithActions *RuleMessage::getRule() const { + return m_rule; +} + + +void RuleMessage::setRule(const RuleWithActions *rule) { + m_rule = rule; +} + + +bool RuleMessage::isSettle() const { + return m_rule != nullptr; +} + + +int RuleMessage::getRuleId() const { + if (m_rule) { + return m_rule->getId(); + } + return -1; +} + + +int RuleMessage::getPhase() const { + if (m_rule) { + return m_rule->getPhase(); + } + return 0; +} + + +std::string RuleMessage::getFileName() const { + if (m_rule) { + return *m_rule->getFileName().get(); + } + return ""; +} + + +int RuleMessage::getLineNumber() const { + if (m_rule) { + return m_rule->getLineNumber(); + } + return 0; +} + + +std::string RuleMessage::getRev() const { + if (m_rule) { + return m_rule->getRevision(); + } + return ""; +} + + +std::string RuleMessage::getVer() const { + if (m_rule) { + return m_rule->getVersion(); + } + return ""; +} + + +int RuleMessage::getMaturity() const { + if (m_rule) { + return m_rule->getMaturity(); + } + return 0; +} + + +int RuleMessage::getAccuracy() const { + if (m_rule) { + return m_rule->getAccuracy(); + } + return 0; +} + + +bool RuleMessage::toBeAuditLog() const { + if (m_rule) { + return m_rule->isItToBeAuditLogged(); + } + return false; +} + + +std::string RuleMessage::getClientIpAddress() const { + if (m_transaction) { + return *m_transaction->m_clientIpAddress.get(); + } + return ""; +} + + +std::string RuleMessage::getServerIpAddress() const { + if (m_transaction) { + return *m_transaction->m_serverIpAddress.get(); + } + return ""; +} + + +std::string RuleMessage::getRequestId() const { + if (m_transaction) { + return *m_transaction->m_id.get(); + } + return ""; +} + + +std::string RuleMessage::getUri() const { + if (m_transaction) { + return *m_transaction->m_uri_no_query_string_decoded.get(); + } + return ""; +} + + +bool RuleMessage::isDisruptive() const { + if (m_rule) { + return m_rule->hasDisruptiveAction(); + } + return 0; +} + + +} // namespace modsecurity diff --git a/src/rule_script.cc b/src/rule_script.cc index e4ce531562..3018823198 100644 --- a/src/rule_script.cc +++ b/src/rule_script.cc @@ -19,23 +19,19 @@ namespace modsecurity { bool RuleScript::init(std::string *err) { - return m_lua.load(m_name, err); + return m_lua->load(m_name, err); } -bool RuleScript::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { +bool RuleScript::evaluate(Transaction *trans) const { ms_dbg_a(trans, 4, " Executing script: " + m_name + "."); - bool containsDisruptive = false; + executeActionsIndependentOfChainedRuleResult(trans); - executeActionsIndependentOfChainedRuleResult(trans, - &containsDisruptive, ruleMessage); - - bool ret = m_lua.run(trans); + bool ret = m_lua->run(trans); if (ret) { - executeActionsAfterFullMatch(trans, containsDisruptive, ruleMessage); + executeActionsAfterFullMatch(trans); } return ret; diff --git a/src/rule_script.h b/src/rule_script.h index f8b7930596..7569c5bf86 100644 --- a/src/rule_script.h +++ b/src/rule_script.h @@ -32,6 +32,8 @@ #include "src/actions/log_data.h" #include "src/actions/severity.h" #include "src/variables/variable.h" +#include "src/rule_with_actions.h" + #ifndef SRC_RULE_SCRIPT_H_ #define SRC_RULE_SCRIPT_H_ @@ -50,15 +52,26 @@ class RuleScript : public RuleWithActions { std::unique_ptr fileName, int lineNumber) : RuleWithActions(actions, t, std::move(fileName), lineNumber), - m_name(name) { } + m_name(name), + m_lua(std::unique_ptr(new engine::Lua())) { } - bool init(std::string *err); - bool evaluate(Transaction *trans, - std::shared_ptr ruleMessage) override; + RuleScript(const RuleScript &rs) + : RuleWithActions(rs), + m_name(rs.m_name), + m_lua(rs.m_lua) { } + RuleScript &operator=(const RuleScript& r) { + RuleWithActions::operator = (r); + m_name = r.m_name; + m_lua = r.m_lua; + return *this; + } + + bool init(std::string *err); + bool evaluate(Transaction *trans) const override; std::string m_name; - engine::Lua m_lua; + std::shared_ptr m_lua; }; } // namespace modsecurity diff --git a/src/rule_unconditional.cc b/src/rule_unconditional.cc index 17532c67bb..d04ca4a46a 100644 --- a/src/rule_unconditional.cc +++ b/src/rule_unconditional.cc @@ -13,28 +13,23 @@ * */ -#include "modsecurity/rule_unconditional.h" +#include "src/rule_unconditional.h" namespace modsecurity { -bool RuleUnconditional::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { - RuleWithActions::evaluate(trans, ruleMessage); +bool RuleUnconditional::evaluate(Transaction *trans) const { + RuleWithActions::evaluate(trans); - // FIXME: This needs to be romeved on the runtime exeption review. - bool containsBlock = false; - - ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ + ms_dbg_a(trans, 4, "(Rule: " + std::to_string(getId()) \ + ") Executing unconditional rule..."); - executeActionsIndependentOfChainedRuleResult(trans, - &containsBlock, ruleMessage); + executeActionsIndependentOfChainedRuleResult(trans); - executeActionsAfterFullMatch(trans, containsBlock, ruleMessage); + executeActionsAfterFullMatch(trans); - performLogging(trans, ruleMessage); + trans->logMatchLastRuleOnTheChain(this); return true; } diff --git a/headers/modsecurity/rule_unconditional.h b/src/rule_unconditional.h similarity index 80% rename from headers/modsecurity/rule_unconditional.h rename to src/rule_unconditional.h index 04abb90ac1..6aa08ff693 100644 --- a/headers/modsecurity/rule_unconditional.h +++ b/src/rule_unconditional.h @@ -22,15 +22,15 @@ #include #endif -#ifndef HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_ -#define HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_ +#ifndef SRC_RULE_UNCONDITIONAL_H_ +#define SRC_RULE_UNCONDITIONAL_H_ #include "modsecurity/modsecurity.h" #include "modsecurity/variable_value.h" #include "modsecurity/rule.h" #include "modsecurity/rules_set.h" -#include "modsecurity/rule_with_actions.h" #include "modsecurity/actions/action.h" +#include "src/rule_with_actions.h" #ifdef __cplusplus @@ -46,7 +46,11 @@ class RuleUnconditional : public RuleWithActions { int lineNumber) : RuleWithActions(actions, transformations, std::move(fileName), lineNumber) { } - virtual bool evaluate(Transaction *transaction, std::shared_ptr ruleMessage) override; + RuleUnconditional(const RuleUnconditional &r) + : RuleWithActions(r) + { } + + virtual bool evaluate(Transaction *transaction) const override; private: }; @@ -56,4 +60,4 @@ class RuleUnconditional : public RuleWithActions { #endif -#endif // HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_ +#endif // SRC_RULE_UNCONDITIONAL_H_ diff --git a/src/rule_with_actions.cc b/src/rule_with_actions.cc index a2d7306eed..738b3d7215 100644 --- a/src/rule_with_actions.cc +++ b/src/rule_with_actions.cc @@ -18,41 +18,46 @@ #include #include -#include -#include #include +#include #include -#include #include +#include +#include -#include "modsecurity/rules_set.h" -#include "src/operators/operator.h" #include "modsecurity/actions/action.h" #include "modsecurity/modsecurity.h" -#include "src/actions/transformations/none.h" -#include "src/actions/tag.h" -#include "src/utils/string.h" #include "modsecurity/rule_message.h" -#include "modsecurity/rule_with_actions.h" -#include "src/actions/msg.h" -#include "src/actions/log_data.h" -#include "src/actions/severity.h" +#include "modsecurity/rules_set.h" +#include "src/rule_with_actions.h" +#include "src/actions/accuracy.h" +#include "src/actions/block.h" #include "src/actions/capture.h" +#include "src/actions/log_data.h" +#include "src/actions/msg.h" +#include "src/actions/maturity.h" #include "src/actions/multi_match.h" +#include "src/actions/rev.h" +#include "src/actions/log.h" +#include "src/actions/no_log.h" #include "src/actions/set_var.h" -#include "src/actions/block.h" -#include "src/variables/variable.h" - - -namespace modsecurity { +#include "src/actions/severity.h" +#include "src/actions/tag.h" +#include "src/actions/disruptive/disruptive_action.h" +#include "src/actions/transformations/transformation.h" +#include "src/actions/transformations/none.h" +#include "src/actions/xmlns.h" +#include "src/utils/string.h" +#include "src/actions/action_with_run_time_string.h" +#include "src/actions/phase.h" +#include "src/actions/chain.h" +#include "src/actions/rule_id.h" +#include "src/actions/ver.h" +#include "src/actions/action_type_rule_metadata.h" -using operators::Operator; -using actions::Action; -using variables::Variable; -using actions::transformations::None; -using actions::transformations::Transformation; +namespace modsecurity { RuleWithActions::RuleWithActions( Actions *actions, @@ -60,128 +65,132 @@ RuleWithActions::RuleWithActions( std::unique_ptr fileName, int lineNumber) : Rule(std::move(fileName), lineNumber), - m_rev(""), - m_ver(""), - m_accuracy(0), - m_maturity(0), m_ruleId(0), m_chainedRuleChild(nullptr), m_chainedRuleParent(nullptr), m_disruptiveAction(nullptr), m_logData(nullptr), m_msg(nullptr), - m_severity(nullptr), m_actionsRuntimePos(), m_actionsSetVar(), m_actionsTag(), - m_transformations(transformations != NULL ? *transformations : Transformations()), + m_XmlNSs(), + m_defaultActionDisruptiveAction(nullptr), + m_defaultActionLogData(nullptr), + m_defaultActionMsg(nullptr), + m_defaultActionActionsRuntimePos(), + m_defaultActionActionsSetVar(), + m_defaultActionActionsTag(), + m_transformations(transformations != nullptr ? *transformations : Transformations()), + m_defaultTransformations(), + m_severity(SEVERITY_NOT_SET), + m_revision(""), + m_version(""), + m_accuracy(ACCURACY_NOT_SET), + m_maturity(MATURITY_NOT_SET), m_containsCaptureAction(false), + m_containsLogAction(false), + m_containsNoLogAction(false), + m_containsAuditLogAction(false), + m_containsNoAuditLogAction(false), m_containsMultiMatchAction(false), m_containsStaticBlockAction(false), + m_defaultSeverity(SEVERITY_NOT_SET), + m_defaultRevision(""), + m_defaultVersion(""), + m_defaultAccuracy(ACCURACY_NOT_SET), + m_defaultMaturity(MATURITY_NOT_SET), + m_defaultContainsCaptureAction(false), + m_defaultContainsLogAction(false), + m_defaultContainsNoLogAction(false), + m_defaultContainsAuditLogAction(false), + m_defaultContainsNoAuditLogAction(false), + m_defaultContainsMultiMatchAction(false), + m_defaultContainsStaticBlockAction(false), m_isChained(false) { if (actions) { - for (Action *a : *actions) { - if (a->action_kind == Action::ConfigurationKind) { - a->evaluate(this, NULL); - delete a; - - } else if (a->action_kind == Action::RunTimeOnlyIfMatchKind) { - if (dynamic_cast(a)) { - m_containsCaptureAction = true; - delete a; - } else if (dynamic_cast(a)) { - m_containsMultiMatchAction = true; - delete a; - } else if (dynamic_cast(a)) { - m_severity = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_logData = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_msg = dynamic_cast(a); - } else if (dynamic_cast(a)) { - m_actionsSetVar.push_back( - dynamic_cast(a)); - } else if (dynamic_cast(a)) { - m_actionsTag.push_back(dynamic_cast(a)); - } else if (dynamic_cast(a)) { - m_actionsRuntimePos.push_back(a); - m_containsStaticBlockAction = true; - } else if (a->isDisruptive() == true) { - if (m_disruptiveAction != nullptr) { - delete m_disruptiveAction; - m_disruptiveAction = nullptr; - } - m_disruptiveAction = a; - } else { - m_actionsRuntimePos.push_back(a); - } - } else { - delete a; - std::cout << "General failure, action: " << a->m_name; - std::cout << " has an unknown type." << std::endl; - throw; - } + for (actions::Action *a : *actions) { + addAction(a); } - delete actions; } } -RuleWithActions::~RuleWithActions() { - if (m_severity) { - delete m_severity; - m_severity = nullptr; - } - if (m_logData) { - delete m_logData; - m_logData = nullptr; - } - if (m_msg) { - delete m_msg; - m_msg = nullptr; +void RuleWithActions::addDefaultAction(std::shared_ptr a) { + + actions::ActionWithRunTimeString *arts = dynamic_cast(a.get()); + if (arts != nullptr) { + a = std::unique_ptr(arts->clone()); + arts = dynamic_cast(a.get()); + arts->populate(this); } - while (m_transformations.empty() == false) { - auto *a = m_transformations.back(); - m_transformations.pop_back(); - delete a; + + if (dynamic_cast(a.get())) { + ActionTypeRuleMetaData *conf = dynamic_cast(a.get()); + conf->configure(this); + return; } - while (m_actionsRuntimePos.empty() == false) { - auto *a = m_actionsRuntimePos.back(); - m_actionsRuntimePos.pop_back(); - delete a; + + if (dynamic_cast(a.get())) { + m_defaultActionLogData.reset(dynamic_cast(a.get())); + } else if (dynamic_cast(a.get())) { + m_defaultActionMsg.reset(dynamic_cast(a.get())); + } else if (dynamic_cast(a.get())) { + actions::SetVar *var = dynamic_cast(a.get()); + m_actionsSetVar.push_back(std::unique_ptr(var)); + } else if (dynamic_cast(a.get())) { + m_defaultActionActionsTag.push_back(std::dynamic_pointer_cast(a)); + } else if (dynamic_cast(a.get())) { + m_defaultActionActionsRuntimePos.push_back(std::dynamic_pointer_cast(a)); + m_defaultContainsStaticBlockAction = true; + } else if (std::dynamic_pointer_cast(a) != NULL) { + m_defaultActionDisruptiveAction = std::dynamic_pointer_cast(a); + } else { + m_defaultActionActionsRuntimePos.push_back(std::dynamic_pointer_cast(a)); } - while (m_actionsSetVar.empty() == false) { - auto *a = m_actionsSetVar.back(); - m_actionsSetVar.pop_back(); - delete a; +} + +void RuleWithActions::addAction(actions::Action *a) { + actions::ActionWithRunTimeString *arts = dynamic_cast(a); + if (arts != nullptr) { + a = arts->clone(); + arts = dynamic_cast(a); + arts->populate(this); } - while (m_actionsTag.empty() == false) { - auto *a = m_actionsTag.back(); - m_actionsTag.pop_back(); + + if (dynamic_cast(a)) { + ActionTypeRuleMetaData *conf = dynamic_cast(a); + conf->configure(this); delete a; + return; } - if (m_disruptiveAction != nullptr) { - delete m_disruptiveAction; - m_disruptiveAction = nullptr; - } -} - -bool RuleWithActions::evaluate(Transaction *transaction) { - RuleMessage rm(this, transaction); - std::shared_ptr rm2 = std::make_shared(&rm); - return evaluate(transaction, rm2); + if (dynamic_cast(a)) { + m_logData = std::unique_ptr(dynamic_cast(a)); + } else if (dynamic_cast(a)) { + m_msg = std::unique_ptr(dynamic_cast(a)); + } else if (dynamic_cast(a)) { + actions::SetVar *var = dynamic_cast(a); + m_actionsSetVar.push_back(std::unique_ptr(var)); + } else if (dynamic_cast(a)) { + m_actionsTag.push_back(std::unique_ptr(dynamic_cast(a))); + } else if (dynamic_cast(a)) { + m_actionsRuntimePos.push_back(std::unique_ptr(dynamic_cast(a))); + m_containsStaticBlockAction = true; + } else if (dynamic_cast(a)) { + m_XmlNSs.push_back(std::unique_ptr(dynamic_cast(a))); + } else if (dynamic_cast(a) != NULL) { + m_disruptiveAction = std::unique_ptr(dynamic_cast(a)); + } else { + m_actionsRuntimePos.push_back(std::unique_ptr(dynamic_cast(a))); + } } -bool RuleWithActions::evaluate(Transaction *transaction, - std::shared_ptr ruleMessage) { +RuleWithActions::~RuleWithActions() { } - /* Rule evaluate is pure virtual. - * - * Rule::evaluate(transaction, ruleMessage); - */ +bool RuleWithActions::evaluate(Transaction *transaction) const { /* Matched vars needs to be clear at every new rule execution */ transaction->m_matched.clear(); @@ -189,193 +198,129 @@ bool RuleWithActions::evaluate(Transaction *transaction, } -void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans, - bool *containsBlock, std::shared_ptr ruleMessage) { +void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans) const { - for (actions::SetVar *a : m_actionsSetVar) { + for (actions::SetVar *a : getSetVarsActionsPtr()) { ms_dbg_a(trans, 4, "Running [independent] (non-disruptive) " \ - "action: " + *a->m_name.get()); + "action: " + *a->getName()); - a->evaluate(this, trans); - } - - for (auto &b : - trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) { - if (m_ruleId != b.first) { - continue; - } - actions::Action *a = dynamic_cast(b.second.get()); - if (a->isDisruptive() == true && *a->m_name.get() == "block") { - ms_dbg_a(trans, 9, "Rule contains a `block' action"); - *containsBlock = true; - } else if (*a->m_name.get() == "setvar") { - ms_dbg_a(trans, 4, "Running [independent] (non-disruptive) " \ - "action: " + *a->m_name.get()); - a->evaluate(this, trans, ruleMessage); - } - } - - if (m_severity) { - m_severity->evaluate(this, trans, ruleMessage); + a->execute(trans); } if (m_logData) { - m_logData->evaluate(this, trans, ruleMessage); + m_logData->execute(trans); + } else if (m_defaultActionLogData) { + m_defaultActionLogData->execute(trans); } if (m_msg) { - m_msg->evaluate(this, trans, ruleMessage); + m_msg->execute(trans); + } else if (m_defaultActionMsg) { + m_defaultActionMsg->execute(trans); } } -void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans, - bool containsBlock, std::shared_ptr ruleMessage) { +void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans) const { bool disruptiveAlreadyExecuted = false; - for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) { - if (a.get()->action_kind != actions::Action::RunTimeOnlyIfMatchKind) { - continue; - } - if (!a.get()->isDisruptive()) { - executeAction(trans, containsBlock, ruleMessage, a.get(), true); - } - } - - for (actions::Tag *a : this->m_actionsTag) { + for (actions::Tag *a : getTagsActionPtr()) { ms_dbg_a(trans, 4, "Running (non-disruptive) action: " \ - + *a->m_name.get()); - a->evaluate(this, trans, ruleMessage); + + a->getTagName(trans)); + a->execute(trans); } + /** + * + * FIXME: SecRuleUpdateActionBy should be runtime + * + */ for (auto &b : trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) { if (m_ruleId != b.first) { continue; } - actions::Action *a = dynamic_cast(b.second.get()); - executeAction(trans, containsBlock, ruleMessage, a, false); - disruptiveAlreadyExecuted = true; + ActionWithExecution *a = dynamic_cast(b.second.get()); + if (dynamic_cast(a) != NULL) { + trans->messageGetLast()->setRule(this); + } + executeAction(trans, a, false); + if (dynamic_cast(a) != NULL) { + disruptiveAlreadyExecuted = true; + } } - for (Action *a : this->m_actionsRuntimePos) { - if (!a->isDisruptive() + for (auto &a : getMatchActionsPtr()) { + if (!dynamic_cast(a) != NULL && !(disruptiveAlreadyExecuted && dynamic_cast(a))) { - executeAction(trans, containsBlock, ruleMessage, a, false); + executeAction(trans, a, false); } } if (!disruptiveAlreadyExecuted && m_disruptiveAction != nullptr) { - executeAction(trans, containsBlock, ruleMessage, - m_disruptiveAction, false); + executeAction(trans, + m_disruptiveAction.get(), false); + } else if (!disruptiveAlreadyExecuted && hasBlockAction() + && m_defaultActionDisruptiveAction != nullptr) { + executeAction(trans, + m_defaultActionDisruptiveAction.get(), false); } } void RuleWithActions::executeAction(Transaction *trans, - bool containsBlock, std::shared_ptr ruleMessage, - Action *a, bool defaultContext) { - if (a->isDisruptive() == false && *a->m_name.get() != "block") { - ms_dbg_a(trans, 9, "Running " \ - "action: " + *a->m_name.get()); - a->evaluate(this, trans, ruleMessage); - return; - } + ActionWithExecution *a, bool defaultContext) { + ms_dbg_a(trans, 9, "Running action: " + *a->getName()); + a->execute(trans); +} + - if (defaultContext && !containsBlock) { - ms_dbg_a(trans, 4, "Ignoring action: " + *a->m_name.get() + \ +void RuleWithActions::executeAction(Transaction *trans, + ActionDisruptive *a, bool defaultContext) const { + if (defaultContext && !hasBlockAction()) { + ms_dbg_a(trans, 4, "Ignoring action: " + *a->getName() + \ " (rule does not cotains block)"); return; } if (trans->getRuleEngineState() == RulesSet::EnabledRuleEngine) { - ms_dbg_a(trans, 4, "Running (disruptive) action: " + *a->m_name.get() + \ - "."); - a->evaluate(this, trans, ruleMessage); + ms_dbg_a(trans, 4, "Running (disruptive) action: " + \ + *a->getName() + "."); + ActionWithExecution *ae = dynamic_cast(a); + ae->execute(trans); return; } - ms_dbg_a(trans, 4, "Not running any disruptive action (or block): " \ - + *a->m_name.get() + ". SecRuleEngine is not On."); + ms_dbg_a(trans, 4, "Not running disruptive action: " \ + + *a->getName() + ". SecRuleEngine is not On."); } -inline void RuleWithActions::executeTransformation( - actions::transformations::Transformation *a, - std::shared_ptr *value, +void RuleWithActions::executeTransformations( Transaction *trans, - TransformationResults *ret, - std::string *path, - int *nth) const { - - std::string *oldValue = (*value).get(); - std::string newValue = a->evaluate(*oldValue, trans); - - if (newValue != *oldValue) { - std::shared_ptr u(new std::string(newValue)); - if (m_containsMultiMatchAction) { - ret->push_back(std::make_pair(u, a->m_name)); - (*nth)++; - } - *value = u; - } + const std::string &in, + TransformationsResults &results) const { + int none = 0; - if (path->empty()) { - path->append(*a->m_name.get()); - } else { - path->append("," + *a->m_name.get()); - } + ModSecString ssin; + ssin.assign(in.c_str(), in.size()); + results.push_back(TransformationResult(&ssin)); - ms_dbg_a(trans, 9, " T (" + \ - std::to_string(*nth) + ") " + \ - *a->m_name.get() + ": \"" + \ - utils::string::limitTo(80, newValue) +"\""); -} -void RuleWithActions::executeTransformations( - Transaction *trans, const std::string &in, TransformationResults &ret) { - int none = 0; - int transformations = 0; std::string path(""); std::shared_ptr value = std::shared_ptr(new std::string(in)); - if (m_containsMultiMatchAction == true) { - /* keep the original value */ - ret.push_back(std::make_pair( - std::shared_ptr(new std::string(*value)), - std::shared_ptr(new std::string(path)))); - } - - for (Action *a : m_transformations) { - if (a->m_isNone) { + for (Transformation *action : getTransformationPtr()) { + if (dynamic_cast(action)) { none++; } } - // Check for transformations on the SecDefaultAction - // Notice that first we make sure that won't be a t:none - // on the target rule. - if (none == 0) { - for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) { - if (a->action_kind \ - != actions::Action::RunTimeBeforeMatchAttemptKind) { - continue; - } - - // FIXME: here the object needs to be a transformation already. - Transformation *t = dynamic_cast(a.get()); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); - } - } - - for (Transformation *a : m_transformations) { + for (Transformation *t : getTransformationPtr()) { if (none == 0) { - Transformation *t = dynamic_cast(a); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + executeTransformation(trans, &results, t); } - if (a->m_isNone) { + if (dynamic_cast(t)) { none--; } } @@ -383,167 +328,86 @@ void RuleWithActions::executeTransformations( // FIXME: It can't be something different from transformation. Sort this // on rules compile time. for (auto &b : - trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) { + trans->m_rules->m_exceptions.m_action_transformation_update_target_by_id) { if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); - if (a->m_isNone) { + Transformation *t = b.second.get(); + if (dynamic_cast(t)) { none++; } } for (auto &b : - trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) { + trans->m_rules->m_exceptions.m_action_transformation_update_target_by_id) { if (m_ruleId != b.first) { continue; } - Transformation *a = dynamic_cast(b.second.get()); + Transformation *t = b.second.get(); if (none == 0) { - Transformation *t = dynamic_cast(a); - executeTransformation(t, &value, trans, &ret, &path, - &transformations); + executeTransformation(trans, &results, t); } - if (a->m_isNone) { + if (dynamic_cast(t)) { none--; } } +} - if (m_containsMultiMatchAction == true) { - ms_dbg_a(trans, 9, "multiMatch is enabled. " \ - + std::to_string(ret.size()) + \ - " values to be tested."); - } - if (!m_containsMultiMatchAction) { - ret.push_back(std::make_pair( - std::shared_ptr(new std::string(*value)), - std::shared_ptr(new std::string(path)))); - } + +void RuleWithActions::executeTransformation( + Transaction *transaction, + TransformationsResults *ret, + Transformation *transformation) { + executeTransformation( + transaction, + *ret->back().getAfter(), + ret, + transformation + ); } -bool RuleWithActions::containsTag(const std::string& name, Transaction *t) { - for (auto &tag : m_actionsTag) { - if (tag != NULL && tag->getName(t) == name) { - return true; - } - } - return false; -} +void RuleWithActions::executeTransformation( + Transaction *transaction, + ModSecString &in, + TransformationsResults *ret, + Transformation *transformation) { + ModSecString out; + transformation->execute(transaction, in, out); -bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) { - return m_msg && m_msg->data(t) == name; + ms_dbg_a(transaction, 9, " T (" + std::to_string(ret->size() - 1) + ") " + \ + *transformation->getName() + ": \"" + \ + utils::string::limitTo(80, out.c_str()) + "\""); + + ret->push_back( + TransformationResult( + out, + transformation->getName() + ) + ); } -std::vector RuleWithActions::getActionsByName(const std::string& name, - Transaction *trans) { - std::vector ret; - for (auto &z : m_actionsRuntimePos) { - if (*z->m_name.get() == name) { - ret.push_back(z); - } - } - for (auto &z : m_transformations) { - if (*z->m_name.get() == name) { - ret.push_back(z); - } - } - for (auto &b : - trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) { - if (m_ruleId != b.first) { - continue; - } - actions::Action *z = dynamic_cast(b.second.get()); - if (*z->m_name.get() == name) { - ret.push_back(z); - } - } - for (auto &b : - trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) { - if (m_ruleId != b.first) { - continue; - } - actions::Action *z = dynamic_cast(b.second.get()); - if (*z->m_name.get() == name) { - ret.push_back(z); +bool RuleWithActions::containsTag(const std::string& name, Transaction *t) const { + for (auto &tag : getTagsAction()) { + if (tag != NULL && tag->getTagName(t) == name) { + return true; } } - return ret; + return false; } -void RuleWithActions::performLogging(Transaction *trans, - std::shared_ptr ruleMessage, - bool lastLog, - bool chainedParentNull) { - - /* last rule in the chain. */ - bool isItToBeLogged = ruleMessage->m_saveMessage; - /** - * - * RuleMessage is stacked allocated for the rule execution, - * anything beyond this may lead to invalid pointer access. - * - * In case of a warning, o set of messages is saved to be read - * at audit log generation. Therefore demands a copy here. - * - * FIXME: Study an way to avoid the copy. - * - **/ - if (lastLog) { - if (chainedParentNull) { - isItToBeLogged = (ruleMessage->m_saveMessage && (m_chainedRuleParent == nullptr)); - if (isItToBeLogged && !hasMultimatch()) { - /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); - - /* error */ - if (!ruleMessage->m_isDisruptive) { - trans->serverLog(ruleMessage); - } - } - } else if (hasBlockAction() && !hasMultimatch()) { - /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); - /* error */ - if (!ruleMessage->m_isDisruptive) { - trans->serverLog(ruleMessage); - } - } else { - if (isItToBeLogged && !hasMultimatch() - && !ruleMessage->m_message.empty()) { - /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage); - - /* error */ - if (!ruleMessage->m_isDisruptive) { - trans->serverLog(ruleMessage); - } - } - } - } else { - if (hasMultimatch() && isItToBeLogged) { - /* warn */ - trans->m_rulesMessages.push_back(*ruleMessage.get()); - - /* error */ - if (!ruleMessage->m_isDisruptive) { - trans->serverLog(ruleMessage); - } - - RuleMessage *rm = new RuleMessage(this, trans); - rm->m_saveMessage = ruleMessage->m_saveMessage; - ruleMessage.reset(rm); - } - } +bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) const { + return m_msg && m_msg->getEvaluatedRunTimeString(t) == name; } -std::string RuleWithActions::logData(Transaction *t) { return m_logData->data(t); } -std::string RuleWithActions::msg(Transaction *t) { return m_msg->data(t); } -int RuleWithActions::severity() const { return m_severity->m_severity; } + +std::string RuleWithActions::getLogData(Transaction *t) const { return m_logData->getEvaluatedRunTimeString(t); } +std::string RuleWithActions::getMessage(Transaction *t) const { return m_msg->getEvaluatedRunTimeString(t); } + } // namespace modsecurity diff --git a/src/rule_with_actions.h b/src/rule_with_actions.h new file mode 100644 index 0000000000..4139c32893 --- /dev/null +++ b/src/rule_with_actions.h @@ -0,0 +1,621 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#endif + +#ifndef SRC_RULE_WITH_ACTIONS_H_ +#define SRC_RULE_WITH_ACTIONS_H_ + +#include "modsecurity/transaction.h" +#include "modsecurity/modsecurity.h" +#include "modsecurity/variable_value.h" +#include "modsecurity/rule.h" +#include "modsecurity/actions/action.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/action_with_execution.h" +#include "src/actions/disruptive/disruptive_action.h" + + +#ifdef __cplusplus + +namespace modsecurity { + +namespace actions { +class Action; +class Severity; +class LogData; +class Msg; +class Rev; +class SetVar; +class Tag; +class XmlNS; +namespace transformations { +class Transformation; +} +} + +using Transformation = actions::transformations::Transformation; +using Transformations = std::vector >; +using TransformationsPtr = std::vector; + +using Actions = std::vector; +using ActionWithExecution = actions::ActionWithExecution; +using ActionTypeRuleMetaData = actions::ActionTypeRuleMetaData; +using ActionDisruptive = actions::disruptive::ActionDisruptive; + +using MatchActions = std::vector >; +using MatchActionsPtr = std::vector; + +using Tags = std::vector >; +using TagsPtr = std::vector; + +using SetVars = std::vector >; +using SetVarsPtr = std::vector; + +using XmlNSs = std::vector >; +using XmlNSsPtr = std::vector; + + +class TransformationResult { + public: + TransformationResult( + ModSecString &after, + const std::string *transformation = nullptr) + : m_after(after), + m_transformation(transformation) { }; + + explicit TransformationResult( + ModSecString *after) + : m_after(*after), + m_transformation(nullptr) { }; + + TransformationResult(const TransformationResult &t2) + : m_after(t2.m_after), + m_transformation(t2.m_transformation) { }; + + + ModSecString *getAfter() { + return &m_after; + } + + + const std::string *getTransformationName() const { + return m_transformation; + } + + + private: + ModSecString m_after; + const std::string *m_transformation; +}; + +using TransformationsResults = std::list; + + +class RuleWithActions : public Rule { + public: + int SEVERITY_NOT_SET = 10; + int ACCURACY_NOT_SET = 10; + int MATURITY_NOT_SET = 10; + + RuleWithActions( + Actions *a, + Transformations *t, + std::unique_ptr fileName, + int lineNumber); + ~RuleWithActions(); + + RuleWithActions(const RuleWithActions &r) + : Rule(r), + m_ruleId(r.m_ruleId), + m_chainedRuleChild(r.m_chainedRuleChild), + m_chainedRuleParent(r.m_chainedRuleParent), + m_disruptiveAction(r.m_disruptiveAction), + m_logData(r.m_logData), + m_msg(r.m_msg), + m_actionsRuntimePos(r.m_actionsRuntimePos), + m_actionsSetVar(r.m_actionsSetVar), + m_actionsTag(r.m_actionsTag), + m_XmlNSs(r.m_XmlNSs), + m_defaultActionDisruptiveAction(r.m_defaultActionDisruptiveAction), + m_defaultActionLogData(r.m_defaultActionLogData), + m_defaultActionMsg(r.m_defaultActionMsg), + m_defaultActionActionsRuntimePos(r.m_defaultActionActionsRuntimePos), + m_defaultActionActionsSetVar(r.m_defaultActionActionsSetVar), + m_defaultActionActionsTag(r.m_defaultActionActionsTag), + m_transformations(r.m_transformations), + m_defaultTransformations(r.m_defaultTransformations), + m_severity(r.m_severity), + m_revision(r.m_revision), + m_version(r.m_version), + m_accuracy(r.m_accuracy), + m_maturity(r.m_maturity), + m_containsCaptureAction(r.m_containsCaptureAction), + m_containsLogAction(r.m_containsLogAction), + m_containsNoLogAction(r.m_containsNoLogAction), + m_containsAuditLogAction(r.m_containsAuditLogAction), + m_containsNoAuditLogAction(r.m_containsNoAuditLogAction), + m_containsMultiMatchAction(r.m_containsMultiMatchAction), + m_containsStaticBlockAction(r.m_containsStaticBlockAction), + m_defaultSeverity(r.m_defaultSeverity), + m_defaultRevision(r.m_defaultRevision), + m_defaultVersion(r.m_defaultVersion), + m_defaultAccuracy(r.m_defaultAccuracy), + m_defaultMaturity(r.m_defaultMaturity), + m_defaultContainsCaptureAction(r.m_defaultContainsCaptureAction), + m_defaultContainsLogAction(r.m_defaultContainsLogAction), + m_defaultContainsNoLogAction(r.m_defaultContainsNoLogAction), + m_defaultContainsAuditLogAction(r.m_defaultContainsAuditLogAction), + m_defaultContainsNoAuditLogAction(r.m_defaultContainsNoAuditLogAction), + m_defaultContainsMultiMatchAction(r.m_defaultContainsMultiMatchAction), + m_defaultContainsStaticBlockAction(r.m_defaultContainsStaticBlockAction), + m_isChained(r.m_isChained) { + // Verificar actions e fazer copia. + }; + + RuleWithActions &operator=(const RuleWithActions& r) { + // Verificar actions e fazer copia. + Rule::operator = (r); + m_ruleId = r.m_ruleId; + m_chainedRuleChild = r.m_chainedRuleChild; + m_chainedRuleParent = r.m_chainedRuleParent; + m_disruptiveAction = r.m_disruptiveAction; + m_logData = r.m_logData; + m_msg = r.m_msg; + m_actionsRuntimePos = r.m_actionsRuntimePos; + m_actionsSetVar = r.m_actionsSetVar; + m_actionsTag = r.m_actionsTag; + m_XmlNSs = r.m_XmlNSs; + m_defaultActionDisruptiveAction = r.m_defaultActionDisruptiveAction; + m_defaultActionLogData = r.m_defaultActionLogData; + m_defaultActionMsg = r.m_defaultActionMsg; + m_defaultActionActionsRuntimePos = r.m_defaultActionActionsRuntimePos; + m_defaultActionActionsSetVar = r.m_defaultActionActionsSetVar; + m_defaultActionActionsTag = r.m_defaultActionActionsTag; + m_transformations = r.m_transformations; + m_defaultTransformations = r.m_defaultTransformations; + m_severity = r.m_severity; + m_revision = r.m_revision; + m_version = r.m_version; + m_accuracy = r.m_accuracy; + m_maturity = r.m_maturity; + m_containsCaptureAction = r.m_containsCaptureAction; + m_containsLogAction = r.m_containsLogAction; + m_containsNoLogAction = r.m_containsNoLogAction; + m_containsAuditLogAction = r.m_containsAuditLogAction; + m_containsNoAuditLogAction = r.m_containsNoAuditLogAction; + m_containsMultiMatchAction = r.m_containsMultiMatchAction; + m_containsStaticBlockAction = r.m_containsStaticBlockAction; + m_defaultSeverity = r.m_defaultSeverity; + m_defaultRevision = r.m_defaultRevision; + m_defaultVersion = r.m_defaultVersion; + m_defaultAccuracy = r.m_defaultAccuracy; + m_defaultMaturity = r.m_defaultMaturity; + m_defaultContainsCaptureAction = r.m_defaultContainsCaptureAction; + m_defaultContainsLogAction = r.m_defaultContainsLogAction; + m_defaultContainsNoLogAction = r.m_defaultContainsNoLogAction; + m_defaultContainsAuditLogAction = r.m_defaultContainsAuditLogAction; + m_defaultContainsNoAuditLogAction = r.m_defaultContainsNoAuditLogAction; + m_defaultContainsMultiMatchAction = r.m_defaultContainsMultiMatchAction; + m_defaultContainsStaticBlockAction = r.m_defaultContainsStaticBlockAction; + m_isChained = r.m_isChained; + return *this; + } + + + virtual bool evaluate(Transaction *transaction) const override; + + + void executeActionsIndependentOfChainedRuleResult( + Transaction *trasn) const; + + void executeActionsAfterFullMatch( + Transaction *trasn) const; + + static void executeAction(Transaction *trans, + ActionWithExecution *a, + bool context); + + void executeAction(Transaction *trans, + ActionDisruptive *a, + bool context) const; + + static void executeTransformation( + Transaction *transaction, + TransformationsResults *ret, + Transformation *transformation); + + static void executeTransformation( + Transaction *transaction, + ModSecString &in, + TransformationsResults *ret, + Transformation *transformation); + + void executeTransformations( + Transaction *transaction, + const std::string &value, + TransformationsResults &results) const; + + void addAction(actions::Action *a); + void addTransformation(std::shared_ptr t) { + m_transformations.push_back(t); + } + void addDefaultAction(std::shared_ptr); + void addDefaultTransformation(std::shared_ptr t) { + m_defaultTransformations.push_back(t); + } + + + std::vector getActionsByName(const std::string& name, + Transaction *t); + bool containsTag(const std::string& name, Transaction *t) const; + bool containsMsg(const std::string& name, Transaction *t) const; + + + void clearDefaultActions() { + m_defaultSeverity = SEVERITY_NOT_SET; + m_defaultRevision = ""; + m_defaultVersion = ""; + m_defaultAccuracy = ACCURACY_NOT_SET; + m_defaultMaturity = MATURITY_NOT_SET; + m_defaultContainsCaptureAction = false; + m_defaultContainsLogAction = false; + m_defaultContainsNoLogAction = false; + m_defaultContainsMultiMatchAction = false; + m_defaultContainsStaticBlockAction = false; + m_defaultActionLogData = nullptr; + m_defaultActionMsg = nullptr; + m_defaultActionActionsSetVar.clear(); + m_defaultActionActionsTag.clear(); + m_defaultActionActionsRuntimePos.clear(); + m_defaultActionDisruptiveAction = nullptr; + m_defaultActionActionsRuntimePos.clear(); + m_defaultTransformations.clear(); + } + + Transformations getTransformation() const { + Transformations dst; + for (auto &a : m_defaultTransformations) { + dst.push_back(a); + } + for (auto &a : m_transformations) { + dst.push_back(a); + } + return dst; + } + + TransformationsPtr getTransformationPtr() const { + TransformationsPtr dst; + for (auto &a : m_defaultTransformations) { + dst.push_back(a.get()); + } + for (auto &a : m_transformations) { + dst.push_back(a.get()); + } + return dst; + } + + SetVars getSetVarsActions() const { + SetVars dst; + for (auto &a : m_defaultActionActionsSetVar) { + dst.push_back(a); + } + for (auto &a : m_actionsSetVar) { + dst.push_back(a); + } + return dst; + } + + SetVarsPtr getSetVarsActionsPtr() const { + SetVarsPtr dst; + for (auto &a : m_defaultActionActionsSetVar) { + dst.push_back(a.get()); + } + for (auto &a : m_actionsSetVar) { + dst.push_back(a.get()); + } + return dst; + } + + MatchActionsPtr getMatchActionsPtr() const { + MatchActionsPtr dst; + for (auto &a : m_defaultActionActionsRuntimePos) { + dst.push_back(a.get()); + } + for (auto &a : m_actionsRuntimePos) { + dst.push_back(a.get()); + } + return dst; + } + + MatchActions getMatchActions() const { + MatchActions dst; + for (auto &a : m_defaultActionActionsRuntimePos) { + dst.push_back(a); + } + for (auto &a : m_actionsRuntimePos) { + dst.push_back(a); + } + return dst; + } + + inline bool hasChainAction() const { return m_isChained == true; } + inline void setHasChainAction(bool b) { m_isChained = b; } + inline bool hasChainedParent() const { return m_chainedRuleParent != nullptr; } + inline bool hasChainedChild() const { return m_chainedRuleChild.get() != nullptr; } + + inline void setHasCaptureAction(bool b) { m_containsCaptureAction = b; } + inline bool hasCaptureAction() const { return m_containsCaptureAction || m_defaultContainsCaptureAction; } + + inline bool hasDisruptiveAction() const { return m_disruptiveAction != nullptr || m_defaultActionDisruptiveAction != nullptr; } + inline void setDisruptiveAction(const std::shared_ptr &a) { m_disruptiveAction = a; } + inline std::shared_ptr getDisruptiveAction() const { return m_disruptiveAction; } + + inline bool hasBlockAction() const { return m_containsStaticBlockAction || m_defaultContainsStaticBlockAction; } + inline void setHasBlockAction(bool b) { m_containsStaticBlockAction = b; } + + inline void setHasMultimatchAction(bool b) { m_containsMultiMatchAction = b; } + inline bool hasMultimatchAction() const { return m_containsMultiMatchAction || m_defaultContainsMultiMatchAction; } + + inline bool hasAuditLogAction() const { return m_containsAuditLogAction == true; } + inline void setHasAuditLogAction(bool b) { m_containsAuditLogAction = b; } + inline bool hasNoAuditLogAction() const { return m_containsNoAuditLogAction == true; } + inline void setHasNoAuditLogAction(bool b) { m_containsNoAuditLogAction = b; } + + inline bool hasLogAction() const { return m_containsLogAction == true; } + inline void setHasLogAction(bool b) { m_containsLogAction = b; } + inline bool hasNoLogAction() const { return m_containsNoLogAction == true; } + inline void setHasNoLogAction(bool b) { m_containsNoLogAction = b; } + + + inline bool isItToBeLogged() const noexcept { + if (m_containsNoLogAction) { + return false; + } + + if (m_defaultContainsNoLogAction && !m_containsLogAction) { + return false; + } + + return true; + } + + + inline bool isItToBeAuditLogged() const noexcept { + if (!isItToBeLogged() && !m_containsAuditLogAction + && !m_defaultContainsAuditLogAction) { + return false; + } + + if (m_containsNoAuditLogAction) { + return false; + } + + if (m_defaultContainsNoLogAction && !m_containsAuditLogAction) { + return false; + } + + return true; + } + + + inline bool hasLogDataAction() const { return m_logData != nullptr || m_defaultActionLogData != nullptr; } + inline std::shared_ptr getLogDataAction() const { return m_logData; } + std::string getLogData(/*const */Transaction *t) const; + inline void setLogDataAction(const std::shared_ptr &data) { m_logData = data; } + + inline bool hasMessageAction() const { return m_msg != nullptr || m_defaultActionMsg != nullptr; } + inline std::shared_ptr getMessageAction() const { return m_msg; } + inline void setMessageAction(const std::shared_ptr &msg) { m_msg = msg; } + std::string getMessage(/*const */Transaction *t) const; + + + inline bool hasSeverityAction() const { return m_severity != SEVERITY_NOT_SET || m_defaultSeverity != SEVERITY_NOT_SET; } + inline int getSeverity() const { return (m_severity != SEVERITY_NOT_SET)?m_severity:m_defaultSeverity; } + inline void setDefaultActionSeverity(unsigned int severity) { m_defaultSeverity = severity; } + inline void setSeverity(unsigned int severity) { m_severity = severity; } + + inline bool hasRevisionAction() const { return m_revision != ""; } + inline const std::string getRevision() const { return m_revision; }; + inline void setRevision(const std::string &revision) { m_revision.assign(revision); } + + inline bool hasVersionAction() const { return m_version != ""; } + inline const std::string getVersion() const { return m_version; }; + inline void setVersion(const std::string &version) { m_version.assign(version); } + + inline bool hasAccuracyAction() const { return m_accuracy != ACCURACY_NOT_SET || m_defaultAccuracy != ACCURACY_NOT_SET; } + inline const int getAccuracy() const { return m_accuracy; } + inline void setAccuracy(unsigned int accuracy) { m_accuracy = accuracy; } + + inline bool hasMaturityAction() const { return m_maturity != MATURITY_NOT_SET || m_defaultMaturity != MATURITY_NOT_SET; } + inline const int getMaturity() const { return m_maturity; } + inline void setDefaultActionMaturity(unsigned int maturity) { m_defaultMaturity = maturity; } + inline void setMaturity(unsigned int maturity) { m_maturity = maturity; } + + inline bool hasTagAction() const { return m_actionsTag.size() > 0; } + inline void setTags(Tags tags) { + for (auto tag : tags) { + m_actionsTag.push_back(tag); + } + } + inline void cleanTags() { + m_actionsTag.clear(); + } + Tags getTagsAction() const { + Tags dst; + for (auto &a : m_defaultActionActionsTag) { + dst.push_back(a); + } + for (auto &a : m_actionsTag) { + dst.push_back(a); + } + return dst; + } + + TagsPtr getTagsActionPtr() const { + TagsPtr dst; + for (auto &a : m_defaultActionActionsTag) { + dst.push_back(a.get()); + } + for (auto &a : m_actionsTag) { + dst.push_back(a.get()); + } + return dst; + } + + inline RuleId getId() const { return m_ruleId; } + void setId(int id) { + m_ruleId = id; + } + + void setChainedNext(std::unique_ptr r) { + m_chainedRuleChild = std::move(r); + } + + inline RuleWithActions *getChainedNext() const { + return m_chainedRuleChild.get(); + } + + void setChainedParent(RuleWithActions *r) { + m_chainedRuleParent = r; + } + + inline RuleWithActions *getChainedParent() { + return m_chainedRuleParent; + } + + XmlNSsPtr getXmlNSsPtr() const { + /** + * FIXME: this is not conteplating SecRuleUpdateActionBy* yet. + * + */ + XmlNSsPtr dst; + for (auto &a : m_XmlNSs) { + dst.push_back(a.get()); + } + + return dst; + } + + + virtual void dump(std::stringstream &out) const override { + out << "RuleWithActions" << std::endl; + } + + private: + RuleId m_ruleId; + + std::shared_ptr m_chainedRuleChild; + RuleWithActions *m_chainedRuleParent; + + /* actions */ + std::shared_ptr m_disruptiveAction; + std::shared_ptr m_logData; + std::shared_ptr m_msg; + MatchActions m_actionsRuntimePos; + SetVars m_actionsSetVar; + Tags m_actionsTag; + XmlNSs m_XmlNSs; + + /* actions || SecDefaultAction */ + std::shared_ptr m_defaultActionDisruptiveAction; + std::shared_ptr m_defaultActionLogData; + std::shared_ptr m_defaultActionMsg; + + MatchActions m_defaultActionActionsRuntimePos; + SetVars m_defaultActionActionsSetVar; + Tags m_defaultActionActionsTag; + + /* actions > transformations */ + Transformations m_transformations; + + /* actions > transformations || SecDefaultAction */ + Transformations m_defaultTransformations; + + + /* || */ + /** + * 0 - EMERGENCY: is generated from correlation of anomaly + * scoring data where there is an inbound + * attack and an outbound leakage. + * 1 - ALERT: is generated from correlation where there is + * an inbound attack and an outbound application + * level error. + * 2 - CRITICAL: Anomaly Score of 5. Is the highest severity + * level possible without correlation. It is + * normally generated by the web attack rules + * (40 level files). + * 3 - ERROR: Error - Anomaly Score of 4. Is generated mostly + * from outbound leakage rules (50 level files). + * 4 - WARNING: Anomaly Score of 3. Is generated by malicious + * client rules (35 level files). + * 5 - NOTICE: Anomaly Score of 2. Is generated by the Protocol + * policy and anomaly files. + * 6 - INFO + * 7 - DEBUG + **/ + unsigned int m_severity:3; + + std::string m_revision; + std::string m_version; + + /** + * 1-9 where 9 is very strong and 1 has many false positives + */ + unsigned int m_accuracy:3; + /** + * 1-9 where 9 is extensively tested and 1 is a brand new experimental rule + */ + unsigned int m_maturity:3; + + + bool m_containsCaptureAction:1; + bool m_containsLogAction:1; + bool m_containsNoLogAction:1; + bool m_containsAuditLogAction:1; + bool m_containsNoAuditLogAction:1; + bool m_containsMultiMatchAction:1; + bool m_containsStaticBlockAction:1; + + /* || SecDefaultAction */ + unsigned int m_defaultSeverity:3; + std::string m_defaultRevision; + std::string m_defaultVersion; + unsigned int m_defaultAccuracy:3; + unsigned int m_defaultMaturity:3; + bool m_defaultContainsCaptureAction:1; + bool m_defaultContainsLogAction:1; + bool m_defaultContainsNoLogAction:1; + bool m_defaultContainsAuditLogAction:1; + bool m_defaultContainsNoAuditLogAction:1; + bool m_defaultContainsMultiMatchAction:1; + bool m_defaultContainsStaticBlockAction:1; + + bool m_isChained:1; +}; + +} // namespace modsecurity +#endif + + +#endif // SRC_RULE_WITH_ACTIONS_H_ + diff --git a/src/rule_with_operator.cc b/src/rule_with_operator.cc index e4ab6a579f..39cae816a8 100644 --- a/src/rule_with_operator.cc +++ b/src/rule_with_operator.cc @@ -13,7 +13,6 @@ * */ -#include "modsecurity/rule_with_operator.h" #include @@ -41,6 +40,10 @@ #include "src/actions/set_var.h" #include "src/actions/block.h" #include "src/variables/variable.h" +#include "src/variables/rule.h" +#include "src/rule_with_operator.h" +#include "modsecurity/string_view.hpp" + namespace modsecurity { @@ -58,29 +61,27 @@ RuleWithOperator::RuleWithOperator(Operator *op, std::unique_ptr fileName, int lineNumber) : RuleWithActions(actions, transformations, std::move(fileName), lineNumber), - m_operator(op), - m_variables(_variables) { /* */ } + m_variables(std::unique_ptr(_variables)), + m_operator(std::unique_ptr(op)) { + for (auto &a : *m_variables.get()) { + variables::RuleVariable *vrule = dynamic_cast(a); + if (vrule != nullptr) { + std::cout << "here we are" << std::endl; + vrule->populate(this); + } + } + } -RuleWithOperator::~RuleWithOperator() { - if (m_operator != NULL) { - delete m_operator; - } - while (m_variables != NULL && m_variables->empty() == false) { - auto *a = m_variables->back(); - m_variables->pop_back(); - delete a; - } - if (m_variables != NULL) { - delete m_variables; - } +RuleWithOperator::~RuleWithOperator() { } -void RuleWithOperator::updateMatchedVars(Transaction *trans, const std::string &key, - const std::string &value) { +void RuleWithOperator::updateMatchedVars(Transaction *trans, + const std::string &key, + const bpstd::string_view &value) { ms_dbg_a(trans, 9, "Matched vars updated."); trans->m_variableMatchedVar.set(value, trans->m_variableOffset); trans->m_variableMatchedVarName.set(key, trans->m_variableOffset); @@ -90,7 +91,7 @@ void RuleWithOperator::updateMatchedVars(Transaction *trans, const std::string & } -void RuleWithOperator::cleanMatchedVars(Transaction *trans) { +inline void RuleWithOperator::cleanMatchedVars(Transaction *trans) { ms_dbg_a(trans, 9, "Matched vars cleaned."); trans->m_variableMatchedVar.unset(); trans->m_variableMatchedVars.unset(); @@ -99,9 +100,9 @@ void RuleWithOperator::cleanMatchedVars(Transaction *trans) { } - -bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string &key, - std::string value, std::shared_ptr ruleMessage) { +bool RuleWithOperator::executeOperatorAt(Transaction *trans, + const std::string &key, + const bpstd::string_view &value) const { #if MSC_EXEC_CLOCK_ENABLED clock_t begin = clock(); clock_t end; @@ -109,15 +110,12 @@ bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string & #endif bool ret; - ms_dbg_a(trans, 9, "Target value: \"" + utils::string::limitTo(80, - utils::string::toHexIfNeeded(value)) \ + ms_dbg_a(trans, 9, "Target value: \"" \ + + utils::string::limitTo(80, + utils::string::toHexIfNeeded(value.to_string())) \ + "\" (Variable: " + key + ")"); - ret = this->m_operator->evaluateInternal(trans, this, value, ruleMessage); - - if (ret == false) { - return false; - } + ret = m_operator->evaluateInternal(trans, this, value, trans->messageGetLast()); #if MSC_EXEC_CLOCK_ENABLED end = clock(); @@ -131,7 +129,7 @@ bool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string & void RuleWithOperator::getVariablesExceptions(Transaction *t, - variables::Variables *exclusion, variables::Variables *addition) { + variables::Variables *exclusion, variables::Variables *addition) const { for (auto &a : t->m_rules->m_exceptions.m_variable_update_target_by_tag) { if (containsTag(*a.first.get(), t) == false) { continue; @@ -161,7 +159,7 @@ void RuleWithOperator::getVariablesExceptions(Transaction *t, } for (auto &a : t->m_rules->m_exceptions.m_variable_update_target_by_id) { - if (m_ruleId != a.first) { + if (getId() != a.first) { continue; } Variable *b = a.second.get(); @@ -177,7 +175,7 @@ void RuleWithOperator::getVariablesExceptions(Transaction *t, inline void RuleWithOperator::getFinalVars(variables::Variables *vars, - variables::Variables *exclusion, Transaction *trans) { + variables::Variables *exclusion, Transaction *trans) const { variables::Variables addition; getVariablesExceptions(trans, exclusion, &addition); @@ -189,7 +187,7 @@ inline void RuleWithOperator::getFinalVars(variables::Variables *vars, if (std::find_if(trans->m_ruleRemoveTargetById.begin(), trans->m_ruleRemoveTargetById.end(), [&, variable, this](std::pair &m) -> bool { - return m.first == m_ruleId + return m.first == getId() && m.second == *variable->m_fullName.get(); }) != trans->m_ruleRemoveTargetById.end()) { continue; @@ -213,10 +211,9 @@ inline void RuleWithOperator::getFinalVars(variables::Variables *vars, } -bool RuleWithOperator::evaluate(Transaction *trans, - std::shared_ptr ruleMessage) { +bool RuleWithOperator::evaluate(Transaction *trans) const { bool globalRet = false; - variables::Variables *variables = this->m_variables; + variables::Variables *variables = m_variables.get(); bool recursiveGlobalRet; bool containsBlock = hasBlockAction(); std::string eparam; @@ -224,23 +221,22 @@ bool RuleWithOperator::evaluate(Transaction *trans, vars.reserve(4); variables::Variables exclusion; - RuleWithActions::evaluate(trans, ruleMessage); - + RuleWithActions::evaluate(trans); // FIXME: Make a class runTimeException to handle this cases. for (auto &i : trans->m_ruleRemoveById) { - if (m_ruleId != i) { + if (getId() != i) { continue; } - ms_dbg_a(trans, 9, "Rule id: " + std::to_string(m_ruleId) + + ms_dbg_a(trans, 9, "Rule id: " + std::to_string(getId()) + " was skipped due to a ruleRemoveById action..."); return true; } for (auto &i : trans->m_ruleRemoveByIdRange) { - if (!(i.first <= m_ruleId && i.second >= m_ruleId)) { + if (!(i.first <= getId() && i.second >= getId())) { continue; } - ms_dbg_a(trans, 9, "Rule id: " + std::to_string(m_ruleId) + + ms_dbg_a(trans, 9, "Rule id: " + std::to_string(getId()) + " was skipped due to a ruleRemoveById action..."); return true; } @@ -254,14 +250,14 @@ bool RuleWithOperator::evaluate(Transaction *trans, } else { eparam = "\"" + eparam + "\""; } - ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ + ms_dbg_a(trans, 4, "(Rule: " + std::to_string(getId()) \ + ") Executing operator \"" + getOperatorName() \ + "\" with param " \ + eparam \ + " against " \ + variables + "."); } else { - ms_dbg_a(trans, 4, "(Rule: " + std::to_string(m_ruleId) \ + ms_dbg_a(trans, 4, "(Rule: " + std::to_string(getId()) \ + ") Executing operator \"" + getOperatorName() \ + " against " \ + variables + "."); @@ -270,13 +266,16 @@ bool RuleWithOperator::evaluate(Transaction *trans, getFinalVars(&vars, &exclusion, trans); + std::vector> e; for (auto &var : vars) { - std::vector e; if (!var) { continue; } - var->evaluate(trans, this, &e); - for (const VariableValue *v : e) { + e.clear(); + var->evaluate(trans, &e); + for (const auto &vv : e) { + TransformationsResults transformationsResults; + const VariableValue *v = vv.get(); const std::string &value = v->getValue(); const std::string &key = v->getKeyWithCollection(); @@ -284,11 +283,9 @@ bool RuleWithOperator::evaluate(Transaction *trans, std::find_if(trans->m_ruleRemoveTargetById.begin(), trans->m_ruleRemoveTargetById.end(), [&, v, this](std::pair &m) -> bool { - return m.first == m_ruleId && m.second == v->getKeyWithCollection(); + return m.first == getId() && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetById.end() ) { - delete v; - v = NULL; continue; } if (exclusion.contains(v) || @@ -298,43 +295,55 @@ bool RuleWithOperator::evaluate(Transaction *trans, return containsTag(m.first, trans) && m.second == v->getKeyWithCollection(); }) != trans->m_ruleRemoveTargetByTag.end() ) { - delete v; - v = NULL; continue; } - TransformationResults values; - - executeTransformations(trans, value, values); + executeTransformations(trans, value, transformationsResults); - for (const auto &valueTemp : values) { + auto iter = transformationsResults.begin(); + if (!hasMultimatchAction()) { + iter = transformationsResults.end(); + std::advance(iter, -1); + } + while (iter != transformationsResults.end()) { bool ret; - std::string valueAfterTrans = std::move(*valueTemp.first); + auto &valueTemp = *iter; + bpstd::string_view view = *valueTemp.getAfter(); - ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage); + ret = executeOperatorAt(trans, key, view); if (ret == true) { - ruleMessage->m_match = m_operator->resolveMatchMessage(trans, + trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans, key, value); - for (auto &i : v->getOrigin()) { - ruleMessage->m_reference.append(i->toText()); + + for (const auto &i : v->getOrigin()) { + trans->messageGetLast()->m_reference.append(i.toText()); } - ruleMessage->m_reference.append(*valueTemp.second); - updateMatchedVars(trans, key, valueAfterTrans); - executeActionsIndependentOfChainedRuleResult(trans, - &containsBlock, ruleMessage); + auto iter2 = transformationsResults.begin(); + while (iter2 != transformationsResults.end()) { + if (iter2->getTransformationName()) { + trans->messageGetLast()->m_reference.append(*iter2->getTransformationName()); + } + /* + if (iter == iter2) { + break; + } else if (iter2->getTransformationName()) { + trans->messageGetLast()->m_reference.append(","); + } + */ + iter2++; + } - performLogging(trans, ruleMessage, false); + updateMatchedVars(trans, key, view); + executeActionsIndependentOfChainedRuleResult(trans); globalRet = true; } + + iter++; } - delete v; - v = NULL; } - e.clear(); - e.reserve(4); } if (globalRet == false) { @@ -344,19 +353,19 @@ bool RuleWithOperator::evaluate(Transaction *trans, } ms_dbg_a(trans, 4, "Rule returned 1."); - if (this->isChained() == false) { + if (this->hasChainAction() == false) { goto end_exec; } /* FIXME: this check should happens on the parser. */ - if (this->m_chainedRuleChild == nullptr) { + if (getChainedNext() == nullptr) { ms_dbg_a(trans, 4, "Rule is marked as chained but there " \ "isn't a subsequent rule."); goto end_clean; } ms_dbg_a(trans, 4, "Executing chained rule."); - recursiveGlobalRet = m_chainedRuleChild->evaluate(trans, ruleMessage); + recursiveGlobalRet = getChainedNext()->evaluate(trans); if (recursiveGlobalRet == true) { goto end_exec; @@ -366,10 +375,21 @@ bool RuleWithOperator::evaluate(Transaction *trans, return false; end_exec: - executeActionsAfterFullMatch(trans, containsBlock, ruleMessage); + executeActionsAfterFullMatch(trans); /* last rule in the chain. */ - performLogging(trans, ruleMessage, true, true); + trans->logMatchLastRuleOnTheChain(this); + + if (hasSeverityAction()) { + ms_dbg_a(trans, 9, "This rule severity is: " + \ + std::to_string(getSeverity()) + " current transaction is: " + \ + std::to_string(trans->m_highestSeverityAction)); + + if (trans->m_highestSeverityAction > getSeverity()) { + trans->m_highestSeverityAction = getSeverity(); + } + } + return true; } diff --git a/src/rule_with_operator.h b/src/rule_with_operator.h new file mode 100644 index 0000000000..106f21d2bb --- /dev/null +++ b/src/rule_with_operator.h @@ -0,0 +1,109 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#endif + +#ifndef SRC_RULE_WITH_OPERATOR_H_ +#define SRC_RULE_WITH_OPERATOR_H_ + +#include "modsecurity/transaction.h" +#include "modsecurity/modsecurity.h" +#include "modsecurity/variable_value.h" +#include "modsecurity/rule.h" +#include "src/rule_with_actions.h" +#include "src/variables/variable.h" +#include "src/operators/operator.h" +#include "modsecurity/string_view.hpp" + +#ifdef __cplusplus + +namespace modsecurity { + + +class RuleWithOperator : public RuleWithActions { + public: + RuleWithOperator(operators::Operator *op, + variables::Variables *variables, + std::vector *actions, + Transformations *transformations, + std::unique_ptr fileName, + int lineNumber); + + RuleWithOperator(const RuleWithOperator &op) + : RuleWithActions(op), + m_variables(op.m_variables), + m_operator(op.m_operator) + { }; + + RuleWithOperator &operator=(const RuleWithOperator& r) { + RuleWithActions::operator = (r); + m_variables = r.m_variables; + m_operator = r.m_operator; + return *this; + } + + virtual ~RuleWithOperator(); + + bool evaluate(Transaction *transaction) const override; + + void getVariablesExceptions(Transaction *t, + variables::Variables *exclusion, variables::Variables *addition) const; + inline void getFinalVars(variables::Variables *vars, + variables::Variables *eclusion, Transaction *trans) const; + + bool executeOperatorAt(Transaction *transaction, + const std::string &key, + const bpstd::string_view &value) const; + + static void updateMatchedVars(Transaction *transaction, + const std::string &key, + const bpstd::string_view &value); + + static void cleanMatchedVars(Transaction *trasn); + + std::string getOperatorName() const; + + virtual std::string getReference() const override { + return std::to_string(getId()); + } + + virtual void dump(std::stringstream &out) const override { + Rule::dump(out); + out << "# RuleWithOperator" << std::endl; + out << "SecRule "; + out << m_variables->getVariableNames() << " "; + out << "\"" << "@" << m_operator->m_op << " " << m_operator->m_param << "\""; + out << std::endl; + } + + private: + std::shared_ptr m_variables; + std::shared_ptr m_operator; +}; + + +} // namespace modsecurity +#endif + + +#endif // SRC_RULE_WITH_OPERATOR_H_ + diff --git a/src/rules.cc b/src/rules.cc new file mode 100644 index 0000000000..ff91e8b4f9 --- /dev/null +++ b/src/rules.cc @@ -0,0 +1,67 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "modsecurity/rules.h" +#include "src/rule_with_actions.h" + + +namespace modsecurity { + + +int Rules::append(Rules *from) { + m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end()); + if (!from->m_defaultActions.empty() || !from->m_defaultTransformations.empty()) { + m_defaultActions.clear(); + m_defaultTransformations.clear(); + for (auto &a : from->m_defaultActions) { + m_defaultActions.push_back(a); + } + for (auto &a : from->m_defaultTransformations) { + m_defaultTransformations.push_back(a); + } + } + return from->size(); +} + + +bool Rules::insert(const std::shared_ptr &rule) { + m_rules.push_back(rule); + return true; +} + + +size_t Rules::size() const { + return m_rules.size(); +} + + +std::shared_ptr Rules::operator[](int index) const { + return m_rules[index]; +} + + +std::shared_ptr Rules::at(int index) const { + return m_rules[index]; +} + + +void Rules::dump(std::stringstream &out) { + for (auto &r : m_rules) { + r->dump(out); + } +} + +} // namespace modsecurity + diff --git a/src/rules_exceptions.cc b/src/rules_exceptions.cc index 93b23a4382..aee9e8c0ea 100644 --- a/src/rules_exceptions.cc +++ b/src/rules_exceptions.cc @@ -19,6 +19,8 @@ #include "src/utils/string.h" #include "src/variables/variable.h" +#include "src/actions/action_type_rule_metadata.h" +#include "src/actions/transformations/transformation.h" namespace modsecurity { @@ -36,21 +38,26 @@ bool RulesExceptions::loadUpdateActionById(double id, std::string *error) { for (auto &a : *actions) { - if (a->action_kind == actions::Action::ConfigurationKind) { - std::cout << "General failure, action: " << a->m_name; + if (dynamic_cast(a.get())) { + std::cout << "General failure, action: " << *a->getName(); std::cout << " has not expected to be used with UpdateActionByID."; std::cout << std::endl; - } else if (a->action_kind - == actions::Action::RunTimeBeforeMatchAttemptKind) { - m_action_pre_update_target_by_id.emplace(std::pair>(id , std::move(a))); - } else if (a->action_kind == actions::Action::RunTimeOnlyIfMatchKind) { - m_action_pos_update_target_by_id.emplace(std::pair>(id , std::move(a))); - } else { - std::cout << "General failure, action: " << a->m_name; - std::cout << " has an unknown type." << std::endl; + continue; + } + + if (dynamic_cast(a.get())) { + actions::transformations::Transformation *t = dynamic_cast(a.get()); + m_action_transformation_update_target_by_id.emplace( + std::pair>(id, std::unique_ptr(t)) + ); + continue; } + + m_action_pos_update_target_by_id.emplace( + std::pair>(id , std::move(a)) + ); } return true; @@ -247,10 +254,10 @@ bool RulesExceptions::merge(RulesExceptions *from) { p.second)); } - for (auto &p : from->m_action_pre_update_target_by_id) { - m_action_pre_update_target_by_id.emplace( + for (auto &p : from->m_action_transformation_update_target_by_id) { + m_action_transformation_update_target_by_id.emplace( std::pair>(p.first, + std::shared_ptr>(p.first, p.second)); } diff --git a/src/rules_set.cc b/src/rules_set.cc index 89b2745b73..b4c64588af 100644 --- a/src/rules_set.cc +++ b/src/rules_set.cc @@ -18,8 +18,10 @@ #include #include #include +#include #include "modsecurity/rules_set.h" +#include "src/rule_marker.h" #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" #include "src/parser/driver.h" @@ -31,6 +33,46 @@ using modsecurity::Utils::HttpsClient; namespace modsecurity { + void Rules::fixDefaultActions(RulesWarnings *warnings, RulesErrors *errors) { + for (size_t i = 0; i < m_rules.size(); i++) { + auto &rule = m_rules[i]; + + RuleWithActions *r = dynamic_cast(rule.get()); + if (!r) { + continue; + } + + if (dynamic_cast(rule.get())) { + RuleWithOperator *op = new RuleWithOperator(*dynamic_cast(rule.get())); + std::unique_ptr nrp(op); + m_rules[i] = std::move(nrp); + } else if (dynamic_cast(rule.get())) { + RuleUnconditional *un = new RuleUnconditional(*dynamic_cast(rule.get())); + std::unique_ptr nrp(un); + m_rules[i] = std::move(nrp); + } else if (dynamic_cast(rule.get())) { + RuleScript *rs = new RuleScript(*dynamic_cast(rule.get())); + std::unique_ptr nrp(rs); + m_rules[i] = std::move(nrp); + } else { + RuleWithActions *nr = new RuleWithActions(*dynamic_cast(rule.get())); + std::unique_ptr nrp(nr); + m_rules[i] = std::move(nrp); + } + + RuleWithActions *nr = dynamic_cast(m_rules[i].get()); + nr->clearDefaultActions(); + for (auto a : m_defaultActions) { + nr->addDefaultAction(a); + } + for (auto a : m_defaultTransformations) { + nr->addDefaultTransformation(a); + } + + + } + } + /** * @name loadFromUri @@ -101,6 +143,52 @@ int RulesSet::load(const char *plainRules) { } +bool RulesSet::containsDuplicatedIds(RulesWarnings *warning, RulesErrors *error) { + std::multimap allIds; + std::set duplicatedIds; + for (auto &rules : m_rulesSetPhases) { + for (auto &j : rules) { + RuleWithActions *rule = dynamic_cast(j.get()); + if (rule) { + allIds.insert(std::pair(rule->getId(), rule)); + } + } + } + + auto id = allIds.begin(); + auto next = id; + if (id != allIds.end()) { + next++; + } + while (id != allIds.end() && next != allIds.end()) { + if (id->first == next->first) { + duplicatedIds.insert(id->first); + } + id++; + next++; + } + + for (auto i : duplicatedIds) { + auto ret = allIds.equal_range(i); + std::stringstream ss; + + ss << "There are multiple rules defined with "; + ss << "same id. The ID " << i << " is defined at: " << std::endl; + for (auto it = ret.first; it != ret.second; ++it) { + auto rule = it->second; + ss << " " << *rule->getFileName() << ":"; + ss << rule->getLineNumber() << std::endl; + } + + std::unique_ptr e(new std::string(ss.str())); + error->push_back(std::move(e)); + } + + return duplicatedIds.size() > 0; +} + + + std::string RulesSet::getParserError() { return this->m_parserError.str(); } @@ -136,12 +224,14 @@ int RulesSet::evaluate(int phase, Transaction *t) { // FIXME: This is not meant to be here. At the end of this refactoring, // the shared pointer won't be used. auto rule = rules->at(i); - if (t->isInsideAMarker() && !rule->isMarker()) { - ms_dbg_a(t, 9, "Skipped rule id '" + rule->getReference() \ - + "' due to a SecMarker: " + *t->getCurrentMarker()); - - } else if (rule->isMarker()) { - rule->evaluate(t); + if (t->isInsideAMarker()) { + RuleMarker *ruleMarker = dynamic_cast(rule.get()); + if (!ruleMarker) { + ms_dbg_a(t, 9, "Skipped rule id '" + rule->getReference() \ + + "' due to a SecMarker: " + *t->getCurrentMarker()); + } else { + rule->evaluate(t); + } } else if (t->m_skip_next > 0) { t->m_skip_next--; ms_dbg_a(t, 9, "Skipped rule id '" + rule->getReference() \ @@ -155,7 +245,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { Rule *base = rule.get(); RuleWithActions *ruleWithActions = dynamic_cast(base); // FIXME: Those should be treated inside the rule itself - if (ruleWithActions && m_exceptions.contains(ruleWithActions->m_ruleId)) { + if (ruleWithActions && m_exceptions.contains(ruleWithActions->getId())) { ms_dbg_a(t, 9, "Skipped rule id '" + rule->getReference() \ + "'. Removed by an SecRuleRemove directive."); continue; @@ -222,28 +312,50 @@ int RulesSet::evaluate(int phase, Transaction *t) { int RulesSet::merge(Driver *from) { int amount_of_rules = 0; + RulesErrors errors; + RulesWarnings warnings; - amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases, - &m_parserError); + m_rulesSetPhases.append(&from->m_rulesSetPhases); mergeProperties( dynamic_cast(from), dynamic_cast(this), &m_parserError); + m_rulesSetPhases.fixDefaultActions(&warnings, &errors); + containsDuplicatedIds(&warnings, &errors); + + if (!errors.empty()) { + for (auto &i : errors) { + m_parserError << "*** Error: " << *i << std::endl; + } + return -1; + } + return amount_of_rules; } int RulesSet::merge(RulesSet *from) { int amount_of_rules = 0; + RulesErrors errors; + RulesWarnings warnings; - amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases, - &m_parserError); + m_rulesSetPhases.append(&from->m_rulesSetPhases); mergeProperties( dynamic_cast(from), dynamic_cast(this), &m_parserError); + m_rulesSetPhases.fixDefaultActions(&warnings, &errors); + containsDuplicatedIds(&warnings, &errors); + + if (!errors.empty()) { + for (auto &i : errors) { + m_parserError << "*** Error: " << *i << std::endl; + } + return -1; + } + return amount_of_rules; } @@ -256,7 +368,7 @@ void RulesSet::debug(int level, const std::string &id, } -void RulesSet::dump() const { +void RulesSet::dump() { m_rulesSetPhases.dump(); } diff --git a/src/rules_set_phases.cc b/src/rules_set_phases.cc index 6d92530e57..ed9dfe7ce3 100644 --- a/src/rules_set_phases.cc +++ b/src/rules_set_phases.cc @@ -13,68 +13,48 @@ * */ -#include -#include -#include -#include -#include - #include "modsecurity/rules_set_phases.h" -#include "modsecurity/rule.h" -#include "modsecurity/rules.h" -#include "modsecurity/modsecurity.h" - - +#include "src/rule_with_operator.h" +#include namespace modsecurity { -bool RulesSetPhases::insert(std::shared_ptr rule) { - if (rule->getPhase() >= modsecurity::Phases::NUMBER_OF_PHASES) { - return false; +void RulesSetPhases::insert(std::shared_ptr rule) { + if (rule->getPhase() >= size()) { + return; } m_rulesAtPhase[rule->getPhase()].insert(rule); - - return true; } -int RulesSetPhases::append(RulesSetPhases *from, std::ostringstream *err) { - int amount_of_rules = 0; - std::vector v; - - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - v.reserve(m_rulesAtPhase[i].size()); - for (size_t z = 0; z < m_rulesAtPhase[i].size(); z++) { - RuleWithOperator *rule_ckc = dynamic_cast(m_rulesAtPhase[i].at(z).get()); - if (!rule_ckc) { - continue; - } - v.push_back(rule_ckc->m_ruleId); - } +void RulesSetPhases::append(RulesSetPhases *from) { + int phase = 0; + for (auto &a : *from) { + m_rulesAtPhase[phase++].append(&a); } - std::sort (v.begin(), v.end()); +} + - for (int phase = 0; phase < modsecurity::Phases::NUMBER_OF_PHASES; phase++) { - int res = m_rulesAtPhase[phase].append(from->at(phase), v, err); - if (res < 0) { - return res; - } - amount_of_rules = amount_of_rules + res; +void RulesSetPhases::dump() { + int phase = 0; + for (auto &rules : m_rulesAtPhase) { + std::cout << "Phase: " << std::to_string(phase++); + std::cout << " (" << std::to_string(rules.size()); + std::cout << " rules)" << std::endl; + rules.dump(); } +} - return amount_of_rules; + +Rules *RulesSetPhases::operator[](int index) { + return &m_rulesAtPhase[index]; } -void RulesSetPhases::dump() const { - for (int i = 0; i <= modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::cout << "Phase: " << std::to_string(i); - std::cout << " (" << std::to_string(m_rulesAtPhase[i].size()); - std::cout << " rules)" << std::endl; - m_rulesAtPhase[i].dump(); - } + +Rules *RulesSetPhases::at(int index) { + return &m_rulesAtPhase[index]; } } // namespace modsecurity - diff --git a/src/run_time_string.cc b/src/run_time_string.cc index 604467e8d1..5068a97614 100644 --- a/src/run_time_string.cc +++ b/src/run_time_string.cc @@ -25,6 +25,7 @@ #include "src/variables/highest_severity.h" #include "src/utils/string.h" #include "src/variables/variable.h" +#include "src/rule_with_operator.h" namespace modsecurity { @@ -40,36 +41,27 @@ void RunTimeString::appendText(const std::string &text) { void RunTimeString::appendVar( std::unique_ptr var) { std::unique_ptr r(new RunTimeElementHolder); - r->m_var = std::move(var); + r->m_variable = std::move(var); m_elements.push_back(std::move(r)); m_containsMacro = true; } -std::string RunTimeString::evaluate(Transaction *t) { - return evaluate(t, NULL); -} - - -std::string RunTimeString::evaluate(Transaction *t, Rule *r) { - std::string s; - for (auto &z : m_elements) { - if (z->m_string.size() > 0) { - s.append(z->m_string); - } else if (z->m_var != NULL && t != NULL) { - std::vector l; - // FIXME: This cast should be removed. - RuleWithOperator *rr = dynamic_cast(r); - z->m_var->evaluate(t, rr, &l); - if (l.size() > 0) { - s.append(l[0]->getValue()); - } - for (auto &i : l) { - delete i; +std::string RunTimeString::evaluate(Transaction *transaction) { + std::string retString; + // FIXME: Educated guess the size of retString based on the size of the elements. + for (auto &element : m_elements) { + if (element->m_string.size() > 0) { + retString.append(element->m_string); + } else if (element->m_variable != nullptr && transaction != nullptr) { + std::vector> l; + element->m_variable->evaluate(transaction, &l); + if (!l.empty()) { + retString.append(l[0]->getValue()); } } } - return s; + return retString; } } // namespace modsecurity diff --git a/src/run_time_string.h b/src/run_time_string.h index 85b02dd027..c6109a9e24 100644 --- a/src/run_time_string.h +++ b/src/run_time_string.h @@ -25,6 +25,7 @@ #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" #include "src/variables/variable.h" +#include "src/variables/rule_variable.h" #ifndef SRC_RUN_TIME_STRING_H_ @@ -34,29 +35,72 @@ namespace modsecurity { class RunTimeElementHolder { public: - RunTimeElementHolder() : - m_string("") { - m_var.reset(NULL); - } - std::unique_ptr m_var; + RunTimeElementHolder() + : m_string(""), + m_variable(nullptr) + { }; + + + RunTimeElementHolder(const RunTimeElementHolder &other) + : m_string(other.m_string), + m_variable(other.m_variable) { + variables::RuleVariable *rv = dynamic_cast(m_variable.get()); + if (rv != nullptr) { + auto nrv = rv->clone(); + rv = dynamic_cast(nrv); + rv->populate(nullptr); + m_variable = std::unique_ptr(nrv); + } + }; + + /* protected: */ std::string m_string; + std::shared_ptr m_variable; }; class RunTimeString { public: - RunTimeString() : - m_containsMacro(false) { } + RunTimeString() + : m_containsMacro(false), + m_elements() + { }; + + + RunTimeString(const RunTimeString &other) + : m_containsMacro(other.m_containsMacro), + m_elements() + { + for (auto &m : other.m_elements) { + m_elements.push_back(std::unique_ptr(new RunTimeElementHolder(*m.get()))); + } + }; + + void appendText(const std::string &text); void appendVar(std::unique_ptr var); + + std::string evaluate(Transaction *t); - std::string evaluate(Transaction *t, Rule *r); - std::string evaluate() { + + inline std::string evaluate() { return evaluate(NULL); } + + inline bool containsMacro() const { return m_containsMacro; } - bool m_containsMacro; - protected: + + void populate(RuleWithActions *rule) { + for (auto &a : m_elements) { + modsecurity::variables::RuleVariable *vrule = dynamic_cast(a->m_variable.get()); + if (vrule != nullptr) { + vrule->populate(rule); + } + } + } + + private: + bool m_containsMacro; std::list> m_elements; }; diff --git a/src/transaction.cc b/src/transaction.cc index 9d608ecb9b..91d0c27f1d 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -52,7 +52,8 @@ #include "modsecurity/rules_set_properties.h" #include "src/actions/disruptive/allow.h" #include "src/variables/remote_user.h" - +#include "src/rule_with_actions.h" +#include "src/actions/ctl/audit_log_parts.h" using modsecurity::actions::Action; @@ -61,6 +62,46 @@ using modsecurity::RequestBodyProcessor::XML; namespace modsecurity { + +RuleMessage *TransactionRuleMessageManagement::messageGetLast() { + return m_rulesMessages.back(); +} + +void TransactionRuleMessageManagement::logMatchLastRuleOnTheChain(const RuleWithActions *rule) { + RuleMessage *rm = m_rulesMessages.back(); + + rm->setRule(rule); + + if (rule->hasDisruptiveAction() && rule->isItToBeLogged() && + (m_transaction->getRuleEngineState() == RulesSet::DetectionOnlyRuleEngine)) { + /* error */ + // The error goes over the disruptive massage. We don't need it here. + //m_transaction->serverLog(rm); + } else if (rule->hasBlockAction() && rule->isItToBeLogged()) { + /* Log as warning. */ + m_transaction->serverLog(rm); + } else if (rule->isItToBeLogged()) { + /* Log as warning. */ + m_transaction->serverLog(rm); + } + + messageNew(); +} + +void TransactionRuleMessageManagement::messageNew() { + m_rulesMessages.push_back(new RuleMessage(m_transaction)); +} + +std::list TransactionRuleMessageManagement::messageGetAll() { + std::list messages; + for (RuleMessage *a : m_rulesMessages) { + messages.push_back(a); + } + return messages; +} + + + /** * @name Transaction * @brief Represents the inspection on an entire request. @@ -121,8 +162,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) m_ruleRemoveTargetByTag(), m_ruleRemoveTargetById(), m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean), - m_auditLogModifier(), - m_rulesMessages(), + m_auditLogParts(0), m_requestBody(), m_responseBody(), /* m_id(), */ @@ -160,7 +200,8 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) m_variableTimeWDay(""), m_variableTimeYear(""), m_logCbData(logCbData), - TransactionAnchoredVariables(this) { + TransactionAnchoredVariables(this), + TransactionRuleMessageManagement(this) { m_id = std::unique_ptr( new std::string( std::to_string(m_timeStamp))); @@ -169,6 +210,10 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) ms_dbg(4, "Initializing transaction"); + if (m_rules != NULL && m_rules->m_auditLog != NULL) { + m_auditLogParts = this->m_rules->m_auditLog->getParts(); + } + intervention::clean(&m_it); } @@ -194,8 +239,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb m_ruleRemoveTargetByTag(), m_ruleRemoveTargetById(), m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean), - m_auditLogModifier(), - m_rulesMessages(), + m_auditLogParts(0), m_requestBody(), m_responseBody(), m_id(std::unique_ptr(new std::string(id))), @@ -233,12 +277,17 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb m_variableTimeWDay(""), m_variableTimeYear(""), m_logCbData(logCbData), - TransactionAnchoredVariables(this) { + TransactionAnchoredVariables(this), + TransactionRuleMessageManagement(this) { m_variableUrlEncodedError.set("0", 0); ms_dbg(4, "Initializing transaction"); + if (m_rules != NULL && m_rules->m_auditLog != NULL) { + m_auditLogParts = m_rules->m_auditLog->getParts(); + } + intervention::clean(&m_it); } @@ -250,7 +299,7 @@ Transaction::~Transaction() { m_requestBody.str(std::string()); m_requestBody.clear(); - m_rulesMessages.clear(); + messageClear(); intervention::free(&m_it); intervention::clean(&m_it); @@ -315,7 +364,6 @@ int Transaction::processConnection(const char *client, int cPort, ms_dbg(4, "Transaction context created."); ms_dbg(4, "Starting phase CONNECTION. (SecRules 0)"); - m_variableRemoteHost.set(*m_clientIpAddress.get(), m_variableOffset); m_variableUniqueID.set(*m_id.get(), m_variableOffset); m_variableRemoteAddr.set(*m_clientIpAddress.get(), m_variableOffset); @@ -340,7 +388,6 @@ bool Transaction::extractArguments(const std::string &orig, for (std::string t : key_value_sets) { char sep2 = '='; - int i = 0; size_t key_s = 0; size_t value_s = 0; int invalid = 0; @@ -915,11 +962,10 @@ int Transaction::processRequestBody() { * computationally intensive. */ std::string fullRequest; - std::vector l; + std::vector> l; m_variableRequestHeaders.resolve(&l); - for (auto &h : l) { + for (const auto &h : l) { fullRequest = fullRequest + h->getKey() + ": " + h->getValue() + "\n"; - delete h; } fullRequest = fullRequest + "\n\n"; @@ -1380,35 +1426,14 @@ int Transaction::processLogging() { this->m_rules->evaluate(modsecurity::LoggingPhase, this); - /* If relevant, save this transaction information at the audit_logs */ - if (m_rules != NULL && m_rules->m_auditLog != NULL) { - int parts = this->m_rules->m_auditLog->getParts(); + if (m_auditLogParts != 0) { ms_dbg(8, "Checking if this request is suitable to be " \ "saved as an audit log."); - if (!this->m_auditLogModifier.empty()) { - ms_dbg(4, "There was an audit log modifier for this transaction."); - std::list>::iterator it; - ms_dbg(7, "AuditLog parts before modification(s): " + - std::to_string(parts) + "."); - for (it = m_auditLogModifier.begin(); - it != m_auditLogModifier.end(); ++it) { - std::pair p = *it; - if (p.first == 0) { // Add - parts = this->m_rules->m_auditLog->addParts(parts, - p.second); - } else { // Remove - parts = this->m_rules->m_auditLog->removeParts(parts, - p.second); - } - } - } - ms_dbg(8, "Checking if this request is relevant to be " \ - "part of the audit logs."); - bool saved = this->m_rules->m_auditLog->saveIfRelevant(this, parts); + bool saved = m_rules->m_auditLog->saveIfRelevant(this); if (saved) { ms_dbg(8, "Request was relevant to be saved. Parts: " + - std::to_string(parts)); + std::to_string(m_auditLogParts)); } } @@ -1466,8 +1491,8 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename, ss << utils::string::dash_if_empty(this->m_clientIpAddress->c_str()) << " "; /** TODO: Check variable */ variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER"); - std::vector l; - r->evaluate(this, NULL, &l); + std::vector> l; + r->evaluate(this, &l); delete r; ss << utils::string::dash_if_empty( @@ -1529,7 +1554,7 @@ std::string Transaction::toOldAuditLogFormat(int parts, audit_log << std::endl; if (parts & audit_log::AuditLog::BAuditLogPart) { - std::vector l; + std::vector> l; audit_log << "--" << trailer << "-" << "B--" << std::endl; audit_log << utils::string::dash_if_empty( m_variableRequestMethod.evaluate()); @@ -1537,11 +1562,10 @@ std::string Transaction::toOldAuditLogFormat(int parts, audit_log << this->m_httpVersion.c_str() << std::endl; m_variableRequestHeaders.resolve(&l); - for (auto &h : l) { + for (const auto &h : l) { size_t pos = strlen("REQUEST_HEADERS:"); audit_log << h->getKeyWithCollection().c_str() + pos << ": "; audit_log << h->getValue().c_str() << std::endl; - delete h; } audit_log << std::endl; } @@ -1569,16 +1593,15 @@ std::string Transaction::toOldAuditLogFormat(int parts, audit_log << std::endl; } if (parts & audit_log::AuditLog::FAuditLogPart) { - std::vector l; + std::vector> l; audit_log << "--" << trailer << "-" << "F--" << std::endl; audit_log << "HTTP/" << m_httpVersion.c_str() << " "; audit_log << this->m_httpCodeReturned << std::endl; m_variableResponseHeaders.resolve(&l); - for (auto &h : l) { + for (const auto &h : l) { audit_log << h->getKey().c_str() << ": "; audit_log << h->getValue().c_str() << std::endl; - delete h; } } audit_log << std::endl; @@ -1590,8 +1613,11 @@ std::string Transaction::toOldAuditLogFormat(int parts, } if (parts & audit_log::AuditLog::HAuditLogPart) { audit_log << "--" << trailer << "-" << "H--" << std::endl; - for (auto a : m_rulesMessages) { - audit_log << a.log(0, m_httpCodeReturned) << std::endl; + for (auto a : messageGetAll()) { + if (!a->toBeAuditLog()) { + continue; + } + audit_log << a->log(0, m_httpCodeReturned) << std::endl; } audit_log << std::endl; /** TODO: write audit_log H part. */ @@ -1668,15 +1694,14 @@ std::string Transaction::toJSON(int parts) { /* request headers */ if (parts & audit_log::AuditLog::BAuditLogPart) { - std::vector l; + std::vector> l; yajl_gen_string(g, reinterpret_cast("headers"), strlen("headers")); yajl_gen_map_open(g); m_variableRequestHeaders.resolve(&l); - for (auto &h : l) { + for (const auto &h : l) { LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); - delete h; } /* end: request headers */ @@ -1698,15 +1723,14 @@ std::string Transaction::toJSON(int parts) { /* response headers */ if (parts & audit_log::AuditLog::FAuditLogPart) { - std::vector l; + std::vector> l; yajl_gen_string(g, reinterpret_cast("headers"), strlen("headers")); yajl_gen_map_open(g); m_variableResponseHeaders.resolve(&l); - for (auto &h : l) { + for (const auto &h : l) { LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); - delete h; } /* end: response headers */ @@ -1753,36 +1777,40 @@ std::string Transaction::toJSON(int parts) { reinterpret_cast("messages"), strlen("messages")); yajl_gen_array_open(g); - for (auto a : m_rulesMessages) { + for (auto a : messageGetAll()) { + if (!a->toBeAuditLog()) { + continue; + } + yajl_gen_map_open(g); - LOGFY_ADD("message", a.m_message.c_str()); + LOGFY_ADD("message", a->m_message.c_str()); yajl_gen_string(g, reinterpret_cast("details"), strlen("details")); yajl_gen_map_open(g); - LOGFY_ADD("match", a.m_match.c_str()); - LOGFY_ADD("reference", a.m_reference.c_str()); - LOGFY_ADD("ruleId", std::to_string(a.m_ruleId).c_str()); - LOGFY_ADD("file", a.m_ruleFile->c_str()); - LOGFY_ADD("lineNumber", std::to_string(a.m_ruleLine).c_str()); - LOGFY_ADD("data", a.m_data.c_str()); - LOGFY_ADD("severity", std::to_string(a.m_severity).c_str()); - LOGFY_ADD("ver", a.m_ver.c_str()); - LOGFY_ADD("rev", a.m_rev.c_str()); + LOGFY_ADD("match", a->m_match.c_str()); + LOGFY_ADD("reference", a->m_reference.c_str()); + LOGFY_ADD("ruleId", std::to_string(a->getRuleId()).c_str()); + LOGFY_ADD("file", a->getFileName().c_str()); + LOGFY_ADD("lineNumber", std::to_string(a->getLineNumber()).c_str()); + LOGFY_ADD("data", a->m_data.c_str()); + LOGFY_ADD("severity", std::to_string(a->m_severity).c_str()); + LOGFY_ADD("ver", a->getVer().c_str()); + LOGFY_ADD("rev", a->getRev().c_str()); yajl_gen_string(g, reinterpret_cast("tags"), strlen("tags")); yajl_gen_array_open(g); - for (auto b : a.m_tags) { + for (auto &b : a->m_tags) { yajl_gen_string(g, reinterpret_cast(b.c_str()), strlen(b.c_str())); } yajl_gen_array_close(g); - LOGFY_ADD("maturity", std::to_string(a.m_maturity).c_str()); - LOGFY_ADD("accuracy", std::to_string(a.m_accuracy).c_str()); + LOGFY_ADD("maturity", std::to_string(a->getMaturity()).c_str()); + LOGFY_ADD("accuracy", std::to_string(a->getAccuracy()).c_str()); yajl_gen_map_close(g); yajl_gen_map_close(g); } @@ -1811,7 +1839,7 @@ std::string Transaction::toJSON(int parts) { } -void Transaction::serverLog(std::shared_ptr rm) { +void Transaction::serverLog(RuleMessage *rm) { m_ms->serverLog(m_logCbData, rm); } diff --git a/src/utils/geo_lookup.cc b/src/utils/geo_lookup.cc index e0801f835b..1092c91b84 100644 --- a/src/utils/geo_lookup.cc +++ b/src/utils/geo_lookup.cc @@ -56,8 +56,12 @@ void GeoLookup::cleanUp() { bool GeoLookup::setDataBase(const std::string& filePath, std::string *err) { +#ifdef WITH_MAXMIND std::string intMax; +#endif +#ifdef WITH_GEOIP std::string intGeo; +#endif #ifdef WITH_MAXMIND int status = MMDB_open(filePath.c_str(), MMDB_MODE_MMAP, &mmdb); @@ -85,19 +89,22 @@ bool GeoLookup::setDataBase(const std::string& filePath, #ifdef WITH_MAXMIND err->append(" libMaxMind"); #endif - #ifdef WITH_GEOIP err->append(" GeoIP"); #endif err->append("."); +#ifdef WITH_MAXMIND if (intMax.size() > 0) { err->append(" " + intMax); - } +#endif +#ifdef WITH_GEOIP if (intGeo.size() > 0) { err->append(" " + intGeo); } +#endif + return false; } diff --git a/src/utils/shared_files.h b/src/utils/shared_files.h index 92c8d25727..b5b72f3e92 100644 --- a/src/utils/shared_files.h +++ b/src/utils/shared_files.h @@ -81,7 +81,7 @@ class SharedFiles { { #ifdef MODSEC_USE_GENERAL_LOCK int shm_id; - bool toBeCreated; + bool toBeCreated(false); bool err = false; m_memKeyStructure = ftok(".", 1); diff --git a/src/variables/duration.cc b/src/variables/duration.cc index b60db675df..aaf9782a0c 100644 --- a/src/variables/duration.cc +++ b/src/variables/duration.cc @@ -28,14 +28,12 @@ namespace modsecurity { namespace variables { void Duration::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { double e = utils::cpu_seconds() - transaction->m_creationTimeStamp; transaction->m_variableDuration.assign(std::to_string(e)); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableDuration)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableDuration)); } diff --git a/src/variables/duration.h b/src/variables/duration.h index ec35b73f61..992117d93c 100644 --- a/src/variables/duration.h +++ b/src/variables/duration.h @@ -35,8 +35,7 @@ class Duration : public Variable { m_retName("DURATION") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/env.cc b/src/variables/env.cc index 9566b7526c..7de87d8423 100644 --- a/src/variables/env.cc +++ b/src/variables/env.cc @@ -33,8 +33,7 @@ namespace modsecurity { namespace variables { void Env::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { for (char **current = environ; *current; current++) { std::string env = std::string(*current); size_t pos = env.find_first_of("="); @@ -52,8 +51,7 @@ void Env::evaluate(Transaction *transaction, continue; } if (!m_keyExclusion.toOmit(x.first)) { - l->push_back(new VariableValue(&m_collectionName, &x.first, - &x.second)); + l->emplace_back(std::make_shared(&m_collectionName, &x.first, &x.second)); } } } diff --git a/src/variables/env.h b/src/variables/env.h index 505c91e05d..9259124093 100644 --- a/src/variables/env.h +++ b/src/variables/env.h @@ -34,8 +34,7 @@ class Env : public Variable { : Variable(_name) { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; }; } // namespace variables diff --git a/src/variables/global.h b/src/variables/global.h index 4fdf906c07..4d32f55f3b 100644 --- a/src/variables/global.h +++ b/src/variables/global.h @@ -25,6 +25,7 @@ #include "src/variables/variable.h" #include "src/run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" namespace modsecurity { @@ -39,8 +40,7 @@ class Global_DictElement : public Variable { m_dictElement("GLOBAL:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_global_collection->resolveMultiMatches( m_name, t->m_collections.m_global_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -56,8 +56,7 @@ class Global_NoDictElement : public Variable { : Variable("GLOBAL") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_global_collection->resolveMultiMatches("", t->m_collections.m_global_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -72,8 +71,7 @@ class Global_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_global_collection->resolveRegularExpression( m_dictElement, t->m_collections.m_global_collection_key, @@ -84,15 +82,17 @@ class Global_DictElementRegexp : public VariableRegex { }; -class Global_DynamicElement : public Variable { +class Global_DynamicElement : public VariableWithRunTimeString { public: explicit Global_DynamicElement(std::unique_ptr dictElement) - : Variable("GLOBAL:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "GLOBAL:dynamic", + std::move(dictElement) + ) + { }; void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_global_collection->resolveMultiMatches( string, @@ -113,8 +113,6 @@ class Global_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/highest_severity.cc b/src/variables/highest_severity.cc index 7059bc1110..c2db0f21b6 100644 --- a/src/variables/highest_severity.cc +++ b/src/variables/highest_severity.cc @@ -27,12 +27,10 @@ namespace modsecurity { namespace variables { void HighestSeverity::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { transaction->m_variableHighestSeverityAction.assign( std::to_string(transaction->m_highestSeverityAction)); - l->push_back(new VariableValue(m_fullName.get(), - &transaction->m_variableHighestSeverityAction)); + l->push_back(std::make_shared(m_fullName.get(), &transaction->m_variableHighestSeverityAction)); } diff --git a/src/variables/highest_severity.h b/src/variables/highest_severity.h index ecc6cc1e37..bbc8af3ba3 100644 --- a/src/variables/highest_severity.h +++ b/src/variables/highest_severity.h @@ -35,8 +35,7 @@ class HighestSeverity : public Variable { { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; }; diff --git a/src/variables/ip.h b/src/variables/ip.h index 6f3efa9445..12f076d696 100644 --- a/src/variables/ip.h +++ b/src/variables/ip.h @@ -25,6 +25,7 @@ #include "src/variables/variable.h" #include "src/run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" namespace modsecurity { @@ -39,8 +40,7 @@ class Ip_DictElement : public Variable { m_dictElement("IP:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_ip_collection->resolveMultiMatches( m_name, t->m_collections.m_ip_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -56,8 +56,7 @@ class Ip_NoDictElement : public Variable { : Variable("IP") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_ip_collection->resolveMultiMatches("", t->m_collections.m_ip_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -72,8 +71,7 @@ class Ip_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_ip_collection->resolveRegularExpression( m_dictElement, t->m_collections.m_ip_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -83,15 +81,17 @@ class Ip_DictElementRegexp : public VariableRegex { }; -class Ip_DynamicElement : public Variable { +class Ip_DynamicElement : public VariableWithRunTimeString { public: explicit Ip_DynamicElement(std::unique_ptr dictElement) - : Variable("IP:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "IP:dynamic", + std::move(dictElement) + ) + { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_ip_collection->resolveMultiMatches( string, @@ -112,8 +112,6 @@ class Ip_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/modsec_build.cc b/src/variables/modsec_build.cc index 594b3bf5bc..ec509a421c 100644 --- a/src/variables/modsec_build.cc +++ b/src/variables/modsec_build.cc @@ -25,10 +25,9 @@ namespace modsecurity { namespace variables { void ModsecBuild::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { - l->push_back(new VariableValue(&m_retName, &m_build)); + l->push_back(std::make_shared(&m_retName, &m_build)); } diff --git a/src/variables/modsec_build.h b/src/variables/modsec_build.h index 318f7ef891..6fa75856e9 100644 --- a/src/variables/modsec_build.h +++ b/src/variables/modsec_build.h @@ -44,8 +44,7 @@ class ModsecBuild : public Variable { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_build; std::string m_retName; diff --git a/src/variables/remote_user.cc b/src/variables/remote_user.cc index aa751a38eb..3d13e43b73 100644 --- a/src/variables/remote_user.cc +++ b/src/variables/remote_user.cc @@ -37,22 +37,19 @@ namespace variables { void RemoteUser::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { size_t pos; std::string base64; - VariableValue *var; std::string header; - std::vector *l2 = \ - new std::vector(); - transaction->m_variableRequestHeaders.resolve("authorization", l2); + std::vector> l2; + transaction->m_variableRequestHeaders.resolve("authorization", &l2); - if (l2->size() < 1) { - goto clear; + if (l2.size() < 1) { + return; } - header = std::string(l2->at(0)->getValue()); + header = std::string(l2.at(0)->getValue()); if (header.compare(0, 6, "Basic ") == 0) { base64 = std::string(header, 6, header.length()); @@ -62,27 +59,16 @@ void RemoteUser::evaluate(Transaction *transaction, pos = base64.find(":"); if (pos == std::string::npos) { - goto clear; + return; } transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); - var = new VariableValue(&l2->at(0)->getKeyWithCollection(), - &transaction->m_variableRemoteUser); + auto var = std::make_shared(&l2[0]->getKeyWithCollection(), &transaction->m_variableRemoteUser); - for (auto &i : l2->at(0)->getOrigin()) { - std::unique_ptr origin(new VariableOrigin()); - origin->m_offset = i->m_offset; - origin->m_length = i->m_length; - var->addOrigin(std::move(origin)); + for (auto &i : l2[0]->getOrigin()) { + var->addOrigin(i); } - l->push_back(var); - -clear: - for (auto &a : *l2) { - delete a; - } - l2->clear(); - delete l2; + l->push_back(std::move(var)); } diff --git a/src/variables/remote_user.h b/src/variables/remote_user.h index 3b099a79af..af2c121f34 100644 --- a/src/variables/remote_user.h +++ b/src/variables/remote_user.h @@ -37,8 +37,7 @@ class RemoteUser : public Variable { m_retName("REMOTE_USER") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/resource.h b/src/variables/resource.h index aa352ba1fc..f3ad152ba0 100644 --- a/src/variables/resource.h +++ b/src/variables/resource.h @@ -25,6 +25,7 @@ #include "src/variables/variable.h" #include "src/run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" namespace modsecurity { @@ -39,8 +40,7 @@ class Resource_DictElement : public Variable { m_dictElement("RESOURCE:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_resource_collection->resolveMultiMatches( m_name, t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -56,8 +56,7 @@ class Resource_NoDictElement : public Variable { : Variable("RESOURCE") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_resource_collection->resolveMultiMatches(m_name, t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -72,8 +71,7 @@ class Resource_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_resource_collection->resolveRegularExpression( m_dictElement, t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -83,15 +81,17 @@ class Resource_DictElementRegexp : public VariableRegex { }; -class Resource_DynamicElement : public Variable { +class Resource_DynamicElement : public VariableWithRunTimeString { public: explicit Resource_DynamicElement(std::unique_ptr dictElement) - : Variable("RESOURCE:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "RESOURCE:dynamic", + std::move(dictElement) + ) + { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_resource_collection->resolveMultiMatches( string, @@ -111,8 +111,6 @@ class Resource_DynamicElement : public Variable { var, t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/rule.h b/src/variables/rule.h index 969fd030ec..b09089d04e 100644 --- a/src/variables/rule.h +++ b/src/variables/rule.h @@ -24,6 +24,7 @@ #include "src/actions/severity.h" #include "src/actions/log_data.h" #include "src/actions/msg.h" +#include "src/rule_with_actions.h" namespace modsecurity { @@ -32,153 +33,125 @@ class Transaction; namespace variables { -class Rule_DictElement : public VariableDictElement { \ +class Rule_DictElement : public RuleVariable, public VariableDictElement { public: explicit Rule_DictElement(const std::string &dictElement) - : VariableDictElement(std::string("RULE"), dictElement) { } + : RuleVariable(), + VariableDictElement( + std::string("RULE"), + dictElement + ) + { }; - static void id(Transaction *t, - RuleWithActions *rule, - std::vector *l) { - RuleWithActions *r = rule; - - while (r && r->m_ruleId == 0) { - r = r->m_chainedRuleParent; - } - - if (!r || r->m_ruleId == 0) { - return; - } - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(std::to_string(r->m_ruleId)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_id, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; - var->addOrigin(std::move(origin)); - l->push_back(var); - } + Rule_DictElement(const Rule_DictElement &r) + : RuleVariable(), + VariableDictElement(r) + { }; - static void rev(Transaction *t, - RuleWithActions *rule, - std::vector *l) { - RuleWithActions *r = rule; - - while (r && r->m_rev.empty()) { - r = r->m_chainedRuleParent; - } - if (!r) { - return; - } + virtual Variable *clone() override { + return new Rule_DictElement(*this); + }; - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->m_rev); - VariableValue *var = new VariableValue(&m_rule, &m_rule_rev, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; + static void id(Transaction *t, + const RuleWithActions *rule, + std::vector> *l) { + std::string a = std::to_string(rule->getId()); + auto var = std::make_shared(&m_rule, &m_rule_id, &a); + VariableOrigin origin; + origin.m_offset = 0; + origin.m_length = 0; var->addOrigin(std::move(origin)); - l->push_back(var); + l->push_back(std::move(var)); } - static void severity(Transaction *t, - RuleWithActions *rule, - std::vector *l) { - RuleWithActions *r = rule; - - while (r && !r->hasSeverity()) { - r = r->m_chainedRuleParent; - } - if (r && r->hasSeverity()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(std::to_string(r->severity())); - VariableValue *var = new VariableValue(&m_rule, &m_rule_severity, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; + static void rev(Transaction *t, + const RuleWithActions *rule, + std::vector> *l) { + + if (rule->hasRevisionAction()) { + std::string a(rule->getRevision()); + auto var = std::make_shared(&m_rule, &m_rule_rev, &a); + VariableOrigin origin; + origin.m_offset = 0; + origin.m_length = 0; var->addOrigin(std::move(origin)); l->push_back(var); + l->push_back(std::move(var)); } } - static void logData(Transaction *t, - RuleWithActions *rule, - std::vector *l) { - RuleWithActions *r = rule; - - while (r && !r->hasLogData()) { - r = r->m_chainedRuleParent; + static void severity(Transaction *t, + const RuleWithActions *rule, + std::vector> *l) { + + if (rule->hasSeverityAction()) { + std::string a(std::to_string(rule->getSeverity())); + auto var = std::make_shared(&m_rule, &m_rule_severity, &a); + VariableOrigin origin; + origin.m_offset = 0; + origin.m_length = 0; + var->addOrigin(std::move(origin)); + l->push_back(std::move(var)); } - if (r && r->hasLogData()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->logData(t)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; + } + + static void logData(Transaction *t, + const RuleWithActions *rule, + std::vector> *l) { + + if (rule->hasLogDataAction()) { + std::string a(rule->getLogData(t)); + auto var = std::make_shared(&m_rule, &m_rule_logdata, &a); + VariableOrigin origin; + origin.m_offset = 0; + origin.m_length = 0; var->addOrigin(std::move(origin)); - l->push_back(var); + l->push_back(std::move(var)); } } static void msg(Transaction *t, - RuleWithActions *rule, - std::vector *l) { - RuleWithActions *r = rule; - - while (r && !r->hasMsg()) { - r = r->m_chainedRuleParent; - } - - if (r && r->hasMsg()) { - std::unique_ptr origin(new VariableOrigin()); - std::string *a = new std::string(r->msg(t)); - VariableValue *var = new VariableValue(&m_rule, &m_rule_msg, - a - ); - delete a; - origin->m_offset = 0; - origin->m_length = 0; + const RuleWithActions *rule, + std::vector> *l) { + + if (rule->hasMessageAction()) { + std::string a(rule->getMessage(t)); + auto var = std::make_shared(&m_rule, &m_rule_msg, &a); + VariableOrigin origin; + origin.m_offset = 0; + origin.m_length = 0; var->addOrigin(std::move(origin)); - l->push_back(var); + l->push_back(std::move(var)); } } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { + if (m_dictElement == "id") { - id(t, rule, l); + id(t, getRule(), l); return; } - if (rule && m_dictElement == "rev") { - rev(t, rule, l); + if (m_dictElement == "rev") { + rev(t, getRule(), l); return; } - if (rule && m_dictElement == "severity") { - severity(t, rule, l); + if (m_dictElement == "severity") { + severity(t, getRule(), l); return; } if (m_dictElement == "logdata") { - logData(t, rule, l); + logData(t, getRule(), l); return; } if (m_dictElement == "msg") { - msg(t, rule, l); + msg(t, getRule(), l); return; } } @@ -192,52 +165,77 @@ class Rule_DictElement : public VariableDictElement { \ }; -class Rule_DictElementRegexp : public VariableRegex { +class Rule_DictElementRegexp : public RuleVariable, public VariableRegex { public: explicit Rule_DictElementRegexp(const std::string ®ex) - : VariableRegex("RULE", regex) { } + : RuleVariable(), + VariableRegex("RULE", regex) + { }; + + + Rule_DictElementRegexp(const Rule_DictElementRegexp &r) + : RuleVariable(), + VariableRegex(r) + { }; + void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { + if (Utils::regex_search("id", m_r) > 0) { - Rule_DictElement::id(t, rule, l); + Rule_DictElement::id(t, getRule(), l); return; } if (Utils::regex_search("rev", m_r) > 0) { - Rule_DictElement::rev(t, rule, l); + Rule_DictElement::rev(t, getRule(), l); return; } if (Utils::regex_search("severity", m_r) > 0) { - Rule_DictElement::severity(t, rule, l); + Rule_DictElement::severity(t, getRule(), l); return; } if (Utils::regex_search("logdata", m_r) > 0) { - Rule_DictElement::logData(t, rule, l); + Rule_DictElement::logData(t, getRule(), l); return; } if (Utils::regex_search("msg", m_r) > 0) { - Rule_DictElement::msg(t, rule, l); + Rule_DictElement::msg(t, getRule(), l); return; } } + + virtual Variable *clone() override { + return new Rule_DictElementRegexp(*this); + }; }; -class Rule_NoDictElement : public Variable { +class Rule_NoDictElement : public RuleVariable, public Variable { public: - explicit Rule_NoDictElement() - : Variable("RULE") { } + Rule_NoDictElement() + : RuleVariable(), + Variable("RULE") + { }; + + + explicit Rule_NoDictElement(const Rule_DictElementRegexp &r) + : RuleVariable(), + Variable(r) + { }; + void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { - Rule_DictElement::id(t, rule, l); - Rule_DictElement::rev(t, rule, l); - Rule_DictElement::severity(t, rule, l); - Rule_DictElement::logData(t, rule, l); - Rule_DictElement::msg(t, rule, l); + std::vector> *l) override { + Rule_DictElement::id(t, getRule(), l); + Rule_DictElement::rev(t, getRule(), l); + Rule_DictElement::severity(t, getRule(), l); + Rule_DictElement::logData(t, getRule(), l); + Rule_DictElement::msg(t, getRule(), l); } + + virtual Variable *clone() override { + return new Rule_NoDictElement(*this); + }; }; // DEFINE_VARIABLE_DICT(Rule, RULE, m_variableRule) diff --git a/src/variables/rule_variable.h b/src/variables/rule_variable.h new file mode 100644 index 0000000000..47714f16dc --- /dev/null +++ b/src/variables/rule_variable.h @@ -0,0 +1,60 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include + +#ifndef SRC_VARIABLES_RULE_VARIABLE_H_ +#define SRC_VARIABLES_RULE_VARIABLE_H_ + +#include "src/rule_with_actions.h" + + +namespace modsecurity { + +class Transaction; +namespace variables { + +class RuleVariable { + public: + RuleVariable() + : m_rule(nullptr) + { }; + + RuleVariable(const RuleVariable &a) + : m_rule(a.m_rule) + { }; + + + void populate(const RuleWithActions *rule) { + m_rule = rule; + } + + const RuleWithActions *getRule() const noexcept { + return m_rule; + } + + virtual Variable* clone() = 0; + + private: + const RuleWithActions *m_rule; +}; + + +} // namespace variables +} // namespace modsecurity + +#endif // SRC_VARIABLES_RULE_VARIABLE_H_ diff --git a/src/variables/session.h b/src/variables/session.h index bc831e31d2..0ac59bc835 100644 --- a/src/variables/session.h +++ b/src/variables/session.h @@ -39,8 +39,7 @@ class Session_DictElement : public Variable { m_dictElement("SESSION:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_session_collection->resolveMultiMatches( m_name, t->m_collections.m_session_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -56,8 +55,7 @@ class Session_NoDictElement : public Variable { : Variable("SESSION") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_session_collection->resolveMultiMatches("", t->m_collections.m_session_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -72,8 +70,7 @@ class Session_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_session_collection->resolveRegularExpression( m_dictElement, t->m_collections.m_session_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -83,15 +80,17 @@ class Session_DictElementRegexp : public VariableRegex { }; -class Session_DynamicElement : public Variable { +class Session_DynamicElement : public VariableWithRunTimeString { public: explicit Session_DynamicElement(std::unique_ptr dictElement) - : Variable("SESSION:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "SESSION:dynamic", + std::move(dictElement) + ) + { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_session_collection->resolveMultiMatches( string, @@ -112,8 +111,6 @@ class Session_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/time.cc b/src/variables/time.cc index b14e96109d..57457a6e9c 100644 --- a/src/variables/time.cc +++ b/src/variables/time.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void Time::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; @@ -48,8 +47,7 @@ void Time::evaluate(Transaction *transaction, strftime(tstr, 200, "%H:%M:%S", &timeinfo); transaction->m_variableTime.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTime)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTime)); } diff --git a/src/variables/time.h b/src/variables/time.h index 4f3dec89c4..2ef1fe72cd 100644 --- a/src/variables/time.h +++ b/src/variables/time.h @@ -36,8 +36,7 @@ class Time : public Variable { m_retName("TIME") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_day.cc b/src/variables/time_day.cc index f16500e952..23cd3ea48f 100644 --- a/src/variables/time_day.cc +++ b/src/variables/time_day.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeDay::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeDay::evaluate(Transaction *transaction, transaction->m_variableTimeDay.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeDay)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeDay)); } diff --git a/src/variables/time_day.h b/src/variables/time_day.h index 946ba3aaca..532a5962e3 100644 --- a/src/variables/time_day.h +++ b/src/variables/time_day.h @@ -35,8 +35,7 @@ class TimeDay : public Variable { m_retName("TIME_DAY") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_epoch.cc b/src/variables/time_epoch.cc index f7ee0f52dd..75c40ab365 100644 --- a/src/variables/time_epoch.cc +++ b/src/variables/time_epoch.cc @@ -34,12 +34,10 @@ namespace modsecurity { namespace variables { void TimeEpoch::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { transaction->m_variableTimeEpoch.assign( std::to_string(std::time(nullptr))); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeEpoch)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeEpoch)); } diff --git a/src/variables/time_epoch.h b/src/variables/time_epoch.h index a259e8638e..cdd9d82842 100644 --- a/src/variables/time_epoch.h +++ b/src/variables/time_epoch.h @@ -35,8 +35,7 @@ class TimeEpoch : public Variable { m_retName("TIME_EPOCH") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_hour.cc b/src/variables/time_hour.cc index 380f471a5d..9c149e1c20 100644 --- a/src/variables/time_hour.cc +++ b/src/variables/time_hour.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeHour::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeHour::evaluate(Transaction *transaction, transaction->m_variableTimeHour.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeHour)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeHour)); } diff --git a/src/variables/time_hour.h b/src/variables/time_hour.h index aad53515b1..cfe1a42044 100644 --- a/src/variables/time_hour.h +++ b/src/variables/time_hour.h @@ -35,8 +35,7 @@ class TimeHour : public Variable { m_retName("TIME_HOUR") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_min.cc b/src/variables/time_min.cc index 099e668533..3711f19ef2 100644 --- a/src/variables/time_min.cc +++ b/src/variables/time_min.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeMin::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeMin::evaluate(Transaction *transaction, transaction->m_variableTimeMin.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeMin)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeMin)); } diff --git a/src/variables/time_min.h b/src/variables/time_min.h index fd26eb2685..a2923008dc 100644 --- a/src/variables/time_min.h +++ b/src/variables/time_min.h @@ -35,8 +35,7 @@ class TimeMin : public Variable { m_retName("TIME_MIN") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_mon.cc b/src/variables/time_mon.cc index c1ff817561..5af0f37d8b 100644 --- a/src/variables/time_mon.cc +++ b/src/variables/time_mon.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeMon::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -50,8 +49,7 @@ void TimeMon::evaluate(Transaction *transaction, transaction->m_variableTimeMin.assign(std::to_string(a)); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeMin)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeMin)); } diff --git a/src/variables/time_mon.h b/src/variables/time_mon.h index e54866a38a..3da5803613 100644 --- a/src/variables/time_mon.h +++ b/src/variables/time_mon.h @@ -35,8 +35,7 @@ class TimeMon : public Variable { m_retName("TIME_MON") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_sec.cc b/src/variables/time_sec.cc index 9e7a76cd5e..e448ad760d 100644 --- a/src/variables/time_sec.cc +++ b/src/variables/time_sec.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeSec::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeSec::evaluate(Transaction *transaction, transaction->m_variableTimeSec.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeSec)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeSec)); } diff --git a/src/variables/time_sec.h b/src/variables/time_sec.h index 2c9b431a6e..9245cbac8b 100644 --- a/src/variables/time_sec.h +++ b/src/variables/time_sec.h @@ -35,8 +35,7 @@ class TimeSec : public Variable { m_retName("TIME_SEC") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_wday.cc b/src/variables/time_wday.cc index daf29a7d40..ab8e310bb3 100644 --- a/src/variables/time_wday.cc +++ b/src/variables/time_wday.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeWDay::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeWDay::evaluate(Transaction *transaction, transaction->m_variableTimeWDay.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeWDay)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeWDay)); } diff --git a/src/variables/time_wday.h b/src/variables/time_wday.h index 3969e74b8e..68bc459d78 100644 --- a/src/variables/time_wday.h +++ b/src/variables/time_wday.h @@ -35,8 +35,7 @@ class TimeWDay : public Variable { m_retName("TIME_WDAY") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/time_year.cc b/src/variables/time_year.cc index dbec656c74..bccb154225 100644 --- a/src/variables/time_year.cc +++ b/src/variables/time_year.cc @@ -34,8 +34,7 @@ namespace modsecurity { namespace variables { void TimeYear::evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { char tstr[200]; struct tm timeinfo; time_t timer; @@ -48,8 +47,7 @@ void TimeYear::evaluate(Transaction *transaction, transaction->m_variableTimeYear.assign(tstr); - l->push_back(new VariableValue(&m_retName, - &transaction->m_variableTimeYear)); + l->push_back(std::make_shared(&m_retName, &transaction->m_variableTimeYear)); } diff --git a/src/variables/time_year.h b/src/variables/time_year.h index 52099a8385..4a9cf9f432 100644 --- a/src/variables/time_year.h +++ b/src/variables/time_year.h @@ -35,8 +35,7 @@ class TimeYear : public Variable { m_retName("TIME_YEAR") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; std::string m_retName; }; diff --git a/src/variables/tx.h b/src/variables/tx.h index c665433d82..3b2ce073f4 100644 --- a/src/variables/tx.h +++ b/src/variables/tx.h @@ -25,6 +25,7 @@ #include "src/variables/variable.h" #include "src/run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" namespace modsecurity { @@ -39,8 +40,7 @@ class Tx_DictElement : public Variable { m_dictElement("TX:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_tx_collection->resolveMultiMatches( m_name, l, m_keyExclusion); } @@ -55,8 +55,7 @@ class Tx_NoDictElement : public Variable { : Variable("TX") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_tx_collection->resolveMultiMatches("", l, m_keyExclusion); } @@ -70,8 +69,7 @@ class Tx_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_tx_collection->resolveRegularExpression( m_dictElement, l, m_keyExclusion); } @@ -80,15 +78,17 @@ class Tx_DictElementRegexp : public VariableRegex { }; -class Tx_DynamicElement : public Variable { +class Tx_DynamicElement : public VariableWithRunTimeString { public: explicit Tx_DynamicElement(std::unique_ptr dictElement) - : Variable("TX:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "TX:dynamic", + std::move(dictElement) + ) + { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_tx_collection->resolveMultiMatches(string, l, m_keyExclusion); @@ -102,8 +102,6 @@ class Tx_DynamicElement : public Variable { std::string value) { t->m_collections.m_tx_collection->storeOrUpdateFirst(var, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/user.h b/src/variables/user.h index 8860019839..188df8fe13 100644 --- a/src/variables/user.h +++ b/src/variables/user.h @@ -25,6 +25,7 @@ #include "src/variables/variable.h" #include "src/run_time_string.h" +#include "src/variables/variable_with_runtime_string.h" namespace modsecurity { @@ -39,8 +40,7 @@ class User_DictElement : public Variable { m_dictElement("USER:" + dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_user_collection->resolveMultiMatches( m_name, t->m_collections.m_user_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -56,8 +56,7 @@ class User_NoDictElement : public Variable { : Variable("USER") { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_user_collection->resolveMultiMatches(m_name, t->m_collections.m_user_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -72,8 +71,7 @@ class User_DictElementRegexp : public VariableRegex { m_dictElement(dictElement) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { t->m_collections.m_user_collection->resolveRegularExpression( m_dictElement, t->m_collections.m_user_collection_key, t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); @@ -83,15 +81,17 @@ class User_DictElementRegexp : public VariableRegex { }; -class User_DynamicElement : public Variable { +class User_DynamicElement : public VariableWithRunTimeString { public: explicit User_DynamicElement(std::unique_ptr dictElement) - : Variable("USER:dynamic"), - m_string(std::move(dictElement)) { } + : VariableWithRunTimeString( + "USER:dynamic", + std::move(dictElement) + ) + { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { std::string string = m_string->evaluate(t); t->m_collections.m_user_collection->resolveMultiMatches( string, @@ -112,8 +112,6 @@ class User_DynamicElement : public Variable { t->m_rules->m_secWebAppId.m_value, value); } - - std::unique_ptr m_string; }; diff --git a/src/variables/variable.h b/src/variables/variable.h index 09dff6b8ce..c8ebb4e63b 100644 --- a/src/variables/variable.h +++ b/src/variables/variable.h @@ -23,7 +23,6 @@ #include "modsecurity/rules_set.h" #include "modsecurity/transaction.h" -#include "modsecurity/rule.h" #include "src/utils/string.h" #include "src/utils/regex.h" @@ -49,8 +48,7 @@ class n ## _DictElementRegexp : public VariableRegex { \ : VariableRegex(#N, regex) { } \ \ void evaluate(Transaction *transaction, \ - RuleWithActions *rule, \ - std::vector *l) override { \ + std::vector> *l) override { \ transaction-> e .resolveRegularExpression(&m_r, l, \ m_keyExclusion); \ } \ @@ -64,8 +62,7 @@ class n ## _DictElement : public VariableDictElement { \ : VariableDictElement(#N, dictElement) { } \ \ void evaluate(Transaction *transaction, \ - RuleWithActions *rule, \ - std::vector *l) override { \ + std::vector> *l) override { \ transaction-> e .resolve(m_dictElement, l); \ } \ }; @@ -78,8 +75,7 @@ class n ## _NoDictElement : public Variable { \ : Variable(#N) { } \ \ void evaluate(Transaction *transaction, \ - RuleWithActions *rule, \ - std::vector *l) override { \ + std::vector> *l) override { \ transaction-> e .resolve(l, m_keyExclusion); \ } \ }; @@ -92,13 +88,14 @@ class n : public Variable { \ : Variable(#N) { } \ \ void evaluate(Transaction *transaction, \ - RuleWithActions *rule, \ - std::vector *l) override { \ + std::vector> *l) override { \ transaction-> e .evaluate(l); \ } \ }; +// FIXME: Copy methods for variables modificators needs to be done. + namespace modsecurity { class Transaction; @@ -151,8 +148,19 @@ class KeyExclusionString : public KeyExclusion { class KeyExclusions : public std::deque> { public: - KeyExclusions() { - } + + KeyExclusions() + : std::deque>() + { }; + + + KeyExclusions(const KeyExclusions &k) + : std::deque>() + { + //for (auto &a : k) { + + //} + }; bool toOmit(std::string a) { for (auto &z : *this) { @@ -178,7 +186,7 @@ class VariableMonkeyResolution { static void stringMatchResolveMulti(Transaction *t, const std::string &variable, - std::vector *l) { + std::vector> *l) { size_t collection = variable.find("."); if (collection == std::string::npos) { collection = variable.find(":"); @@ -545,13 +553,21 @@ class VariableMonkeyResolution { class Variable : public VariableMonkeyResolution { public: explicit Variable(const std::string &name); + explicit Variable(Variable *_name); + + Variable(const Variable &v) + : m_name(v.m_name), + m_collectionName(v.m_collectionName), + m_fullName(v.m_fullName), + m_keyExclusion(v.m_keyExclusion) + { }; + virtual ~Variable() { } virtual void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) = 0; + std::vector> *l) = 0; bool inline belongsToCollection(Variable *var) { @@ -586,7 +602,14 @@ class Variable : public VariableMonkeyResolution { class VariableDictElement : public Variable { public: VariableDictElement(const std::string &name, const std::string &dict_element) - : m_dictElement(dict_element), Variable(name + ":" + dict_element) { } + : m_dictElement(dict_element), Variable(name + ":" + dict_element) + { }; + + VariableDictElement(const VariableDictElement &v) + : m_dictElement(v.m_dictElement), + Variable(v) + { }; + std::string m_dictElement; }; @@ -597,7 +620,15 @@ class VariableRegex : public Variable { VariableRegex(const std::string &name, const std::string ®ex) : m_r(regex), m_regex(regex), - Variable(name + ":" + "regex(" + regex + ")") { } + Variable(name + ":" + "regex(" + regex + ")") + { } + + VariableRegex(const VariableRegex &v) + : m_r(v.m_regex), + m_regex(v.m_regex), + Variable(v) + { }; + Utils::Regex m_r; // FIXME: no need for that. @@ -610,6 +641,7 @@ class Variables : public std::vector { return std::find_if(begin(), end(), [v](Variable *m) -> bool { return *v == *m; }) != end(); }; + bool contains(const VariableValue *v) { return std::find_if(begin(), end(), [v](Variable *m) -> bool { @@ -620,6 +652,19 @@ class Variables : public std::vector { return v->getKeyWithCollection() == *m->m_fullName.get(); }) != end(); }; + + + std::string getVariableNames(const std::string &sep = ",") { + std::string names; + for (auto a : *this) { + if (names.length() > 0) { + names = names + sep + *a->m_fullName; + } else { + names = *a->m_fullName; + } + } + return names; + } }; @@ -630,9 +675,8 @@ class VariableModificatorExclusion : public Variable { m_base(std::move(var)) { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { - m_base->evaluate(t, rule, l); + std::vector> *l) override { + m_base->evaluate(t, l); } std::unique_ptr m_base; @@ -648,26 +692,14 @@ class VariableModificatorCount : public Variable { } void evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) override { - std::vector reslIn; - VariableValue *val = NULL; - int count = 0; - - m_base->evaluate(t, rule, &reslIn); - - for (const VariableValue *a : reslIn) { - count++; - delete a; - a = NULL; - } - reslIn.clear(); + std::vector> *l) override { - std::string *res = new std::string(std::to_string(count)); - val = new VariableValue(m_fullName.get(), res); - delete res; + std::vector> reslIn; + m_base->evaluate(t, &reslIn); + auto count = reslIn.size(); - l->push_back(val); + std::string res(std::to_string(count)); + l->push_back(std::make_shared(m_fullName.get(), &res)); return; } diff --git a/src/variables/variable_with_runtime_string.h b/src/variables/variable_with_runtime_string.h new file mode 100644 index 0000000000..0e248cc8df --- /dev/null +++ b/src/variables/variable_with_runtime_string.h @@ -0,0 +1,61 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include "src/variables/variable.h" +#include "src/run_time_string.h" + +#ifndef SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_ +#define SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_ + +namespace modsecurity { +namespace variables { + +class VariableWithRunTimeString : public Variable { + public: + VariableWithRunTimeString(const std::string &name, std::unique_ptr string) + : Variable(name), + m_string(std::move(string)) + { }; + + VariableWithRunTimeString(const VariableWithRunTimeString &v) + : Variable(v), + m_string(std::unique_ptr(new RunTimeString(*v.m_string.get()))) + { }; + + VariableWithRunTimeString& operator=(const VariableWithRunTimeString& v) + { + m_string = std::unique_ptr(new RunTimeString(*v.m_string.get())); + return *this; + } + + virtual void populate(RuleWithActions *rule) { + if (m_string) { + m_string->populate(rule); + } + } + + std::string evaluateRunTimeString(Transaction *t) { + return m_string->evaluate(t); + } + + protected: + std::unique_ptr m_string; +}; + + +} // namespace variables +} // namespace modsecurity + +#endif // SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_ diff --git a/src/variables/web_app_id.h b/src/variables/web_app_id.h index d5f1aa545f..e36daf5c51 100644 --- a/src/variables/web_app_id.h +++ b/src/variables/web_app_id.h @@ -36,11 +36,10 @@ class WebAppId : public Variable { : Variable("WEBAPPID") { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override { + std::vector> *l) override { const std::string name("WEBAPPID"); const std::string rname = transaction->m_rules->m_secWebAppId.m_value; - l->push_back(new VariableValue(&m_name, &rname)); + l->push_back(std::make_shared(&m_name, &rname)); } }; diff --git a/src/variables/xml.cc b/src/variables/xml.cc index 7cb14a5fcd..90914e5ce2 100644 --- a/src/variables/xml.cc +++ b/src/variables/xml.cc @@ -42,19 +42,20 @@ #include "src/request_body_processor/xml.h" #include "modsecurity/actions/action.h" #include "src/actions/xmlns.h" +#include "src/rule_with_actions.h" + namespace modsecurity { namespace variables { #ifndef WITH_LIBXML2 void XML::evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) { } + std::vector> *l) { } #else void XML::evaluate(Transaction *t, - RuleWithActions *rule, - std::vector *l) { + std::vector> *l) { +#if 0 xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; xmlNodeSetPtr nodes; @@ -89,9 +90,8 @@ void XML::evaluate(Transaction *t, if (rule == NULL) { ms_dbg_a(t, 2, "XML: Can't look for xmlns, internal error."); } else { - std::vector acts = rule->getActionsByName("xmlns", t); - for (auto &x : acts) { - actions::XmlNS *z = (actions::XmlNS *)x; + std::vector acts = rule->getXmlNSsPtr(); + for (auto &z : acts) { if (xmlXPathRegisterNs(xpathCtx, (const xmlChar*)z->m_scope.c_str(), (const xmlChar*)z->m_href.c_str()) != 0) { ms_dbg_a(t, 1, "Failed to register XML namespace href \"" + \ @@ -124,18 +124,16 @@ void XML::evaluate(Transaction *t, content = reinterpret_cast( xmlNodeGetContent(nodes->nodeTab[i])); if (content != NULL) { - std::string *a = new std::string(content); - VariableValue *var = new VariableValue(m_fullName.get(), - a); + std::string a(content); if (!m_keyExclusion.toOmit(*m_fullName)) { - l->push_back(var); + l->push_back(std::make_shared(m_fullName.get(), &a)); } - delete a; xmlFree(content); } } xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); +#endif } #endif diff --git a/src/variables/xml.h b/src/variables/xml.h index 7b0181fe99..7c8c2e9da0 100644 --- a/src/variables/xml.h +++ b/src/variables/xml.h @@ -39,17 +39,16 @@ class XML_NoDictElement : public Variable { XML_NoDictElement() : Variable("XML"), m_plain("[XML document tree]"), - m_var(&m_name, &m_plain) { + m_var(std::make_shared(&m_name, &m_plain)) { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override { - l->push_back(new VariableValue(&m_var)); + std::vector> *l) override { + l->push_back(m_var); } std::string m_plain; - VariableValue m_var; + std::shared_ptr m_var; }; @@ -59,8 +58,7 @@ class XML : public Variable { : Variable(_name) { } void evaluate(Transaction *transaction, - RuleWithActions *rule, - std::vector *l) override; + std::vector> *l) override; }; diff --git a/test/cppcheck_suppressions.txt b/test/cppcheck_suppressions.txt index 0336b6aa24..c34b117ca7 100644 --- a/test/cppcheck_suppressions.txt +++ b/test/cppcheck_suppressions.txt @@ -19,6 +19,12 @@ *:others/mbedtls/sha1.c +// +// 3rd party string view +// +*:headers/modsecurity/string_view.hpp + + // // Code imported from ModSecurity v2... // @@ -27,20 +33,21 @@ shiftNegative:src/utils/msc_tree.cc *:src/utils/msc_tree.cc invalidScanfArgType_int:src/rules_set_properties.cc:101 invalidScanfArgType_int:src/rules_set_properties.cc:102 +redundantAssignment:src/operators/pm.cc:94 // // ModSecurity v3 code... // -unmatchedSuppression:src/utils/geo_lookup.cc:82 +functionStatic:src/operators/geo_lookup.h:39 useInitializationList:src/utils/shared_files.h:87 unmatchedSuppression:src/utils/msc_tree.cc -functionStatic:headers/modsecurity/transaction.h:404 +functionStatic:headers/modsecurity/transaction.h:452 duplicateBranch:src/audit_log/audit_log.cc:223 unreadVariable:src/request_body_processor/multipart.cc:435 stlcstrParam:src/audit_log/writer/parallel.cc:145 +functionStatic:src/engine/lua.h:70 functionStatic:src/engine/lua.h:71 -functionStatic:src/engine/lua.h:72 functionConst:src/utils/geo_lookup.h:49 useInitializationList:src/operators/rbl.h:69 constStatement:test/common/modsecurity_test.cc:82 @@ -51,6 +58,10 @@ duplicateBranch:src/request_body_processor/multipart.cc:91 syntaxError:src/transaction.cc:62 noConstructor:src/variables/variable.h:152 duplicateBranch:src/request_body_processor/multipart.cc:93 +knownConditionTrueFalse:src/operators/validate_url_encoding.cc:79 +knownConditionTrueFalse:src/operators/verify_svnr.cc:90 +noConstructor:src/actions/rule_id.h:33 +functionStatic:src/actions/rule_id.h:35 noExplicitConstructor:seclang-parser.hh @@ -61,3 +72,17 @@ preprocessorErrorDirective funcArgNamesDifferent unmatchedSuppression missingInclude +unusedFunction +missingIncludeSystem +useStlAlgorithm +preprocessorErrorDirective +funcArgNamesDifferent +unmatchedSuppression +missingInclude + +purgedConfiguration + + +// Examples +memleak:examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h:147 +memleak:examples/using_bodies_in_chunks/simple_request.cc diff --git a/test/fuzzer/afl_fuzzer.cc b/test/fuzzer/afl_fuzzer.cc index d544bc742d..dd4ef487d7 100644 --- a/test/fuzzer/afl_fuzzer.cc +++ b/test/fuzzer/afl_fuzzer.cc @@ -121,14 +121,16 @@ using namespace modsecurity; inline void op_test(const std::string &opName, const std::string &s) { Operator *op = Operator::instantiate(opName, ""); op->init("", nullptr); - op->evaluate(nullptr, nullptr, s, nullptr); + op->execute(nullptr, nullptr, s, nullptr); delete op; } int main(int argc, char** argv) { uint8_t buf[128]; +#if 0 std::string lastString; +#endif while (__AFL_LOOP(1000)) { ssize_t read_bytes; @@ -138,7 +140,9 @@ int main(int argc, char** argv) { std::string currentString = std::string(read_bytes, 128); std::string s = currentString; +#if 0 std::string z = lastString; +#endif ModSecurity *ms = new ModSecurity(); RulesSet *rules = new RulesSet(); @@ -150,52 +154,52 @@ int main(int argc, char** argv) { /** * Transformations, generated by: * - * for i in $(grep "class " -Ri src/actions/transformations/* | grep " :" | grep -v "InstantCache" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\"\)\; $(echo $i | awk '{print tolower($0)}')-\>evaluate\(s, NULL\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done; + * for i in $(grep "class " -Ri src/actions/transformations/* | grep " :" | grep -v "InstantCache" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\"\)\; $(echo $i | awk '{print tolower($0)}')-\>execute\(s, NULL\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done; * */ -Base64Decode *base64decode = new Base64Decode("Base64Decode"); base64decode->evaluate(s, NULL); delete base64decode; -Base64DecodeExt *base64decodeext = new Base64DecodeExt("Base64DecodeExt"); base64decodeext->evaluate(s, NULL); delete base64decodeext; -Base64Encode *base64encode = new Base64Encode("Base64Encode"); base64encode->evaluate(s, NULL); delete base64encode; -CmdLine *cmdline = new CmdLine("CmdLine"); cmdline->evaluate(s, NULL); delete cmdline; -CompressWhitespace *compresswhitespace = new CompressWhitespace("CompressWhitespace"); compresswhitespace->evaluate(s, NULL); delete compresswhitespace; -CssDecode *cssdecode = new CssDecode("CssDecode"); cssdecode->evaluate(s, NULL); delete cssdecode; -EscapeSeqDecode *escapeseqdecode = new EscapeSeqDecode("EscapeSeqDecode"); escapeseqdecode->evaluate(s, NULL); delete escapeseqdecode; -HexDecode *hexdecode = new HexDecode("HexDecode"); hexdecode->evaluate(s, NULL); delete hexdecode; -HexEncode *hexencode = new HexEncode("HexEncode"); hexencode->evaluate(s, NULL); delete hexencode; -HtmlEntityDecode *htmlentitydecode = new HtmlEntityDecode("HtmlEntityDecode"); htmlentitydecode->evaluate(s, NULL); delete htmlentitydecode; -JsDecode *jsdecode = new JsDecode("JsDecode"); jsdecode->evaluate(s, NULL); delete jsdecode; -Length *length = new Length("Length"); length->evaluate(s, NULL); delete length; -LowerCase *lowercase = new LowerCase("LowerCase"); lowercase->evaluate(s, NULL); delete lowercase; -Md5 *md5 = new Md5("Md5"); md5->evaluate(s, NULL); delete md5; -None *none = new None("None"); none->evaluate(s, NULL); delete none; -NormalisePath *normalisepath = new NormalisePath("NormalisePath"); normalisepath->evaluate(s, NULL); delete normalisepath; -NormalisePathWin *normalisepathwin = new NormalisePathWin("NormalisePathWin"); normalisepathwin->evaluate(s, NULL); delete normalisepathwin; -ParityEven7bit *parityeven7bit = new ParityEven7bit("ParityEven7bit"); parityeven7bit->evaluate(s, NULL); delete parityeven7bit; -ParityOdd7bit *parityodd7bit = new ParityOdd7bit("ParityOdd7bit"); parityodd7bit->evaluate(s, NULL); delete parityodd7bit; -ParityZero7bit *parityzero7bit = new ParityZero7bit("ParityZero7bit"); parityzero7bit->evaluate(s, NULL); delete parityzero7bit; -RemoveComments *removecomments = new RemoveComments("RemoveComments"); removecomments->evaluate(s, NULL); delete removecomments; -RemoveCommentsChar *removecommentschar = new RemoveCommentsChar("RemoveCommentsChar"); removecommentschar->evaluate(s, NULL); delete removecommentschar; -RemoveNulls *removenulls = new RemoveNulls("RemoveNulls"); removenulls->evaluate(s, NULL); delete removenulls; -RemoveWhitespace *removewhitespace = new RemoveWhitespace("RemoveWhitespace"); removewhitespace->evaluate(s, NULL); delete removewhitespace; -ReplaceComments *replacecomments = new ReplaceComments("ReplaceComments"); replacecomments->evaluate(s, NULL); delete replacecomments; -ReplaceNulls *replacenulls = new ReplaceNulls("ReplaceNulls"); replacenulls->evaluate(s, NULL); delete replacenulls; -Sha1 *sha1 = new Sha1("Sha1"); sha1->evaluate(s, NULL); delete sha1; -SqlHexDecode *sqlhexdecode = new SqlHexDecode("SqlHexDecode"); sqlhexdecode->evaluate(s, NULL); delete sqlhexdecode; -Transformation *transformation = new Transformation("Transformation"); transformation->evaluate(s, NULL); delete transformation; -Trim *trim = new Trim("Trim"); trim->evaluate(s, NULL); delete trim; -TrimLeft *trimleft = new TrimLeft("TrimLeft"); trimleft->evaluate(s, NULL); delete trimleft; -TrimRight *trimright = new TrimRight("TrimRight"); trimright->evaluate(s, NULL); delete trimright; -UpperCase *uppercase = new UpperCase("UpperCase"); uppercase->evaluate(s, NULL); delete uppercase; -UrlDecode *urldecode = new UrlDecode("UrlDecode"); urldecode->evaluate(s, NULL); delete urldecode; -UrlDecodeUni *urldecodeuni = new UrlDecodeUni("UrlDecodeUni"); urldecodeuni->evaluate(s, NULL); delete urldecodeuni; -UrlEncode *urlencode = new UrlEncode("UrlEncode"); urlencode->evaluate(s, NULL); delete urlencode; -Utf8ToUnicode *utf8tounicode = new Utf8ToUnicode("Utf8ToUnicode"); utf8tounicode->evaluate(s, NULL); delete utf8tounicode; +Base64Decode *base64decode = new Base64Decode("Base64Decode"); base64decode->execute(s, NULL); delete base64decode; +Base64DecodeExt *base64decodeext = new Base64DecodeExt("Base64DecodeExt"); base64decodeext->execute(s, NULL); delete base64decodeext; +Base64Encode *base64encode = new Base64Encode("Base64Encode"); base64encode->execute(s, NULL); delete base64encode; +CmdLine *cmdline = new CmdLine("CmdLine"); cmdline->execute(s, NULL); delete cmdline; +CompressWhitespace *compresswhitespace = new CompressWhitespace("CompressWhitespace"); compresswhitespace->execute(s, NULL); delete compresswhitespace; +CssDecode *cssdecode = new CssDecode("CssDecode"); cssdecode->execute(s, NULL); delete cssdecode; +EscapeSeqDecode *escapeseqdecode = new EscapeSeqDecode("EscapeSeqDecode"); escapeseqdecode->execute(s, NULL); delete escapeseqdecode; +HexDecode *hexdecode = new HexDecode("HexDecode"); hexdecode->execute(s, NULL); delete hexdecode; +HexEncode *hexencode = new HexEncode("HexEncode"); hexencode->execute(s, NULL); delete hexencode; +HtmlEntityDecode *htmlentitydecode = new HtmlEntityDecode("HtmlEntityDecode"); htmlentitydecode->execute(s, NULL); delete htmlentitydecode; +JsDecode *jsdecode = new JsDecode("JsDecode"); jsdecode->execute(s, NULL); delete jsdecode; +Length *length = new Length("Length"); length->execute(s, NULL); delete length; +LowerCase *lowercase = new LowerCase("LowerCase"); lowercase->execute(s, NULL); delete lowercase; +Md5 *md5 = new Md5("Md5"); md5->execute(s, NULL); delete md5; +None *none = new None("None"); none->execute(s, NULL); delete none; +NormalisePath *normalisepath = new NormalisePath("NormalisePath"); normalisepath->execute(s, NULL); delete normalisepath; +NormalisePathWin *normalisepathwin = new NormalisePathWin("NormalisePathWin"); normalisepathwin->execute(s, NULL); delete normalisepathwin; +ParityEven7bit *parityeven7bit = new ParityEven7bit("ParityEven7bit"); parityeven7bit->execute(s, NULL); delete parityeven7bit; +ParityOdd7bit *parityodd7bit = new ParityOdd7bit("ParityOdd7bit"); parityodd7bit->execute(s, NULL); delete parityodd7bit; +ParityZero7bit *parityzero7bit = new ParityZero7bit("ParityZero7bit"); parityzero7bit->execute(s, NULL); delete parityzero7bit; +RemoveComments *removecomments = new RemoveComments("RemoveComments"); removecomments->execute(s, NULL); delete removecomments; +RemoveCommentsChar *removecommentschar = new RemoveCommentsChar("RemoveCommentsChar"); removecommentschar->execute(s, NULL); delete removecommentschar; +RemoveNulls *removenulls = new RemoveNulls("RemoveNulls"); removenulls->execute(s, NULL); delete removenulls; +RemoveWhitespace *removewhitespace = new RemoveWhitespace("RemoveWhitespace"); removewhitespace->execute(s, NULL); delete removewhitespace; +ReplaceComments *replacecomments = new ReplaceComments("ReplaceComments"); replacecomments->execute(s, NULL); delete replacecomments; +ReplaceNulls *replacenulls = new ReplaceNulls("ReplaceNulls"); replacenulls->execute(s, NULL); delete replacenulls; +Sha1 *sha1 = new Sha1("Sha1"); sha1->execute(s, NULL); delete sha1; +SqlHexDecode *sqlhexdecode = new SqlHexDecode("SqlHexDecode"); sqlhexdecode->execute(s, NULL); delete sqlhexdecode; +Transformation *transformation = new Transformation("Transformation"); transformation->execute(s, NULL); delete transformation; +Trim *trim = new Trim("Trim"); trim->execute(s, NULL); delete trim; +TrimLeft *trimleft = new TrimLeft("TrimLeft"); trimleft->execute(s, NULL); delete trimleft; +TrimRight *trimright = new TrimRight("TrimRight"); trimright->execute(s, NULL); delete trimright; +UpperCase *uppercase = new UpperCase("UpperCase"); uppercase->execute(s, NULL); delete uppercase; +UrlDecode *urldecode = new UrlDecode("UrlDecode"); urldecode->execute(s, NULL); delete urldecode; +UrlDecodeUni *urldecodeuni = new UrlDecodeUni("UrlDecodeUni"); urldecodeuni->execute(s, NULL); delete urldecodeuni; +UrlEncode *urlencode = new UrlEncode("UrlEncode"); urlencode->execute(s, NULL); delete urlencode; +Utf8ToUnicode *utf8tounicode = new Utf8ToUnicode("Utf8ToUnicode"); utf8tounicode->execute(s, NULL); delete utf8tounicode; /** * Operators, generated by: * - * for i in $(grep "class " -Ri src/operators/* | grep " :" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\", z, false\)\; $(echo $i | awk '{print tolower($0)}')-\>evaluate\(t, s\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done; + * for i in $(grep "class " -Ri src/operators/* | grep " :" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\(\"$i\", z, false\)\; $(echo $i | awk '{print tolower($0)}')-\>execute\(t, s\)\; delete $(echo $i | awk '{print tolower($0)}')\;; done; * */ op_test("BeginsWith", s); @@ -266,8 +270,9 @@ op_test("Within", s); delete t; delete rules; delete ms; - +#if 0 lastString = currentString; +#endif } return 0; } diff --git a/test/regression/regression.cc b/test/regression/regression.cc index c4600fae4c..64db189338 100644 --- a/test/regression/regression.cc +++ b/test/regression/regression.cc @@ -211,7 +211,7 @@ void perform_unit_test(ModSecurityTest *test, */ if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; } @@ -254,7 +254,7 @@ void perform_unit_test(ModSecurityTest *test, /* Parser error was expected, but with a different content */ if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; } @@ -280,7 +280,7 @@ void perform_unit_test(ModSecurityTest *test, if (t->parser_error.empty() == false) { if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; std::cout << KWHT << "Expected a parser error." \ @@ -387,7 +387,7 @@ void perform_unit_test(ModSecurityTest *test, if (!d->contains(t->debug_log)) { if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; } @@ -399,7 +399,7 @@ void perform_unit_test(ModSecurityTest *test, } else if (r.status != t->http_code) { if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; } @@ -423,7 +423,7 @@ void perform_unit_test(ModSecurityTest *test, && !contains(getAuditLogContent(modsec_transaction->m_rules->m_auditLog->m_path1), t->audit_log)) { if (test->m_automake_output) { std::cout << ":test-result: FAIL " << filename \ - << ":" << t->name << std::endl; + << ":" << t->name << ":" << *count << std::endl; } else { std::cout << KRED << "failed!" << RESET << std::endl; } diff --git a/test/test-cases/regression/action-block.json b/test/test-cases/regression/action-block.json index 239df02715..8bed10927b 100644 --- a/test/test-cases/regression/action-block.json +++ b/test/test-cases/regression/action-block.json @@ -27,7 +27,7 @@ }, "rules":[ "SecRuleEngine On", - "SecDefaultAction \"phase:1,log,block,status:404\"", + "SecDefaultAction \"phase:1,log,status:404\"", "SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5\"" ] }, @@ -59,7 +59,7 @@ }, "rules":[ "SecRuleEngine On", - "SecDefaultAction \"phase:1,log,block,deny,status:400\"", + "SecDefaultAction \"phase:1,log,deny,status:400\"", "SecRule REQUEST_URI \"@contains path1\" \"phase:1,block,id:5\"" ] } diff --git a/test/test-cases/regression/action-initcol.json b/test/test-cases/regression/action-initcol.json index 5051f2e6a5..c6ddd1c21d 100644 --- a/test/test-cases/regression/action-initcol.json +++ b/test/test-cases/regression/action-initcol.json @@ -13,7 +13,6 @@ "request":{ "headers":{ "Host":"localhost", - "User-Agent":"curl/7.38.0", "Accept":"*/*", "User-Agent":"My sweet little browser" }, diff --git a/test/test-cases/regression/action-tnf-base64.json b/test/test-cases/regression/action-tnf-base64.json index 7cb047ce2f..08875aaa70 100644 --- a/test/test-cases/regression/action-tnf-base64.json +++ b/test/test-cases/regression/action-tnf-base64.json @@ -36,7 +36,7 @@ ] }, "expected":{ - "debug_log": "t:base64encode: \"dmFsdWUyCg==\"" + "debug_log": "t:base64Encode: \"dmFsdWUyCg==\"" }, "rules":[ "SecRuleEngine On", @@ -80,7 +80,7 @@ ] }, "expected":{ - "debug_log": "t:base64decode: \"value2\"" + "debug_log": "t:base64Decode: \"value2\"" }, "rules":[ "SecRuleEngine On", diff --git a/test/test-cases/regression/auditlog-ctl.json b/test/test-cases/regression/auditlog-ctl.json new file mode 100644 index 0000000000..40a220b939 --- /dev/null +++ b/test/test-cases/regression/auditlog-ctl.json @@ -0,0 +1,240 @@ +[ + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "ctl:auditlogparts : +E", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": "" + }, + "response": { + "headers": { + "Content-Type": "plain\/text\n\r" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "", + "debug_log": "Request was relevant to be saved. Parts: 34", + "error_log": "", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts A", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Parallel", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:2,t:trim,deny,auditlog\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "ctl:auditlogparts : +E-E", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": "" + }, + "response": { + "headers": { + "Content-Type": "plain\/text\n\r" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "", + "debug_log": "Request was relevant to be saved. Parts: 2", + "error_log": "", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts A", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Parallel", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:2,t:trim,ctl:auditlogparts=-E\"", + "SecRule ARGS \"@contains test\" \"id:3,t:trim,deny,auditlog\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "ctl:auditlogparts : +E-E+E", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": "" + }, + "response": { + "headers": { + "Content-Type": "plain\/text\n\r" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "", + "debug_log": "Request was relevant to be saved. Parts: 34", + "error_log": "", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts A", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Parallel", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:2,t:trim,ctl:auditlogparts=-E\"", + "SecRule ARGS \"@contains test\" \"id:3,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:4,t:trim,deny,auditlog\"" + ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "ctl:auditlogparts : +E-E+E+H", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1= test ¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": "" + }, + "response": { + "headers": { + "Content-Type": "plain\/text\n\r" + }, + "body": [ + "test" + ] + }, + "expected": { + "audit_log": "", + "debug_log": "Request was relevant to be saved. Parts: 290", + "error_log": "", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts A", + "SecAuditLogStorageDir /tmp/test", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0600", + "SecAuditLogType Parallel", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"", + "SecRule ARGS \"@contains test\" \"id:1,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:2,t:trim,ctl:auditlogparts=-E\"", + "SecRule ARGS \"@contains test\" \"id:3,t:trim,ctl:auditlogparts=+E\"", + "SecRule ARGS \"@contains test\" \"id:4,t:trim,ctl:auditlogparts=+H\"", + "SecRule ARGS \"@contains test\" \"id:5,t:trim,deny,auditlog\"" + ] + } +] diff --git a/test/test-cases/regression/auditlog.json b/test/test-cases/regression/auditlog.json index 33b6110111..e872bbaf7a 100644 --- a/test/test-cases/regression/auditlog.json +++ b/test/test-cases/regression/auditlog.json @@ -3,7 +3,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "auditlog : basic parser test - Parallel", + "title": "auditlog : basic parser test - Parallel 1", "client": { "ip": "200.249.12.31", "port": 2313 @@ -40,7 +40,7 @@ }, "expected": { "audit_log": "", - "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", + "debug_log": "Saving this request as part of the audit logs", "error_log": "", "http_code": 403 }, @@ -60,7 +60,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "auditlog : basic parser test - Serial", + "title": "auditlog : basic parser test - Serial 1", "client": { "ip": "200.249.12.31", "port": 2313 @@ -96,8 +96,8 @@ ] }, "expected": { - "audit_log": "", - "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", + "audit_log": "Access denied with code 403", + "debug_log": "", "error_log": "", "http_code": 403 }, @@ -118,7 +118,7 @@ "enabled": 1, "version_min": 300000, "version_max": 0, - "title": "auditlog : basic parser test - Parallel", + "title": "auditlog : basic parser test - Parallel 2", "client": { "ip": "200.249.12.31", "port": 2313 @@ -154,8 +154,8 @@ ] }, "expected": { - "audit_log": "", - "debug_log": "\\[9\\] T \\(0\\) t:trim: \"test", + "audit_log": "www.modsecurity.org 200.249.12.31", + "debug_log": "Saving this request as part of the audit logs", "error_log": "", "http_code": 403 }, @@ -220,5 +220,55 @@ "SecAuditLogType Serial", "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" ] + }, + { + "enabled": 1, + "version_min": 300000, + "version_max": 0, + "title": "auditlog : messages verification - nolog,noauditlog", + "client": { + "ip": "200.249.12.31", + "port": 2313 + }, + "server": { + "ip": "200.249.12.31", + "port": 80 + }, + "request": { + "headers": { + "Host": "www.modsecurity.org", + "User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)", + "Accept": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8", + "Accept-Language": "en-us,en;q=0.5", + "Accept-Encoding": "gzip,deflate", + "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", + "Keep-Alive": "300", + "Connection": "keep-alive", + "Pragma": "no-cache", + "Cache-Control": "no-cache" + }, + "uri": "\/test.pl?param1=test¶m2=test2", + "method": "GET", + "http_version": 1.1, + "body": "" + }, + "expected": { + "audit_log": "1556", + "error_log": "", + "http_code": 403 + }, + "rules": [ + "SecRuleEngine On", + "SecDefaultAction \"phase:1,nolog,auditlog,status:403,pass\"", + "SecRule ARGS \"@contains test\" \"id:1555,phase:1,log,noauditlog\"", + "SecRule ARGS \"@contains test\" \"id:1556,phase:1,deny,auditlog\"", + "SecAuditEngine RelevantOnly", + "SecAuditLogParts ABCFHZ", + "SecAuditLog /tmp/test/modsec_audit_auditlog_1.log", + "SecAuditLogDirMode 0766", + "SecAuditLogFileMode 0666", + "SecAuditLogType Serial", + "SecAuditLogRelevantStatus \"^(?:5|4(?!04))\"" + ] } ] diff --git a/test/test-cases/regression/collection-regular_expression_selection.json b/test/test-cases/regression/collection-regular_expression_selection.json index cde06ac767..ec53d0c90b 100644 --- a/test/test-cases/regression/collection-regular_expression_selection.json +++ b/test/test-cases/regression/collection-regular_expression_selection.json @@ -48,12 +48,12 @@ }, "expected":{ "audit_log":"", - "debug_log":"T \\(0\\) t:lowercase: \"test2\"", + "debug_log":"T \\(0\\) t:lowerCase: \"test2\"", "error_log":"" }, "rules":[ "SecRuleEngine On", - "SecRule ARGS:/^id_/ \"@contains nops\" \"id:1,t:lowercase,block,status:404\"" + "SecRule ARGS:/^id_/ \"@contains nops\" \"id:1,t:lowerCase,block,status:404\"" ] }, { diff --git a/test/test-cases/regression/config-include-bad.json b/test/test-cases/regression/config-include-bad.json index 76797552d7..ed8b0156e0 100644 --- a/test/test-cases/regression/config-include-bad.json +++ b/test/test-cases/regression/config-include-bad.json @@ -43,7 +43,7 @@ "version_min":300000, "title":"Include - duplicate id", "expected":{ - "parser_error": "Rule id: 40 is duplicated" + "parser_error": "There are multiple rules defined with same id. The ID 40 is defined at" }, "rules":[ "SecRuleEngine On", diff --git a/test/test-cases/regression/config-secdefaultaction.json b/test/test-cases/regression/config-secdefaultaction.json index bb3d7d8104..caa4426fa6 100644 --- a/test/test-cases/regression/config-secdefaultaction.json +++ b/test/test-cases/regression/config-secdefaultaction.json @@ -48,14 +48,14 @@ }, "expected":{ "audit_log":"", - "debug_log":"lowercase: \"300\"", + "debug_log":"lowerCase: \"300\"", "error_log":"" }, "rules":[ "SecRuleEngine On", - "SecDefaultAction \"phase:2,t:lowercase,pass\"", + "SecDefaultAction \"phase:2,t:lowerCase,pass\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\"", - "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none\"" + "SecRule TX \"@contains to_test\" \"id:2,t:lowerCase,t:none\"" ] }, { @@ -123,7 +123,7 @@ "version_max":0, "title":"Testing action :: SecDefaultAction: t:none", "expected":{ - "parser_error":"The transformation none is not suitable to be part of the SecDefaultActions" + "parser_error":"The action 't:none' is not suitable to be part of the SecDefaultActions" }, "rules":[ "SecRuleEngine On", @@ -272,11 +272,12 @@ }, "expected":{ "audit_log":"", - "debug_log":"Request was relevant to be saved.", + "debug_log":"Saving this request as part of the audit logs", "http_code": 302 }, "rules":[ "SecRuleEngine On", + "SecAuditEngine On", "SecDefaultAction \"phase:2,log,auditlog,status:302,redirect:'http://www.google.com'\"", "SecRule REQUEST_HEADERS \"@contains PHPSESSID\" \"phase:2,id:1,block\"", "SecRule TX \"@contains to_test\" \"id:2,t:lowercase,t:none,block\"" diff --git a/test/test-cases/regression/config-update-action-by-id.json b/test/test-cases/regression/config-update-action-by-id.json index 4e1a3fc24e..6e343be5fb 100644 --- a/test/test-cases/regression/config-update-action-by-id.json +++ b/test/test-cases/regression/config-update-action-by-id.json @@ -122,7 +122,7 @@ }, "expected":{ "http_code": 200, - "debug_log": "Running action: log" + "debug_log": "Rule returned 1" }, "rules":[ "SecRuleEngine On", @@ -167,7 +167,7 @@ }, "expected":{ "http_code": 200, - "debug_log": "Running action: log" + "debug_log": "Rule returned 1" }, "rules":[ "SecRuleEngine On", diff --git a/test/test-cases/regression/issue-1528.json b/test/test-cases/regression/issue-1528.json index f2257055c2..74f2c3db9e 100644 --- a/test/test-cases/regression/issue-1528.json +++ b/test/test-cases/regression/issue-1528.json @@ -31,8 +31,8 @@ }, "rules": [ "SecRuleEngine On", - "SecAction \"id:1, nolog, setvar:tx.bad_value=attack\"", - "SecRule ARGS:param \"@rx ^%{tx.bad_value}$\" \"id:2,block\"" + "SecAction \"id:1, setvar:tx.bad_value=attack\"", + "SecRule ARGS:param \"@rx ^%{tx.bad_value}$\" \"id:2,log\"" ] } ] diff --git a/test/test-cases/regression/issue-1844.json b/test/test-cases/regression/issue-1844.json index 6ccb1f5e8a..df1a4ec624 100644 --- a/test/test-cases/regression/issue-1844.json +++ b/test/test-cases/regression/issue-1844.json @@ -37,10 +37,12 @@ ] }, "expected":{ - "error_log":"line \"29\"" + "error_log":"line \"29\"", + "http_code": 403 }, "rules":[ "SecRuleEngine On", + "SecDefaultAction \"phase:request,deny\"", "SecRule WEBAPPID \"@contains test1\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] @@ -129,10 +131,12 @@ ] }, "expected":{ - "error_log":"line \"84\"" + "error_log":"line \"84\"", + "http_code": 403 }, "rules":[ "SecRuleEngine On", + "SecDefaultAction \"phase:request,deny\"", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] @@ -175,11 +179,13 @@ ] }, "expected":{ - "error_log":"line \"116\"" + "error_log":"line \"116\"", + "http_code":403 }, "rules":[ "SecRuleEngine On", - "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", + "SecDefaultAction \"phase:request,deny\"", + "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,deny,t:trim\"", "Include test-cases/data/big-file.conf" ] }, @@ -221,10 +227,12 @@ ] }, "expected":{ - "error_log":"line \"174\"" + "error_log":"line \"174\"", + "http_code":403 }, "rules":[ "SecRuleEngine On", + "SecDefaultAction \"phase:request,deny\"", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/big-file.conf" ] @@ -267,10 +275,12 @@ ] }, "expected":{ - "error_log":"line \"174\"" + "error_log":"line \"174\"", + "http_code":403 }, "rules":[ "SecRuleEngine On", + "SecDefaultAction \"phase:request,deny\"", "SecRule WEBAPPID \"@contains test3\" \"id:1,phase:3,pass,t:trim\"", "Include test-cases/data/not-so-big-file.conf" ] diff --git a/test/test-cases/regression/misc-variable-under-quotes.json b/test/test-cases/regression/misc-variable-under-quotes.json index 5310f61e8c..c82c96e1a5 100644 --- a/test/test-cases/regression/misc-variable-under-quotes.json +++ b/test/test-cases/regression/misc-variable-under-quotes.json @@ -31,10 +31,10 @@ ] }, "expected":{ - "debug_log":"t:lowercase:" + "debug_log":"t:lowerCase:" }, "rules":[ - "SecRule \"REQUEST_LINE\" \"@contains index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowercase,ctl:auditLogParts=+E\"" + "SecRule \"REQUEST_LINE\" \"@contains index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowerCase,ctl:auditLogParts=+E\"" ] }, { @@ -69,10 +69,10 @@ ] }, "expected":{ - "debug_log":"t:lowercase:" + "debug_log":"t:lowerCase:" }, "rules":[ - "SecRule \"REQUEST_LINE\" \"index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowercase,ctl:auditLogParts=+E\"" + "SecRule \"REQUEST_LINE\" \"index.php/admin/cms/wysiwyg/directive/\" \"id:1,t:lowerCase,ctl:auditLogParts=+E\"" ] } ] diff --git a/test/test-cases/regression/offset-variable.json b/test/test-cases/regression/offset-variable.json index 99c9e19a71..20d87aa2a1 100644 --- a/test/test-cases/regression/offset-variable.json +++ b/test/test-cases/regression/offset-variable.json @@ -22,10 +22,12 @@ ] }, "expected":{ - "error_log":"o0,3v23,6t:trim" + "error_log":"o0,3v23,6t:trim", + "http_code": 403 }, "rules":[ - "SecRule ARGS \"@rx val\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS \"@rx val\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny,log\"" ] }, { @@ -51,10 +53,12 @@ ] }, "expected":{ - "error_log":"o3,3v37,6t:trim" + "error_log":"o3,3v37,6t:trim", + "http_code":403 }, "rules":[ - "SecRule ARGS_GET \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_GET \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -83,11 +87,13 @@ ] }, "expected":{ - "error_log":"o3,3v142,6t:trim" + "error_log":"o3,3v142,6t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_POST \"@rx ue1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_POST \"@rx ue1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -116,11 +122,13 @@ ] }, "expected":{ - "error_log":"o3,3v156,6t:trim" + "error_log":"o3,3v156,6t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_POST \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_POST \"@rx ue2\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -149,11 +157,13 @@ ] }, "expected":{ - "error_log":"o0,6v17,6t:trim" + "error_log":"o0,6v17,6t:trim", + "http_code":403 }, "rules":[ + "SecRuleEngine On", "SecRequestBodyAccess On", - "SecRule ARGS_GET_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRule ARGS_GET_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -182,11 +192,13 @@ ] }, "expected":{ - "error_log":"o0,6v31,6t:trim" + "error_log":"o0,6v31,6t:trim", + "http_code":403 }, "rules":[ + "SecRuleEngine On", "SecRequestBodyAccess On", - "SecRule ARGS_GET_NAMES \"@rx param2\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRule ARGS_GET_NAMES \"@rx param2\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -219,7 +231,7 @@ }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_GET_NAMES \"@rx am1 par\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRule ARGS_GET_NAMES \"@rx am1 par\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -252,7 +264,7 @@ }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_GET_NAMES \"@rx am1 param2 par\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRule ARGS_GET_NAMES \"@rx am1 param2 par\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -281,11 +293,13 @@ ] }, "expected":{ - "error_log": "0,6v149,6t:trim" + "error_log": "0,6v149,6t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_POST_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_POST_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -314,11 +328,13 @@ ] }, "expected":{ - "error_log":"o0,6v17,6t:trim" + "error_log":"o0,6v17,6t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_NAMES \"@rx param1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -344,11 +360,13 @@ ] }, "expected":{ - "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim" + "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -374,11 +392,13 @@ ] }, "expected":{ - "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim" + "error_log":"v16,6v23,6v30,6v37,6v44,6v51,6t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule ARGS_COMBINED_SIZE \"@gt 1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -405,11 +425,13 @@ ] }, "expected":{ - "error_log":"o23,6v0,63t:trim" + "error_log":"o23,6v0,63t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_LINE \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_LINE \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -437,11 +459,13 @@ ] }, "expected":{ - "error_log":"o0,3v0,3t:trim" + "error_log":"o0,3v0,3t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_METHOD \"GET\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_METHOD \"GET\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -469,11 +493,13 @@ ] }, "expected":{ - "error_log":"o5,3v58,8t:trim" + "error_log":"o5,3v58,8t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_PROTOCOL \"1.1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_PROTOCOL \"1.1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -501,11 +527,13 @@ ] }, "expected":{ - "error_log":"o1,5v4,11t:trim" + "error_log":"o1,5v4,11t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule PATH_INFO \"index\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule PATH_INFO \"index\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -533,11 +561,13 @@ ] }, "expected":{ - "error_log":"o7,6v16,41t:trim" + "error_log":"o7,6v16,41t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule QUERY_STRING \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule QUERY_STRING \"value1\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -565,11 +595,13 @@ ] }, "expected":{ - "error_log":"o6,4v5,10t:trim" + "error_log":"o6,4v5,10t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_BASENAME \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_BASENAME \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -597,11 +629,13 @@ ] }, "expected":{ - "error_log":"o7,4v4,59t:trim" + "error_log":"o7,4v4,59t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_URI \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_URI \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -629,11 +663,14 @@ ] }, "expected":{ - "error_log":"o7,4v4,59t:trim" + "error_log":"o7,4v4,59t:trim", + "http_code": 403 + }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_URI_RAW \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_URI_RAW \"html\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, @@ -661,11 +698,13 @@ ] }, "expected":{ - "error_log":"o0,9v89,9t:trim" + "error_log":"o0,9v89,9t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS \"localhost\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_HEADERS \"localhost\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, @@ -693,11 +732,13 @@ ] }, "expected":{ - "error_log":"o14,3v163,33t:trim" + "error_log":"o14,3v163,33t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS \"www\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_HEADERS \"www\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -724,11 +765,13 @@ ] }, "expected":{ - "error_log":"o0,5v162,5t:trim" + "error_log":"o0,5v162,5t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -755,11 +798,13 @@ ] }, "expected":{ - "error_log":"o0,5v79,5t:trim" + "error_log":"o0,5v79,5t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops'\"" + "SecRuleEngine On", + "SecRule AUTH_TYPE \"Basic\" \"id:1,phase:2,pass,t:trim,msg:'ops',deny\"" ] }, { @@ -786,11 +831,13 @@ ] }, "expected":{ - "error_log":"o0,4v64,13t:lowercase" + "error_log":"o0,4v64,13t:lowerCase", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_HEADERS_NAMES \"auth\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_HEADERS_NAMES \"auth\" \"id:1,phase:2,pass,t:lowerCase,msg:'ops',deny\"" ] }, { @@ -818,11 +865,13 @@ ] }, "expected":{ - "error_log":"o1,2v216,3t:lowercase" + "error_log":"o1,2v216,3t:lowerCase", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_COOKIES \"es\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_COOKIES \"es\" \"id:1,phase:2,pass,t:lowerCase,msg:'ops',deny\"" ] }, { @@ -850,11 +899,13 @@ ] }, "expected":{ - "error_log":"o0,1v223,1t:lowercase" + "error_log":"o0,1v223,1t:lowerCase", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_COOKIES \"z\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_COOKIES \"z\" \"id:1,phase:2,pass,t:lowerCase,msg:'ops',deny\"" ] }, { @@ -882,11 +933,13 @@ ] }, "expected":{ - "error_log":"o0,1v228,1t:lowercase" + "error_log":"o0,1v228,1t:lowerCase", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_COOKIES \"b\" \"id:1,phase:2,pass,t:lowercase,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_COOKIES \"b\" \"id:1,phase:2,pass,t:lowerCase,msg:'ops',deny\"" ] }, { @@ -914,11 +967,13 @@ ] }, "expected":{ - "error_log":"o0,1v226,1" + "error_log":"o0,1v226,1", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_COOKIES_NAMES \"t\" \"id:1,phase:2,pass,msg:'ops'\"" + "SecRuleEngine On", + "SecRule REQUEST_COOKIES_NAMES \"t\" \"id:1,phase:2,pass,msg:'ops',deny\"" ] }, { @@ -956,11 +1011,12 @@ ] }, "expected":{ - "error_log":"o0,7v198,30t:trim" + "error_log":"o0,7v198,30t:trim", + "http_code":403 }, "rules":[ "SecRuleEngine On", - "SecRule REMOTE_USER \"Aladdin\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule REMOTE_USER \"Aladdin\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1005,11 +1061,13 @@ ] }, "expected":{ - "error_log":"o45,30v193,516t:trim" + "error_log":"o45,30v193,516t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1054,11 +1112,13 @@ ] }, "expected":{ - "error_log":"o45,30v193,516t:trim" + "error_log":"o45,30v193,516t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_BODY \"Content-Disposition: form-data\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1103,11 +1163,13 @@ ] }, "expected":{ - "error_log":"v193,516t:trim" + "error_log":"v193,516t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_BODY_LENGTH \"@gt 5\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_BODY_LENGTH \"@gt 5\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1152,11 +1214,13 @@ ] }, "expected":{ - "error_log":"o6,5v5,11t:trim" + "error_log":"o6,5v5,11t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"/file\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"/file\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1201,11 +1265,13 @@ ] }, "expected":{ - "error_log":"o6,8v5,23t:trim" + "error_log":"o6,8v5,23t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1250,11 +1316,13 @@ ] }, "expected":{ - "error_log":"o6,8v5,23t:trim" + "error_log":"o6,8v5,23t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule REQUEST_FILENAME \"/f i l e\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1299,11 +1367,13 @@ ] }, "expected":{ - "error_log":"o0,4v306,4t:trim" + "error_log":"o0,4v306,4t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS \"test\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule ARGS \"test\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1352,11 +1422,13 @@ ] }, "expected":{ - "error_log":"o0,5v402,5t:trim" + "error_log":"o0,5v402,5t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule ARGS \"test2\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule ARGS \"test2\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1405,11 +1477,13 @@ ] }, "expected":{ - "error_log":"o0,16v680,20t:trim" + "error_log":"o0,16v680,20t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES \"small_text_file2\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES \"small_text_file2\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1458,11 +1532,13 @@ ] }, "expected":{ - "error_log":"o0,16v512,20t:trim" + "error_log":"o0,16v512,20t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES \"small_text_file1\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES \"small_text_file1\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1511,11 +1587,13 @@ ] }, "expected":{ - "error_log":"o0,8o0,8v491,8t:trimo0,16o0,16v709,16t:trim" + "error_log":"o0,8o0,8v491,8t:trimo0,16o0,16v709,16t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES_NAMES \"(fiasdfasdfledata|filedata)\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES_NAMES \"(fiasdfasdfledata|filedata)\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1564,11 +1642,13 @@ ] }, "expected":{ - "error_log":"v560,32t:trim" + "error_log":"v560,32t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES_SIZES:filedata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES_SIZES:filedata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1617,11 +1697,13 @@ ] }, "expected":{ - "error_log":"v754,38t:trim" + "error_log":"v754,38t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES_SIZES:fiasdfasdfledata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES_SIZES:fiasdfasdfledata \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1670,11 +1752,13 @@ ] }, "expected":{ - "error_log":"v560,32v754,38t:trim" + "error_log":"v560,32v754,38t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", - "SecRule FILES_COMBINED_SIZE \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRuleEngine On", + "SecRule FILES_COMBINED_SIZE \"@gt 0\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1723,13 +1807,15 @@ ] }, "expected":{ - "error_log":"o8,7v754,38t:trim" + "error_log":"o8,7v754,38t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", "SecUploadKeepFiles On", + "SecRuleEngine On", "SecUploadDir /tmp", - "SecRule FILES_TMP_CONTENT \"another\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule FILES_TMP_CONTENT \"another\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1778,13 +1864,15 @@ ] }, "expected":{ - "error_log":"o15,5v560,32t:trim" + "error_log":"o15,5v560,32t:trim", + "http_code": 403 }, "rules":[ "SecRequestBodyAccess On", "SecUploadKeepFiles On", + "SecRuleEngine On", "SecUploadDir /tmp", - "SecRule FILES_TMP_CONTENT:small_text_file1.txt \"small\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule FILES_TMP_CONTENT:small_text_file1.txt \"small\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1833,13 +1921,15 @@ ] }, "expected":{ - "error_log":"o6,4v5,23t:trim" + "error_log":"o6,4v5,23t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", "SecUploadKeepFiles On", + "SecRuleEngine On", "SecUploadDir /tmp", - "SecRule PATH_INFO \"/f i\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule PATH_INFO \"/f i\" \"id:1,phase:3,t:trim,msg:'s',deny\"" ] }, { @@ -1888,13 +1978,15 @@ ] }, "expected":{ - "error_log":"o0,20v680,20t:trim" + "error_log":"o0,20v680,20t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", "SecUploadKeepFiles On", + "SecRuleEngine On", "SecUploadDir /tmp", - "SecRule MULTIPART_FILENAME \"small_text_file2.txt\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule MULTIPART_FILENAME \"small_text_file2.txt\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] }, { @@ -1943,13 +2035,15 @@ ] }, "expected":{ - "error_log":"o0,16v709,16t:trim" + "error_log":"o0,16v709,16t:trim", + "http_code":403 }, "rules":[ "SecRequestBodyAccess On", "SecUploadKeepFiles On", + "SecRuleEngine On", "SecUploadDir /tmp", - "SecRule MULTIPART_NAME \"fiasdfasdfledata\" \"id:1,phase:3,pass,t:trim,msg:'s'\"" + "SecRule MULTIPART_NAME \"fiasdfasdfledata\" \"id:1,phase:3,pass,t:trim,msg:'s',deny\"" ] } ] diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index d6b9839fe5..e077157341 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -79,11 +79,12 @@ }, "expected":{ "debug_log":"Executing operator \"Rx\" with param \"\\^0\\$\"", - "error_log":"Matched \"Operator `Rx' with parameter `\\^0\\$'" + "error_log":"Matched \"Operator `Rx' with parameter `\\^0\\$'", + "http_code": 403 }, "rules":[ "SecRuleEngine On", - "SecRule REQUEST_HEADERS:Content-Length \"!^0$\" \"id:1,phase:2,pass,t:trim,block\"" + "SecRule REQUEST_HEADERS:Content-Length \"!^0$\" \"id:1,phase:2,pass,t:trim,deny\"" ] } ] diff --git a/test/test-cases/regression/tempCodeRunnerFile.json b/test/test-cases/regression/tempCodeRunnerFile.json new file mode 100644 index 0000000000..7437a22fda --- /dev/null +++ b/test/test-cases/regression/tempCodeRunnerFile.json @@ -0,0 +1,38 @@ + + "enabled":1, + "version_min":300000, + "title":"Testing allow action (1/3)", + "expected":{ + "debug_log": "Skipped rule id 'action-allow.json:3' as request trough the utilization of an `allow' action", + "http_code": 200 + }, + "client":{ + "ip":"200.249.12.31", + "port":123 + }, + "request":{ + "headers":{ + "Host":"localhost", + "User-Agent":"curl/7.38.0", + "Accept":"*/*", + "User-Agent":"My sweet little browser", + "Cookie": "PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120" + }, + "uri":"/?key=value&key=other_value", + "method":"GET" + }, + "server":{ + "ip":"200.249.12.31", + "port":80 + }, + "rules":[ + "SecRuleEngine On", + "SecAction \"phase:1,allow,msg:'ALLOWED',id:500065\"", + "SecAction \"phase:1,deny,msg:'DENIED',id:500066\"" + ] + }, + { + "enabled":1, + "version_min":300000, + "title":"Testing allow action (2/3)", + "expected":{ \ No newline at end of file diff --git a/test/test-cases/regression/transformations.json b/test/test-cases/regression/transformations.json index dcb328f16c..d49ae43427 100644 --- a/test/test-cases/regression/transformations.json +++ b/test/test-cases/regression/transformations.json @@ -107,12 +107,12 @@ }, "expected": { "audit_log": "", - "debug_log": "lowercase: \"test", + "debug_log": "lowerCase: \"test", "error_log": "" }, "rules": [ "SecRuleEngine On", - "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim,t:lowercase\"" + "SecRule ARGS \"@contains test \" \"id:1,pass,t:trim,t:lowerCase\"" ] } ] diff --git a/test/test-suite.sh b/test/test-suite.sh index e242c7baf8..ce03c244e1 100755 --- a/test/test-suite.sh +++ b/test/test-suite.sh @@ -30,10 +30,10 @@ else RET=$? if [ $RET -eq 127 ] then - echo ":test-result: SKIP: json is not enabled. (unit/$RET) ../$FILE" + echo ":test-result: SKIP: json is not enabled. (unit/$RET) ../$FILE:$i" elif [ $RET -ne 0 ] then - echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE" + echo ":test-result: FAIL possible segfault: (unit/$RET) ../$FILE:$i" fi fi diff --git a/test/unit/unit.cc b/test/unit/unit.cc index f610a21ebf..40b47dfb30 100644 --- a/test/unit/unit.cc +++ b/test/unit/unit.cc @@ -90,8 +90,14 @@ void perform_unit_test(ModSecurityTest *test, UnitTest *t, } delete op; } else if (t->type == "tfn") { + modsecurity::ModSecString in; + modsecurity::ModSecString out; + std::string ret; + in.assign(t->input.c_str(), t->input.size()); Transformation *tfn = Transformation::instantiate("t:" + t->name); - std::string ret = tfn->evaluate(t->input, NULL); + tfn->execute(NULL, in, out); + ret.assign(out.c_str(), out.size()); + t->obtained = 1; t->obtainedOutput = ret; if (ret != t->output) { diff --git a/tools/rules-check/rules-check.cc b/tools/rules-check/rules-check.cc index 91d78d841d..fb3108d12b 100644 --- a/tools/rules-check/rules-check.cc +++ b/tools/rules-check/rules-check.cc @@ -91,6 +91,7 @@ int main(int argc, char **argv) { if (err.empty() == false) { std::cerr << " " << err << std::endl; } + rules->dump(); next: args++; }