From 59114dd5984942a6587ee5810295a56536b85469 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Wed, 4 Jan 2017 15:30:45 -0300 Subject: [PATCH] Refactoring on the operators parsers (2/2) This is the first step towards remove the memory leaks in the parser --- src/collection/backend/lmdb.cc | 2 +- src/operators/begins_with.h | 5 +- src/operators/contains.h | 6 +- src/operators/contains_word.h | 7 +- src/operators/ends_with.h | 6 +- src/operators/eq.h | 6 +- src/operators/fuzzy_hash.cc | 7 - src/operators/fuzzy_hash.h | 9 +- src/operators/ge.h | 6 +- src/operators/geo_lookup.h | 7 +- src/operators/gsblookup.cc | 8 +- src/operators/gsblookup.h | 9 +- src/operators/gt.h | 9 +- src/operators/inspect_file.cc | 7 - src/operators/inspect_file.h | 9 +- src/operators/ip_match.h | 7 +- src/operators/ip_match_f.h | 5 +- src/operators/ip_match_from_file.h | 4 +- src/operators/le.h | 6 +- src/operators/lt.h | 6 +- src/operators/operator.h | 9 +- src/operators/pm.h | 11 +- src/operators/pm_f.h | 3 +- src/operators/pm_from_file.h | 7 +- src/operators/rbl.h | 17 +- src/operators/rsub.cc | 7 +- src/operators/rsub.h | 11 +- src/operators/rx.h | 8 +- src/operators/str_eq.h | 5 +- src/operators/str_match.h | 5 +- src/operators/validate_byte_range.h | 9 +- src/operators/validate_dtd.h | 5 +- src/operators/validate_hash.cc | 6 - src/operators/validate_hash.h | 8 +- src/operators/validate_schema.h | 8 +- src/operators/validate_url_encoding.h | 3 +- src/operators/verify_cc.h | 4 + src/operators/verify_cpf.cc | 7 +- src/operators/verify_cpf.h | 9 +- src/operators/verify_ssn.cc | 6 +- src/operators/verify_ssn.h | 7 +- src/operators/within.h | 6 +- src/parser/seclang-parser.yy | 215 ++++++++++++++- src/parser/seclang-scanner.ll | 261 +++++++++++++----- test/test-cases/regression/action-skip.json | 2 +- .../test-cases/regression/config-include.json | 12 +- .../regression/config-secremoterules.json | 4 +- test/test-cases/regression/misc.json | 2 +- test/test-cases/regression/operator-rx.json | 2 +- 49 files changed, 550 insertions(+), 240 deletions(-) diff --git a/src/collection/backend/lmdb.cc b/src/collection/backend/lmdb.cc index f798375f..4f991fad 100644 --- a/src/collection/backend/lmdb.cc +++ b/src/collection/backend/lmdb.cc @@ -188,7 +188,7 @@ std::string* LMDB::resolveFirst(const std::string& var) { goto end_get; } - //FIXME: Memory leak here. + // FIXME: Memory leak here. ret = new std::string( reinterpret_cast(mdb_value_ret.mv_data), mdb_value_ret.mv_size); diff --git a/src/operators/begins_with.h b/src/operators/begins_with.h index 30d3884e..7b696762 100644 --- a/src/operators/begins_with.h +++ b/src/operators/begins_with.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,13 +29,14 @@ class BeginsWith : public Operator { /** @ingroup ModSecurity_Operator */ BeginsWith(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + explicit BeginsWith(std::string param) + : Operator("BeginsWith", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_BEGINS_WITH_H_ diff --git a/src/operators/contains.h b/src/operators/contains.h index b19d6a32..9138bfee 100644 --- a/src/operators/contains.h +++ b/src/operators/contains.h @@ -22,7 +22,7 @@ #include "modsecurity/transaction.h" #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -31,13 +31,13 @@ class Contains : public Operator { /** @ingroup ModSecurity_Operator */ Contains(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit Contains(std::string param) + : Operator("Contains", param) { } bool evaluate(Transaction *transaction, const std::string &exp) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_CONTAINS_H_ diff --git a/src/operators/contains_word.h b/src/operators/contains_word.h index bb9fa51b..1d8c5d42 100644 --- a/src/operators/contains_word.h +++ b/src/operators/contains_word.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,7 +29,8 @@ class ContainsWord : public Operator { /** @ingroup ModSecurity_Operator */ ContainsWord(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit ContainsWord(std::string param) + : Operator("ContainsWord", param) { } bool evaluate(Transaction *transaction, const std::string &str); bool acceptableChar(const std::string& a, size_t pos); @@ -38,7 +39,5 @@ class ContainsWord : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_CONTAINS_WORD_H_ diff --git a/src/operators/ends_with.h b/src/operators/ends_with.h index 68bb38a8..dc858709 100644 --- a/src/operators/ends_with.h +++ b/src/operators/ends_with.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,14 +29,14 @@ class EndsWith : public Operator { /** @ingroup ModSecurity_Operator */ EndsWith(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit EndsWith(std::string param) + : Operator("EndsWith", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_ENDS_WITH_H_ diff --git a/src/operators/eq.h b/src/operators/eq.h index edfe3de1..034b5c64 100644 --- a/src/operators/eq.h +++ b/src/operators/eq.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,13 +29,13 @@ class Eq : public Operator { /** @ingroup ModSecurity_Operator */ Eq(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit Eq(std::string param) + : Operator("Eq", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_EQ_H_ diff --git a/src/operators/fuzzy_hash.cc b/src/operators/fuzzy_hash.cc index 4b28680f..e6c9c1d2 100644 --- a/src/operators/fuzzy_hash.cc +++ b/src/operators/fuzzy_hash.cc @@ -31,12 +31,5 @@ bool FuzzyHash::evaluate(Transaction *transaction, const std::string &str) { return true; } -FuzzyHash::FuzzyHash(std::string op, std::string param, - bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/fuzzy_hash.h b/src/operators/fuzzy_hash.h index c83e43cb..61f91181 100644 --- a/src/operators/fuzzy_hash.h +++ b/src/operators/fuzzy_hash.h @@ -20,21 +20,22 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { class FuzzyHash : public Operator { public: /** @ingroup ModSecurity_Operator */ - FuzzyHash(std::string o, std::string p, bool i); + FuzzyHash(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit FuzzyHash(std::string param) + : Operator("FuzzyHash", param) { } bool evaluate(Transaction *transaction, const std::string &std) override; }; } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_FUZZY_HASH_H_ diff --git a/src/operators/ge.h b/src/operators/ge.h index db907b29..b49c799a 100644 --- a/src/operators/ge.h +++ b/src/operators/ge.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,13 +29,13 @@ class Ge : public Operator { /** @ingroup ModSecurity_Operator */ Ge(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit Ge(std::string param) + : Operator("Ge", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_GE_H_ diff --git a/src/operators/geo_lookup.h b/src/operators/geo_lookup.h index fa1d70c7..a382396b 100644 --- a/src/operators/geo_lookup.h +++ b/src/operators/geo_lookup.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,14 +29,15 @@ class GeoLookup : public Operator { /** @ingroup ModSecurity_Operator */ GeoLookup(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - GeoLookup(std::string param) + explicit GeoLookup(std::string param) : Operator("GeoLookup", param) { } + GeoLookup() + : Operator("GeoLookup") { } bool evaluate(Transaction *transaction, const std::string &exp) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_GEO_LOOKUP_H_ diff --git a/src/operators/gsblookup.cc b/src/operators/gsblookup.cc index 5172b2b9..530752f7 100644 --- a/src/operators/gsblookup.cc +++ b/src/operators/gsblookup.cc @@ -22,6 +22,7 @@ namespace modsecurity { namespace operators { + bool GsbLookup::evaluate(Transaction *transaction, const std::string &str) { /** * @todo Implement the operator GeoLookup. @@ -31,12 +32,5 @@ bool GsbLookup::evaluate(Transaction *transaction, const std::string &str) { } -GsbLookup::GsbLookup(std::string op, std::string param, - bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/gsblookup.h b/src/operators/gsblookup.h index 02255adf..0a49c328 100644 --- a/src/operators/gsblookup.h +++ b/src/operators/gsblookup.h @@ -20,21 +20,22 @@ #include "src/operators/operator.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { class GsbLookup : public Operator { public: /** @ingroup ModSecurity_Operator */ - GsbLookup(std::string o, std::string p, bool i); + GsbLookup(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit GsbLookup(std::string param) + : Operator("GsbLookup", param) { } + bool evaluate(Transaction *transaction, const std::string &str); }; } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_GSBLOOKUP_H_ diff --git a/src/operators/gt.h b/src/operators/gt.h index 1bde4f1c..e04227f8 100644 --- a/src/operators/gt.h +++ b/src/operators/gt.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,12 +29,13 @@ class Gt : public Operator { /** @ingroup ModSecurity_Operator */ Gt(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - - bool evaluate(Transaction *transaction, const std::string &input) override; + explicit Gt(std::string param) + : Operator("Gt", param) { } + bool evaluate(Transaction *transaction, const std::string &input) override; }; } // namespace operators } // namespace modsecurity -#endif + #endif // SRC_OPERATORS_GT_H_ diff --git a/src/operators/inspect_file.cc b/src/operators/inspect_file.cc index 2551985a..5f12f48f 100644 --- a/src/operators/inspect_file.cc +++ b/src/operators/inspect_file.cc @@ -31,12 +31,5 @@ bool InspectFile::evaluate(Transaction *transaction, const std::string &str) { } -InspectFile::InspectFile(std::string op, std::string param, - bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/inspect_file.h b/src/operators/inspect_file.h index 4a761ae8..66f3430e 100644 --- a/src/operators/inspect_file.h +++ b/src/operators/inspect_file.h @@ -20,20 +20,23 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { class InspectFile : public Operator { public: /** @ingroup ModSecurity_Operator */ - InspectFile(std::string o, std::string p, bool i); + InspectFile(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit InspectFile(std::string param) + : Operator("InspectFile", param) { } + bool evaluate(Transaction *transaction, const std::string &str) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_INSPECT_FILE_H_ diff --git a/src/operators/ip_match.h b/src/operators/ip_match.h index ecb6720e..1736942c 100644 --- a/src/operators/ip_match.h +++ b/src/operators/ip_match.h @@ -21,7 +21,6 @@ #include "src/operators/operator.h" #include "src/utils/ip_tree.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { @@ -30,7 +29,10 @@ class IpMatch : public Operator { /** @ingroup ModSecurity_Operator */ IpMatch(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + IpMatch(std::string op, std::string param) + : Operator(op, param) { } + explicit IpMatch(std::string param) + : Operator("IpMatch", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; bool init(const std::string &file, std::string *error) override; @@ -41,7 +43,6 @@ class IpMatch : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_IP_MATCH_H_ diff --git a/src/operators/ip_match_f.h b/src/operators/ip_match_f.h index 043d1bb7..a250a93c 100644 --- a/src/operators/ip_match_f.h +++ b/src/operators/ip_match_f.h @@ -20,7 +20,7 @@ #include "src/operators/ip_match_from_file.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -28,11 +28,12 @@ class IpMatchF : public IpMatchFromFile { public: IpMatchF(std::string op, std::string param, bool negation) : IpMatchFromFile(op, param, negation) { } + explicit IpMatchF(std::string param) + : IpMatchFromFile("IpMatchFromFile", param) { } }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_IP_MATCH_F_H_ diff --git a/src/operators/ip_match_from_file.h b/src/operators/ip_match_from_file.h index a0a03a14..59b9694e 100644 --- a/src/operators/ip_match_from_file.h +++ b/src/operators/ip_match_from_file.h @@ -19,7 +19,6 @@ #include "src/operators/ip_match.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { @@ -28,13 +27,14 @@ class IpMatchFromFile : public IpMatch { /** @ingroup ModSecurity_Operator */ IpMatchFromFile(std::string op, std::string param, bool negation) : IpMatch(op, param, negation) { } + IpMatchFromFile(std::string op, std::string param) + : IpMatch(op, param) { } bool init(const std::string& file, std::string *error) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_IP_MATCH_FROM_FILE_H_ diff --git a/src/operators/le.h b/src/operators/le.h index 5029f486..fbb50823 100644 --- a/src/operators/le.h +++ b/src/operators/le.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,6 +29,8 @@ class Le : public Operator { /** @ingroup ModSecurity_Operator */ Le(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + explicit Le(std::string param) + : Operator("Le", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; }; @@ -37,7 +39,5 @@ class Le : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_LE_H_ diff --git a/src/operators/lt.h b/src/operators/lt.h index c411f975..fc6eb9cf 100644 --- a/src/operators/lt.h +++ b/src/operators/lt.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,6 +29,8 @@ class Lt : public Operator { /** @ingroup ModSecurity_Operator */ Lt(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + explicit Lt(std::string param) + : Operator("Lt", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; }; @@ -36,7 +38,5 @@ class Lt : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_LT_H_ diff --git a/src/operators/operator.h b/src/operators/operator.h index 74945c6c..d9140f72 100644 --- a/src/operators/operator.h +++ b/src/operators/operator.h @@ -13,9 +13,7 @@ * */ -#ifdef __cplusplus #include -#endif #ifndef SRC_OPERATORS_OPERATOR_H__ #define SRC_OPERATORS_OPERATOR_H__ @@ -23,7 +21,7 @@ #include "modsecurity/transaction.h" #include "modsecurity/rule.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -48,7 +46,7 @@ class Operator { m_op(opName), m_param(param) { } - Operator(std::string opName) + explicit Operator(std::string opName) : m_match_message(""), m_negation(false), m_op(opName), @@ -82,7 +80,6 @@ class Operator { } // namespace operators } // namespace modsecurity -#endif + #endif // SRC_OPERATORS_OPERATOR_H__ - diff --git a/src/operators/pm.h b/src/operators/pm.h index d81ac5d5..d4720f97 100644 --- a/src/operators/pm.h +++ b/src/operators/pm.h @@ -22,7 +22,7 @@ #include "src/operators/operator.h" #include "src/utils/acmp.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -34,6 +34,14 @@ class Pm : public Operator { : Operator(op, param, negation) { m_p = acmp_create(0); } + Pm(std::string op, std::string param) + : Operator(op, param) { + m_p = acmp_create(0); + } + explicit Pm(std::string param) + : Operator("Pm", param) { + m_p = acmp_create(0); + } ~Pm(); bool evaluate(Transaction *transaction, Rule *rule, const std::string &input) override; @@ -53,7 +61,6 @@ class Pm : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_PM_H_ diff --git a/src/operators/pm_f.h b/src/operators/pm_f.h index f21ca0f7..17dc5c23 100644 --- a/src/operators/pm_f.h +++ b/src/operators/pm_f.h @@ -20,7 +20,7 @@ #include "src/operators/pm_from_file.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -35,7 +35,6 @@ class PmF : public PmFromFile { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_PM_F_H_ diff --git a/src/operators/pm_from_file.h b/src/operators/pm_from_file.h index fd9b1cc6..89643172 100644 --- a/src/operators/pm_from_file.h +++ b/src/operators/pm_from_file.h @@ -20,7 +20,7 @@ #include "src/operators/pm.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -30,7 +30,8 @@ class PmFromFile : public Pm { /** @ingroup ModSecurity_Operator */ PmFromFile(std::string op, std::string param, bool negation) : Pm(op, param, negation) { } - + explicit PmFromFile(std::string param) + : Pm("PmFromFile", param) { } bool init(const std::string &file, std::string *error) override; }; @@ -38,7 +39,5 @@ class PmFromFile : public Pm { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_PM_FROM_FILE_H_ diff --git a/src/operators/rbl.h b/src/operators/rbl.h index 9e815562..89eacae0 100644 --- a/src/operators/rbl.h +++ b/src/operators/rbl.h @@ -26,7 +26,6 @@ #include "src/operators/operator.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { @@ -74,7 +73,20 @@ class Rbl : public Operator { m_provider = RblProvider::httpbl; } } - + explicit Rbl(std::string param) + : Operator("Rbl", param), + m_service(param), + m_demandsPassword(false) { + m_provider = RblProvider::UnknownProvider; + if (m_service == "httpbl.org") { + m_demandsPassword = true; + m_provider = RblProvider::httpbl; + } else if (m_service == "uribl.com") { + m_provider = RblProvider::httpbl; + } else if (m_service == "spamhaus.org") { + m_provider = RblProvider::httpbl; + } + } bool evaluate(Transaction *transaction, const std::string &str) override; std::string mapIpToAddress(std::string ipStr, Transaction *trans); @@ -95,7 +107,6 @@ class Rbl : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_RBL_H_ diff --git a/src/operators/rsub.cc b/src/operators/rsub.cc index 14baa0d9..f9a7c9a9 100644 --- a/src/operators/rsub.cc +++ b/src/operators/rsub.cc @@ -22,6 +22,7 @@ namespace modsecurity { namespace operators { + bool Rsub::evaluate(Transaction *transaction, const std::string &str) { /** * @todo Implement the operator Rsub. @@ -31,11 +32,5 @@ bool Rsub::evaluate(Transaction *transaction, const std::string &str) { } -Rsub::Rsub(std::string op, std::string param, bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/rsub.h b/src/operators/rsub.h index 16852b58..9fc678b4 100644 --- a/src/operators/rsub.h +++ b/src/operators/rsub.h @@ -20,19 +20,24 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { + class Rsub : public Operator { public: /** @ingroup ModSecurity_Operator */ - Rsub(std::string o, std::string p, bool i); + Rsub(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit Rsub(std::string param) + : Operator("Rsub", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; + + } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_RSUB_H_ diff --git a/src/operators/rx.h b/src/operators/rx.h index 2da5fe67..75cd57dd 100644 --- a/src/operators/rx.h +++ b/src/operators/rx.h @@ -22,7 +22,7 @@ #include "src/operators/operator.h" #include "src/utils/regex.h" -#ifdef __cplusplus + namespace modsecurity { using Utils::SMatch; using Utils::regex_search; @@ -42,6 +42,10 @@ class Rx : public Operator { : Operator(name, param) { m_re = new Regex(param); } + explicit Rx(std::string param) + : Operator("Rx", param) { + m_re = new Regex(param); + } ~Rx() { delete m_re; @@ -61,7 +65,5 @@ class Rx : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_RX_H_ diff --git a/src/operators/str_eq.h b/src/operators/str_eq.h index b9fba758..cfff57ae 100644 --- a/src/operators/str_eq.h +++ b/src/operators/str_eq.h @@ -23,7 +23,6 @@ #define SRC_OPERATORS_STR_EQ_H_ -#ifdef __cplusplus namespace modsecurity { namespace operators { @@ -32,6 +31,8 @@ class StrEq : public Operator { /** @ingroup ModSecurity_Operator */ StrEq(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + explicit StrEq(std::string param) + : Operator("StrEq", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; @@ -39,7 +40,5 @@ class StrEq : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_STR_EQ_H_ diff --git a/src/operators/str_match.h b/src/operators/str_match.h index 02bdbd36..2e744fec 100644 --- a/src/operators/str_match.h +++ b/src/operators/str_match.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,13 +29,14 @@ class StrMatch : public Operator { /** @ingroup ModSecurity_Operator */ StrMatch(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } + explicit StrMatch(std::string param) + : Operator("StrMatch", param) { } bool evaluate(Transaction *transaction, const std::string &input) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_STR_MATCH_H_ diff --git a/src/operators/validate_byte_range.h b/src/operators/validate_byte_range.h index e1baed46..cab7a3ae 100644 --- a/src/operators/validate_byte_range.h +++ b/src/operators/validate_byte_range.h @@ -22,7 +22,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -33,7 +33,10 @@ class ValidateByteRange : public Operator { : Operator(op, param, negation) { std::memset(table, '\0', sizeof(char) * 32); } - + explicit ValidateByteRange(std::string param) + : Operator("ValidadeByteRange", param) { + std::memset(table, '\0', sizeof(char) * 32); + } ~ValidateByteRange() override { } bool evaluate(Transaction *transaction, const std::string &input) override; @@ -47,7 +50,5 @@ class ValidateByteRange : public Operator { } // namespace operators } // namespace modsecurity -#endif - #endif // SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_ diff --git a/src/operators/validate_dtd.h b/src/operators/validate_dtd.h index 1a57abd5..371ac4d5 100644 --- a/src/operators/validate_dtd.h +++ b/src/operators/validate_dtd.h @@ -26,7 +26,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -36,6 +36,8 @@ class ValidateDTD : public Operator { ValidateDTD(std::string o, std::string p, bool i) : Operator(o, p, i), m_dtd(NULL) { } + explicit ValidateDTD(std::string param) + : Operator("ValidateDTD", param) { } ~ValidateDTD() { if (m_dtd != NULL) { xmlFreeDtd(m_dtd); @@ -91,7 +93,6 @@ class ValidateDTD : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VALIDATE_DTD_H_ diff --git a/src/operators/validate_hash.cc b/src/operators/validate_hash.cc index 68f2b6c0..3f5e9341 100644 --- a/src/operators/validate_hash.cc +++ b/src/operators/validate_hash.cc @@ -31,11 +31,5 @@ bool ValidateHash::evaluate(Transaction *transaction, const std::string &str) { } -ValidateHash::ValidateHash(std::string op, std::string param, bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/validate_hash.h b/src/operators/validate_hash.h index 4b62948c..b3da0ea0 100644 --- a/src/operators/validate_hash.h +++ b/src/operators/validate_hash.h @@ -20,20 +20,22 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { class ValidateHash : public Operator { public: /** @ingroup ModSecurity_Operator */ - ValidateHash(std::string o, std::string p, bool i); + ValidateHash(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit ValidateHash(std::string param) + : Operator("ValidateHash", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VALIDATE_HASH_H_ diff --git a/src/operators/validate_schema.h b/src/operators/validate_schema.h index c3bf5af4..7548b624 100644 --- a/src/operators/validate_schema.h +++ b/src/operators/validate_schema.h @@ -26,7 +26,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -38,6 +38,11 @@ class ValidateSchema : public Operator { m_parserCtx(NULL), m_validCtx(NULL), m_schema(NULL) { } + explicit ValidateSchema(std::string param) + : Operator("ValidateSchema", param), + m_parserCtx(NULL), + m_validCtx(NULL), + m_schema(NULL) { } ~ValidateSchema() { /* if (m_schema != NULL) { @@ -131,7 +136,6 @@ class ValidateSchema : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VALIDATE_SCHEMA_H_ diff --git a/src/operators/validate_url_encoding.h b/src/operators/validate_url_encoding.h index dbf37f7e..4b3e148f 100644 --- a/src/operators/validate_url_encoding.h +++ b/src/operators/validate_url_encoding.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -38,7 +38,6 @@ class ValidateUrlEncoding : public Operator { } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VALIDATE_URL_ENCODING_H_ diff --git a/src/operators/verify_cc.h b/src/operators/verify_cc.h index 267e3874..97de9716 100644 --- a/src/operators/verify_cc.h +++ b/src/operators/verify_cc.h @@ -31,6 +31,10 @@ class VerifyCC : public Operator { : Operator(op, param, negation), m_pc(NULL), m_pce(NULL) { } + explicit VerifyCC(std::string param) + : Operator("VerifyCC", param), + m_pc(NULL), + m_pce(NULL) { } ~VerifyCC(); int luhnVerify(const char *ccnumber, int len); diff --git a/src/operators/verify_cpf.cc b/src/operators/verify_cpf.cc index e779f445..4e7a0c5a 100644 --- a/src/operators/verify_cpf.cc +++ b/src/operators/verify_cpf.cc @@ -22,6 +22,7 @@ namespace modsecurity { namespace operators { + bool VerifyCPF::evaluate(Transaction *transaction, const std::string &str) { /** * @todo Implement the operator VerifyCPF. @@ -31,11 +32,5 @@ bool VerifyCPF::evaluate(Transaction *transaction, const std::string &str) { } -VerifyCPF::VerifyCPF(std::string op, std::string param, bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} - } // namespace operators } // namespace modsecurity diff --git a/src/operators/verify_cpf.h b/src/operators/verify_cpf.h index 5380d59f..90cf8a45 100644 --- a/src/operators/verify_cpf.h +++ b/src/operators/verify_cpf.h @@ -20,21 +20,24 @@ #include "src/operators/operator.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { + class VerifyCPF : public Operator { public: /** @ingroup ModSecurity_Operator */ - VerifyCPF(std::string o, std::string p, bool i); + VerifyCPF(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit VerifyCPF(std::string param) + : Operator("VerifyCPF", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; + } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VERIFY_CPF_H_ diff --git a/src/operators/verify_ssn.cc b/src/operators/verify_ssn.cc index 9ffec72a..22f92d11 100644 --- a/src/operators/verify_ssn.cc +++ b/src/operators/verify_ssn.cc @@ -22,6 +22,7 @@ namespace modsecurity { namespace operators { + bool VerifySSN::evaluate(Transaction *transaction, const std::string &str) { /** * @todo Implement the operator VerifySSN. @@ -30,11 +31,6 @@ bool VerifySSN::evaluate(Transaction *transaction, const std::string &str) { return true; } -VerifySSN::VerifySSN(std::string op, std::string param, bool negation) - : Operator() { - this->m_op = op; - this->m_param = param; -} } // namespace operators } // namespace modsecurity diff --git a/src/operators/verify_ssn.h b/src/operators/verify_ssn.h index a1748492..c8f5b510 100644 --- a/src/operators/verify_ssn.h +++ b/src/operators/verify_ssn.h @@ -20,7 +20,6 @@ #include "src/operators/operator.h" -#ifdef __cplusplus namespace modsecurity { namespace operators { @@ -28,13 +27,15 @@ namespace operators { class VerifySSN : public Operator { public: /** @ingroup ModSecurity_Operator */ - VerifySSN(std::string o, std::string p, bool i); + VerifySSN(std::string o, std::string p, bool n) + : Operator(o, p, n) { } + explicit VerifySSN(std::string param) + : Operator("VerifySSN", param) { } bool evaluate(Transaction *transaction, const std::string &str) override; }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_VERIFY_SSN_H_ diff --git a/src/operators/within.h b/src/operators/within.h index 39f61bf0..d67e9076 100644 --- a/src/operators/within.h +++ b/src/operators/within.h @@ -20,7 +20,7 @@ #include "src/operators/operator.h" -#ifdef __cplusplus + namespace modsecurity { namespace operators { @@ -29,13 +29,13 @@ class Within : public Operator { /** @ingroup ModSecurity_Operator */ Within(std::string op, std::string param, bool negation) : Operator(op, param, negation) { } - + explicit Within(std::string param) + : Operator("Within", param) { } bool evaluate(Transaction *transaction, const std::string &str); }; } // namespace operators } // namespace modsecurity -#endif #endif // SRC_OPERATORS_WITHIN_H_ diff --git a/src/parser/seclang-parser.yy b/src/parser/seclang-parser.yy index 495816a8..5836446c 100644 --- a/src/parser/seclang-parser.yy +++ b/src/parser/seclang-parser.yy @@ -214,6 +214,12 @@ using modsecurity::operators::Operator; driver.error(b, "Action: " + std::string(a) + " is not yet supported."); \ YYERROR; + +#define OPERATOR_NOT_SUPPORTED(a, b) \ + driver.error(b, "Operator: " + std::string(a) + " is not yet supported."); \ + YYERROR; + + #define ACTION_INIT(a, b) \ std::string error; \ if (a->init(&error) == false) { \ @@ -256,6 +262,7 @@ using modsecurity::operators::Operator; END 0 "end of file" COMMA "," PIPE + NEW_LINE ; %token ACTION_ACCURACY @@ -408,7 +415,41 @@ using modsecurity::operators::Operator; %token OPERATOR_DETECT_XSS %token OPERATOR_VALIDATE_URL_ENCODING %token OPERATOR_VALIDATE_UTF8_ENCODING -%token OPERATOR_GEOIP +%token OPERATOR_GEOLOOKUP +%token OPERATOR_INSPECT_FILE +%token OPERATOR_FUZZY_HASH +%token OPERATOR_VALIDATE_BYTE_RANGE +%token OPERATOR_VALIDATE_DTD +%token OPERATOR_VALIDATE_HASH +%token OPERATOR_VALIDATE_SCHEMA +%token OPERATOR_VERIFY_CC +%token OPERATOR_VERIFY_CPF +%token OPERATOR_VERIFY_SSN +%token OPERATOR_GSB_LOOKUP +%token OPERATOR_RSUB +%token OPERATOR_RX_CONTENT_ONLY +%token NOT + + +%token OPERATOR_WITHIN +%token OPERATOR_CONTAINS_WORD +%token OPERATOR_CONTAINS +%token OPERATOR_ENDS_WITH +%token OPERATOR_EQ +%token OPERATOR_GE +%token OPERATOR_GT +%token OPERATOR_IP_MATCH_FROM_FILE +%token OPERATOR_IP_MATCH +%token OPERATOR_LE +%token OPERATOR_LT +%token OPERATOR_PM_FROM_FILE +%token OPERATOR_PM +%token OPERATOR_RBL +%token OPERATOR_RX +%token OPERATOR_STR_EQ +%token OPERATOR_STR_MATCH +%token OPERATOR_BEGINS_WITH + %token QUOTATION_MARK %token RUN_TIME_VAR_BLD %token RUN_TIME_VAR_DUR @@ -431,6 +472,8 @@ using modsecurity::operators::Operator; %token VARIABLE_STATUS %token VARIABLE_TX +%token OP_QUOTE + %type act %type *> actings %type *> actions @@ -605,14 +648,40 @@ op: YYERROR; } } + | NOT op_before_init + { + $$ = $2; + $$->m_negation = true; + std::string error; + if ($$->init(driver.ref.back(), &error) == false) { + driver.error(@0, error); + YYERROR; + } + } + | OPERATOR_RX_CONTENT_ONLY + { + $$ = new operators::Rx(utils::string::removeBracketsIfNeeded($1)); + std::string error; + if ($$->init(driver.ref.back(), &error) == false) { + $$->m_negation = true; + driver.error(@0, error); + YYERROR; + } + } + | NOT OPERATOR_RX_CONTENT_ONLY + { + $$ = new operators::Rx("!" + utils::string::removeBracketsIfNeeded($2)); + std::string error; + if ($$->init(driver.ref.back(), &error) == false) { + $$->m_negation = true; + driver.error(@0, error); + YYERROR; + } + } ; op_before_init: - OPERATOR - { - $$ = Operator::instantiate($1); - } - | OPERATOR_UNCONDITIONAL_MATCH + OPERATOR_UNCONDITIONAL_MATCH { $$ = new operators::UnconditionalMatch(); } @@ -632,10 +701,133 @@ op_before_init: { $$ = new operators::ValidateUtf8Encoding(); } - | OPERATOR_GEOIP + | OPERATOR_INSPECT_FILE FREE_TEXT + { + /* $$ = new operators::InspectFile($1); */ + OPERATOR_NOT_SUPPORTED("InspectFile", @0); + } + | OPERATOR_FUZZY_HASH FREE_TEXT + { + /* $$ = new operators::FuzzyHash(); */ + OPERATOR_NOT_SUPPORTED("FuzzyHash", @0); + } + | OPERATOR_VALIDATE_BYTE_RANGE FREE_TEXT + { + $$ = new operators::ValidateByteRange($2); + } + | OPERATOR_VALIDATE_DTD FREE_TEXT + { + $$ = new operators::ValidateDTD($2); + } + | OPERATOR_VALIDATE_HASH FREE_TEXT + { + /* $$ = new operators::ValidateHash($1); */ + OPERATOR_NOT_SUPPORTED("ValidateHash", @0); + } + | OPERATOR_VALIDATE_SCHEMA FREE_TEXT + { + $$ = new operators::ValidateSchema($2); + } + | OPERATOR_VERIFY_CC FREE_TEXT + { + $$ = new operators::VerifyCC($2); + } + | OPERATOR_VERIFY_CPF FREE_TEXT + { + /* $$ = new operators::VerifyCPF($1); */ + OPERATOR_NOT_SUPPORTED("VerifyCPF", @0); + } + | OPERATOR_VERIFY_SSN FREE_TEXT + { + /* $$ = new operators::VerifySSN($1); */ + OPERATOR_NOT_SUPPORTED("VerifySSN", @0); + } + | OPERATOR_GSB_LOOKUP FREE_TEXT + { + /* $$ = new operators::GsbLookup($1); */ + OPERATOR_NOT_SUPPORTED("GsbLookup", @0); + } + | OPERATOR_RSUB FREE_TEXT + { + /* $$ = new operators::Rsub($1); */ + OPERATOR_NOT_SUPPORTED("Rsub", @0); + } + | OPERATOR_WITHIN FREE_TEXT + { + $$ = new operators::Within($2); + } + | OPERATOR_CONTAINS_WORD FREE_TEXT + { + $$ = new operators::ContainsWord($2); + } + | OPERATOR_CONTAINS FREE_TEXT + { + $$ = new operators::Contains($2); + } + | OPERATOR_ENDS_WITH FREE_TEXT + { + $$ = new operators::EndsWith($2); + } + | OPERATOR_EQ FREE_TEXT + { + $$ = new operators::Eq($2); + } + | OPERATOR_GE FREE_TEXT + { + $$ = new operators::Ge($2); + } + | OPERATOR_GT FREE_TEXT + { + $$ = new operators::Gt($2); + } + | OPERATOR_IP_MATCH_FROM_FILE FREE_TEXT + { + $$ = new operators::IpMatchF($2); + } + | OPERATOR_IP_MATCH FREE_TEXT + { + $$ = new operators::IpMatch($2); + } + | OPERATOR_LE FREE_TEXT + { + $$ = new operators::Le($2); + } + | OPERATOR_LT FREE_TEXT + { + $$ = new operators::Lt($2); + } + | OPERATOR_PM_FROM_FILE FREE_TEXT + { + $$ = new operators::PmFromFile($2); + } + | OPERATOR_PM FREE_TEXT + { + $$ = new operators::Pm($2); + } + | OPERATOR_RBL FREE_TEXT + { + $$ = new operators::Rbl($2); + } + | OPERATOR_RX FREE_TEXT + { + $$ = new operators::Rx($2); + } + | OPERATOR_STR_EQ FREE_TEXT + { + $$ = new operators::StrEq($2); + } + | OPERATOR_STR_MATCH FREE_TEXT + { + $$ = new operators::StrMatch($2); + } + | OPERATOR_BEGINS_WITH FREE_TEXT + { + $$ = new operators::BeginsWith($2); + } + | OPERATOR_GEOLOOKUP { #ifdef WITH_GEOIP - $$ = $$ = new operators::GeoLookup($1); + $$ = new operators::GeoLookup(); #else std::stringstream ss; ss << "This version of ModSecurity was not compiled with GeoIP support."; @@ -643,13 +835,6 @@ op_before_init: YYERROR; #endif // WITH_GEOIP } - | FREE_TEXT - { - std::string text = std::string($1); - text.pop_back(); - text.erase(0, 1); - $$ = new operators::Rx("rx", text); - } ; expression: diff --git a/src/parser/seclang-scanner.ll b/src/parser/seclang-scanner.ll index c6bb0131..a1e699e8 100755 --- a/src/parser/seclang-scanner.ll +++ b/src/parser/seclang-scanner.ll @@ -81,7 +81,6 @@ ACTION_STATUS (?i:status:[0-9]+) ACTION_TAG (?i:tag) ACTION_VER (?i:ver) ACTION_XMLNS (?i:xmlns) - ACTION_TRANSFORMATION_CMD_LINE (?i:t:cmdLine) ACTION_TRANSFORMATION_COMPRESS_WHITESPACE (?i:t:compressWhitespace) ACTION_TRANSFORMATION_CSS_DECODE (?i:t:cssDecode) @@ -175,7 +174,6 @@ CONGIG_DIR_SEC_TMP_DIR (?i:SecTmpDir) DICT_ELEMENT [^ \t|]+ DIRECTIVE (?i:SecRule) DIRECTIVE_SECRULESCRIPT (?i:SecRuleScript) -FREE_TEXT ([^\"]|([^\\]\\\"))+ FREE_TEXT_NEW_LINE [^\"|\n]+ FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+ FREE_TEXT_QUOTE_COMMA [^,\']+ @@ -183,14 +181,51 @@ FREE_TEXT_SPACE [^ \t]+ FREE_TEXT_SPACE_COMMA [^, \t]+ FREE_TEXT_SPACE_COMMA_QUOTE [^, \t\"\n\r]+ NEW_LINE_FREE_TEXT [^, \t\"\n\r]+ + OPERATOR_UNCONDITIONAL_MATCH (?i:@unconditionalMatch) OPERATOR_DETECT_SQLI (?i:@detectSQLi) OPERATOR_DETECT_XSS (?i:@detectXSS) OPERATOR_VALIDATE_URL_ENCODING (?i:@validateUrlEncoding) OPERATOR_VALIDATE_UTF8_ENCODING (?i:@validateUtf8Encoding) +OPERATOR_INSPECT_FILE (?i:@inspectFile) +OPERATOR_FUZZY_HASH (?i:@fuzzyHash) +OPERATOR_VALIDATE_BYTE_RANGE (?i:@validateByteRange) +OPERATOR_VALIDATE_DTD (?i:@validateDTD) +OPERATOR_VALIDATE_HASH (?i:@validateHash) +OPERATOR_VALIDATE_SCHEMA (?i:@validateSchema) +OPERATOR_VERIFY_CC (?i:@verifyCC) +OPERATOR_VERIFY_CPF (?i:@verifyCPF) +OPERATOR_VERIFY_SSN (?i:@verifySSN) +OPERATOR_GSB_LOOKUP (?i:@gsbLookup) +OPERATOR_RSUB (?i:@rsub) +OPERATOR_WITHIN (?i:@within) +OPERATOR_CONTAINS_WORD (?i:@containsWord) +OPERATOR_CONTAINS (?i:@contains) +OPERATOR_ENDS_WITH (?i:@endsWith) +OPERATOR_EQ (?i:@eq) +OPERATOR_GE (?i:@ge) +OPERATOR_GT (?i:@gt) +OPERATOR_IP_MATCH_FROM_FILE (?i:(@ipMatchF|@ipMatchFromFile)) +OPERATOR_IP_MATCH (?i:@ipMatch) +OPERATOR_LE (?i:@le) +OPERATOR_LT (?i:@lt) +OPERATOR_PM_FROM_FILE (?i:(@pmf|@pmFromFile)) +OPERATOR_PM (?i:@pm) +OPERATOR_RBL (?i:@rbl) +OPERATOR_RX (?i:@rx) +OPERATOR_STR_EQ (?i:@streq) +OPERATOR_STR_MATCH (?i:@strmatch) +OPERATOR_BEGINS_WITH (?i:@beginsWith) +OPERATOR_GEOLOOKUP (?i:@geoLookup) +OPERATOR_RX_CONTENT_ONLY ([^\"]|([^\\]\\\"))+ + + +NOT ! +OP_QUOTE \" + + +FREE_TEXT ([^\"]|([^\\]\\\"))+ -OPERATOR (?i:(?:@inspectFile|@fuzzyHash|@validateByteRange|@validateDTD|@validateHash|@validateSchema|@verifyCC|@verifyCPF|@verifySSN|@gsbLookup|@rsub)|(?:\!{0,1})(?:@within|@containsWord|@contains|@endsWith|@eq|@ge|@gt|@ipMatchF|@ipMatch|@ipMatchFromFile|@le|@lt|@pmf|@pm|@pmFromFile|@rbl|@rx|@streq|@strmatch|@beginsWith)) -OPERATOR_GEOIP (?i:@geoLookup) REMOVE_RULE_BY [0-9A-Za-z_\/\.\-\*\:\;\]\[]+ RUN_TIME_VAR_BLD (?i:MODSEC_BUILD) RUN_TIME_VAR_DUR (?i:DURATION) @@ -208,7 +243,6 @@ RUN_TIME_VAR_TIME_SEC (?i:TIME_SEC) RUN_TIME_VAR_TIME_WDAY (?i:TIME_WDAY) RUN_TIME_VAR_TIME_YEAR (?i:TIME_YEAR) RUN_TIME_VAR_XML (?i:XML) -SOMETHING ["]{1}([^"]|([^\\"]\\\"))*["]{1} VARIABLENOCOLON (?i:URLENCODED_ERROR|REQBODY_PROCESSOR_ERROR_MSG|REQBODY_PROCESSOR_ERROR|REQBODY_PROCESSOR|REQBODY_ERROR_MSG|REQBODY_ERROR|MULTIPART_FILE_LIMIT_EXCEEDED|MULTIPART_INVALID_QUOTING|MULTIPART_HEADER_FOLDING|MULTIPART_INVALID_HEADER_FOLDING|MULTIPART_STRICT_ERROR|MULTIPART_UNMATCHED_BOUNDARY|REMOTE_ADDR|REQUEST_LINE) VARIABLE (?i:(SERVER_NAME|MULTIPART_DATA_AFTER|RESOURCE|ARGS_COMBINED_SIZE|ARGS_GET_NAMES|ARGS_POST_NAMES|FILES_TMPNAMES|FILES_COMBINED_SIZE|FULL_REQUEST_LENGTH|REQUEST_BODY_LENGTH|REQUEST_URI_RAW|UNIQUE_ID|SERVER_PORT|SERVER_ADDR|REMOTE_PORT|REMOTE_HOST|PATH_INFO|MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VAR|INBOUND_DATA_ERROR|OUTBOUND_DATA_ERROR|FULL_REQUEST|AUTH_TYPE|ARGS_NAMES|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_PROTOCOL|RESPONSE_STATUS|USERID|SESSIONID)) VARIABLE_COL (?i:(SESSION|GLOBAL|ARGS_POST|ARGS_GET|ARGS|FILES_SIZES|FILES_NAMES|FILES_TMP_CONTENT|MULTIPART_FILENAME|MULTIPART_NAME|MATCHED_VARS_NAMES|MATCHED_VARS|FILES|QUERY_STRING|REQUEST_COOKIES|REQUEST_HEADERS|RESPONSE_HEADERS|GEO|IP|REQUEST_COOKIES_NAMES)) @@ -219,9 +253,9 @@ VAR_FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+ VAR_FREE_TEXT_SPACE [^ \t\"]+ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ +NEW_LINE [\n\r]+ - -%x EXPECTING_OPERATOR COMMENT EXPECTING_VARIABLE +%x TRANSACTION_TO_VARIABLE EXPECTING_VARIABLE TRANSACTION_FROM_VARIABLE_TO_OPERATOR EXPECTING_OPERATOR COMMENT EXPECTING_PARAMETER EXPECTING_ACTIONS TRANSACTION_FROM_OPERATOR_TO_ACTIONS TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS NO_OP_INFORMED FINISH_ACTIONS %{ // Code run each time a pattern is matched. @@ -236,6 +270,7 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ driver.loc.back()->step(); %} +{ {ACTION_APPEND} { return p::make_ACTION_APPEND(yytext, *driver.loc.back()); } {ACTION_BLOCK} { return p::make_ACTION_BLOCK(yytext, *driver.loc.back()); } {ACTION_CAPTURE} { return p::make_ACTION_CAPTURE(yytext, *driver.loc.back()); } @@ -334,9 +369,31 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR} { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); } {ACTION_TRANSFORMATION_REMOVE_COMMENTS} { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); } {ACTION_TRANSFORMATION_REPLACE_COMMENTS} { return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); } - - {ACTION_LOG_DATA}:'{FREE_TEXT_QUOTE}' { return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); } + +{CONFIG_VALUE_DETC} { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); } +{CONFIG_VALUE_OFF} { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); } +{CONFIG_VALUE_ON} { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); } + + +[ \t]*[,][ \t]* { return p::make_COMMA(*driver.loc.back()); } +[ \t]*\\\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); } +[ \t]*\\\r\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); } + +\"[ \t]* { BEGIN(INITIAL); yyless(yyleng); } +[ \t]*\n { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); } +[ \t]*\r\n { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); } +\"[ \t]*\n { BEGIN(INITIAL); yyless(1); } +\"[ \t]*\r\n { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); } + +. { driver.error (*driver.loc.back(), "invalid character", yytext); throw p::syntax_error(*driver.loc.back(), ""); } +} + +{ +<> { BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); } +. { BEGIN(INITIAL); } +} + {CONFIG_COMPONENT_SIG}[ \t]+["]{FREE_TEXT}["] { return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); } {CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_AUDIT_DIR}[ ]{CONFIG_VALUE_PATH} { return p::make_CONFIG_DIR_AUDIT_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); } @@ -361,8 +418,6 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {CONFIG_DIR_RES_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_RES_BODY} { return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); } {CONFIG_DIR_RULE_ENG} { return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); } -{CONFIG_DIR_SEC_ACTION} { return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); } -{CONFIG_DIR_SEC_DEFAULT_ACTION} { return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); } {CONFIG_DIR_SEC_MARKER}[ \t]+["]{NEW_LINE_FREE_TEXT}["] { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_SEC_MARKER}[ \t]+{NEW_LINE_FREE_TEXT} { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_UNICODE_MAP_FILE}[ ]{FREE_TEXT_NEW_LINE} { return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); } @@ -391,7 +446,11 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ {CONGIG_DIR_SEC_STATUS_ENGINE}[ ]{FREE_TEXT_NEW_LINE} { return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); } {CONGIG_DIR_SEC_TMP_DIR}[ ]{CONFIG_VALUE_PATH} { return p::make_CONGIG_DIR_SEC_TMP_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); } {DIRECTIVE_SECRULESCRIPT}[ ]{CONFIG_VALUE_PATH} { return p::make_DIRECTIVE_SECRULESCRIPT(yytext, *driver.loc.back()); } -{DIRECTIVE} { return p::make_DIRECTIVE(yytext, *driver.loc.back()); } + +{DIRECTIVE} { BEGIN(TRANSACTION_TO_VARIABLE); return p::make_DIRECTIVE(yytext, *driver.loc.back()); } +{CONFIG_DIR_SEC_DEFAULT_ACTION} { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); } +{CONFIG_DIR_SEC_ACTION} { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); } + {CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); } {CONFIG_SEC_COLLECTION_TIMEOUT}[ ]{CONFIG_VALUE_NUMBER} { return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); } [ \t]*[\n] { driver.loc.back()->lines(1); driver.loc.back()->step(); } @@ -402,74 +461,133 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ ["] { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); } [,] { return p::make_COMMA(*driver.loc.back()); } +{ +[ \t]* { BEGIN(EXPECTING_VARIABLE); } +} - -{ -[!&]?{RUN_TIME_VAR_BLD} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_DUR} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_ENV}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_ENV}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_HSV} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_REMOTE_USER} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_REMOTE_USER(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_RULE}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_RULE}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_DAY} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_EPOCH} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_HOUR} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_MIN} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_MON} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_SEC} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME_YEAR} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_TIME} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_XML}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } -[!&]?{RUN_TIME_VAR_XML}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } -[!&]?{VARIABLENOCOLON} { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_COL}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_COL}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_STATUS} { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_STATUS(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_TX}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_TX}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } -[!&]?{VARIABLE_WEBSERVER_ERROR_LOG} { driver.error (*driver.loc.back(), "Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity", ""); throw p::syntax_error(*driver.loc.back(), "");} -[!&]?{VARIABLE}(\:[\']{FREE_TEXT_QUOTE}[\'])? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -[!&]?{VARIABLE}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_BLD}["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_DUR}["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_ENV}(\:\'{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_ENV}(\:{DICT_ELEMENT})?["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_HSV}["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_RULE}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_RULE}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_XML}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } -["][!&]?{RUN_TIME_VAR_XML}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } -["][!&]?{VARIABLENOCOLON}["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE_COL}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE_COL}(\:{DICT_ELEMENT})? { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE_TX}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE_TX}(\:{DICT_ELEMENT})?["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -["][!&]?{VARIABLE}(\:{DICT_ELEMENT})?["] { BEGIN(EXPECTING_OPERATOR); return p::make_VARIABLE(yytext, *driver.loc.back()); } -[&]?{RUN_TIME_VAR_TIME_WDAY} { BEGIN(EXPECTING_OPERATOR); return p::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); } +{ +[ \t]* { } +[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } +[ \t]*\\\n[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } +[ \t]*\\\r\n[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } } +{ +[!&]?{RUN_TIME_VAR_BLD} { return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_DUR} { return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_ENV}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_ENV}(\:{DICT_ELEMENT})? { return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_HSV} { return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_REMOTE_USER} { return p::make_RUN_TIME_VAR_REMOTE_USER(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_RULE}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_RULE}(\:{DICT_ELEMENT})? { return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_DAY} { return p::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_EPOCH} { return p::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_HOUR} { return p::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_MIN} { return p::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_MON} { return p::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_SEC} { return p::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME_YEAR} { return p::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_TIME} { return p::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_XML}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } +[!&]?{RUN_TIME_VAR_XML}(\:{DICT_ELEMENT})? { return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } +[!&]?{VARIABLENOCOLON} { return p::make_VARIABLE(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_COL}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_COL}(\:{DICT_ELEMENT})? { return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_STATUS} { return p::make_VARIABLE_STATUS(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_TX}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_TX}(\:{DICT_ELEMENT})? { return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } +[!&]?{VARIABLE_WEBSERVER_ERROR_LOG} { driver.error (*driver.loc.back(), "Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity", ""); throw p::syntax_error(*driver.loc.back(), "");} +[!&]?{VARIABLE}(\:[\']{FREE_TEXT_QUOTE}[\'])? { return p::make_VARIABLE(yytext, *driver.loc.back()); } +[!&]?{VARIABLE}(\:{DICT_ELEMENT})? { return p::make_VARIABLE(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_BLD}["] { return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_DUR}["] { return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_ENV}(\:\'{FREE_TEXT_QUOTE}[\'])?["] { return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_ENV}(\:{DICT_ELEMENT})?["] { return p::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_HSV}["] { return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_RULE}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_RULE}(\:{DICT_ELEMENT})? { return p::make_RUN_TIME_VAR_RULE(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_XML}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } +["][!&]?{RUN_TIME_VAR_XML}(\:{DICT_ELEMENT})? { return p::make_RUN_TIME_VAR_XML(yytext, *driver.loc.back()); } +["][!&]?{VARIABLENOCOLON}["] { return p::make_VARIABLE(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE_COL}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE_COL}(\:{DICT_ELEMENT})? { return p::make_VARIABLE_COL(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE_TX}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE_TX}(\:{DICT_ELEMENT})?["] { return p::make_VARIABLE_TX(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE}(\:[\']{FREE_TEXT_QUOTE}[\'])?["] { return p::make_VARIABLE(yytext, *driver.loc.back()); } +["][!&]?{VARIABLE}(\:{DICT_ELEMENT})?["] { return p::make_VARIABLE(yytext, *driver.loc.back()); } +[&]?{RUN_TIME_VAR_TIME_WDAY} { return p::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); } +} + +{ +[ \t]+["]* { BEGIN(EXPECTING_OPERATOR); } +} { -["]{OPERATOR}[ ]{FREE_TEXT}["] { BEGIN(INITIAL); return p::make_OPERATOR(yytext, *driver.loc.back()); } -["]{OPERATOR_UNCONDITIONAL_MATCH}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_UNCONDITIONAL_MATCH(yytext, *driver.loc.back()); } -["]{OPERATOR_DETECT_SQLI}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_DETECT_SQLI(yytext, *driver.loc.back()); } -["]{OPERATOR_DETECT_XSS}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_DETECT_XSS(yytext, *driver.loc.back()); } -["]{OPERATOR_VALIDATE_URL_ENCODING}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_VALIDATE_URL_ENCODING(yytext, *driver.loc.back()); } -["]{OPERATOR_VALIDATE_UTF8_ENCODING}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(yytext, *driver.loc.back()); } -["]{OPERATOR_GEOIP}[\t ]*["] { BEGIN(INITIAL); return p::make_OPERATOR_GEOIP(yytext, *driver.loc.back()); } -{SOMETHING} { BEGIN(INITIAL); return p::make_FREE_TEXT(yytext, *driver.loc.back()); } +{OPERATOR_GEOLOOKUP} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(yytext, *driver.loc.back()); } +{OPERATOR_WITHIN} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_WITHIN(yytext, *driver.loc.back()); } +{OPERATOR_CONTAINS_WORD} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_CONTAINS_WORD(yytext, *driver.loc.back()); } +{OPERATOR_CONTAINS} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_CONTAINS(yytext, *driver.loc.back()); } +{OPERATOR_ENDS_WITH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_ENDS_WITH(yytext, *driver.loc.back()); } +{OPERATOR_EQ} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_EQ(yytext, *driver.loc.back()); } +{OPERATOR_GE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_GE(yytext, *driver.loc.back()); } +{OPERATOR_GT} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_GT(yytext, *driver.loc.back()); } +{OPERATOR_IP_MATCH_FROM_FILE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_IP_MATCH_FROM_FILE(yytext, *driver.loc.back()); } +{OPERATOR_IP_MATCH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_IP_MATCH(yytext, *driver.loc.back()); } +{OPERATOR_LE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_LE(yytext, *driver.loc.back()); } +{OPERATOR_LT} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_LT(yytext, *driver.loc.back()); } +{OPERATOR_PM_FROM_FILE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_PM_FROM_FILE(yytext, *driver.loc.back()); } +{OPERATOR_PM} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_PM(yytext, *driver.loc.back()); } +{OPERATOR_RBL} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_RBL(yytext, *driver.loc.back()); } +{OPERATOR_RX} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_RX(yytext, *driver.loc.back()); } +{OPERATOR_STR_EQ} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_STR_EQ(yytext, *driver.loc.back()); } +{OPERATOR_STR_MATCH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_STR_MATCH(yytext, *driver.loc.back()); } +{OPERATOR_BEGINS_WITH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_BEGINS_WITH(yytext, *driver.loc.back()); } +{OPERATOR_INSPECT_FILE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_INSPECT_FILE(yytext, *driver.loc.back()); } +{OPERATOR_FUZZY_HASH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_FUZZY_HASH(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_BYTE_RANGE} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VALIDATE_BYTE_RANGE(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_DTD} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VALIDATE_DTD(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_HASH} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VALIDATE_HASH(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_SCHEMA} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VALIDATE_SCHEMA(yytext, *driver.loc.back()); } +{OPERATOR_VERIFY_CC} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VERIFY_CC(yytext, *driver.loc.back()); } +{OPERATOR_VERIFY_CPF} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VERIFY_CPF(yytext, *driver.loc.back()); } +{OPERATOR_VERIFY_SSN} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_VERIFY_SSN(yytext, *driver.loc.back()); } +{OPERATOR_GSB_LOOKUP} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_GSB_LOOKUP(yytext, *driver.loc.back()); } +{OPERATOR_RSUB} { BEGIN(EXPECTING_PARAMETER); return p::make_OPERATOR_RSUB(yytext, *driver.loc.back()); } +{OPERATOR_UNCONDITIONAL_MATCH} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(yytext, *driver.loc.back()); } +{OPERATOR_DETECT_SQLI} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(yytext, *driver.loc.back()); } +{OPERATOR_DETECT_XSS} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_URL_ENCODING} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(yytext, *driver.loc.back()); } +{OPERATOR_VALIDATE_UTF8_ENCODING} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(yytext, *driver.loc.back()); } + +{NOT} { BEGIN(EXPECTING_OPERATOR); return p::make_NOT(yytext, *driver.loc.back()); } +. { BEGIN(NO_OP_INFORMED); yyless(0); } + +} + +{ +{FREE_TEXT} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_RX_CONTENT_ONLY(yytext, *driver.loc.back()); } } -{ -[|] { BEGIN(EXPECTING_VARIABLE); return p::make_PIPE(*driver.loc.back()); } +{ +[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } +[ \t]*\"[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } +[ \t]*\"[ \t]*\\\n[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } +[ \t]*\"[ \t]*\\\r\n[ \t]*\"[ \t]* { BEGIN(EXPECTING_ACTIONS); } } -{ + +{ +[ ]{FREE_TEXT} { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_FREE_TEXT(yytext+1, *driver.loc.back()); } +} + +{ +[|] { return p::make_PIPE(*driver.loc.back()); } +} + +{ [ \t]+ { } [ \t]*\\\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); } [ \t]*\\\r\n[ \t]* { driver.loc.back()->lines(1); driver.loc.back()->step(); } @@ -484,8 +602,11 @@ VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+ . { driver.error (*driver.loc.back(), "invalid character", yytext); throw p::syntax_error(*driver.loc.back(), ""); } + + + <> { - if (driver.ref.size() > 0) { + if (driver.ref.size() > 1) { driver.ref.pop_back(); } diff --git a/test/test-cases/regression/action-skip.json b/test/test-cases/regression/action-skip.json index 7aaea13e..affa8af4 100644 --- a/test/test-cases/regression/action-skip.json +++ b/test/test-cases/regression/action-skip.json @@ -38,7 +38,7 @@ "version_min":300000, "title":"Testing skip action 2/3", "expected":{ - "parser_error": "Rules error. File: action-skip.json. Line: 2. Column: 61. invalid character s" + "parser_error": "Rules error. File: action-skip.json. Line: 2. Column: 62. invalid character s" }, "client":{ "ip":"200.249.12.31", diff --git a/test/test-cases/regression/config-include.json b/test/test-cases/regression/config-include.json index 1c72d9d8..26910f50 100644 --- a/test/test-cases/regression/config-include.json +++ b/test/test-cases/regression/config-include.json @@ -31,7 +31,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"config_example2\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." }, "rules":[ "SecRuleEngine On", @@ -71,7 +71,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"config_example\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"config_example\" against ARGS." }, "rules":[ "SecRuleEngine On", @@ -111,7 +111,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"config_example2\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." }, "rules":[ "SecRuleEngine On", @@ -151,7 +151,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"test\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"test\" against ARGS." }, "rules":[ "SecRuleEngine On", @@ -191,7 +191,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"config_example2\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"config_example2\" against ARGS." }, "rules":[ "SecRuleEngine On", @@ -232,7 +232,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"test\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"test\" against ARGS." }, "rules":[ "SecRuleEngine On", diff --git a/test/test-cases/regression/config-secremoterules.json b/test/test-cases/regression/config-secremoterules.json index afaaac4b..8aa1496d 100644 --- a/test/test-cases/regression/config-secremoterules.json +++ b/test/test-cases/regression/config-secremoterules.json @@ -31,7 +31,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@pmfromfile\" with param \"https://www.modsecurity.org/modsecurity-regression-test.txt\" against REQUEST_FILENAME" + "debug_log":"Executing operator \"PmFromFile\" with param \"https://www.modsecurity.org/modsecurity-regression-test.txt\" against REQUEST_FILENAME" }, "rules":[ "SecRuleEngine On", @@ -84,7 +84,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@contains\" with param \"somethingelse\" against ARGS." + "debug_log":"Executing operator \"Contains\" with param \"somethingelse\" against ARGS." }, "rules":[ "SecRuleEngine On", diff --git a/test/test-cases/regression/misc.json b/test/test-cases/regression/misc.json index dde68b9f..f0894599 100644 --- a/test/test-cases/regression/misc.json +++ b/test/test-cases/regression/misc.json @@ -6,7 +6,7 @@ "title":"Testing action :: SecRule directives should be case insensitive", "expected":{ "audit_log":"", - "debug_log":"Executing operator \"@contains\" with param \"PHPSESSID\" against REQUEST_HEADERS.", + "debug_log":"Executing operator \"Contains\" with param \"PHPSESSID\" against REQUEST_HEADERS.", "error_log":"" }, "rules":[ diff --git a/test/test-cases/regression/operator-rx.json b/test/test-cases/regression/operator-rx.json index df051fb6..455e615c 100644 --- a/test/test-cases/regression/operator-rx.json +++ b/test/test-cases/regression/operator-rx.json @@ -36,7 +36,7 @@ ] }, "expected":{ - "debug_log":"Executing operator \"@rx" + "debug_log":"Executing operator \"Rx" }, "rules":[ "SecRuleEngine On",