Fix several minor issues on the seclang grammar

This commit is contained in:
Felipe Zimmerle 2015-08-22 11:06:28 -03:00
parent e78d7f5b91
commit 1065e297b2
15 changed files with 150 additions and 70 deletions

View File

@ -69,10 +69,10 @@ class Rules : public RulesProperties {
void incrementReferenceCount(void); void incrementReferenceCount(void);
void decrementReferenceCount(void); void decrementReferenceCount(void);
bool loadFromUri(const char *uri); int loadFromUri(const char *uri);
bool loadRemote(const char *key, const char *uri); int loadRemote(const char *key, const char *uri);
bool load(const char *rules); int load(const char *rules);
bool load(const char *rules, const std::string &ref); int load(const char *rules, const std::string &ref);
void dump(); void dump();

View File

@ -56,6 +56,7 @@ ACTIONS = \
actions/block.cc \ actions/block.cc \
actions/capture.cc \ actions/capture.cc \
actions/chain.cc \ actions/chain.cc \
actions/log_data.cc \
actions/msg.cc \ actions/msg.cc \
actions/no_audit_log.cc \ actions/no_audit_log.cc \
actions/phase.cc \ actions/phase.cc \

View File

@ -76,9 +76,6 @@ Action *Action::instantiate(const std::string& name) {
if (name.compare(0, rule_id.length(), rule_id) == 0) { if (name.compare(0, rule_id.length(), rule_id) == 0) {
return new RuleId(name); return new RuleId(name);
} }
if (name.compare(0, severity.length(), severity) == 0) {
return new Severity(name);
}
if (name == "chain") { if (name == "chain") {
return new Chain(name); return new Chain(name);
} }

View File

@ -28,7 +28,6 @@ namespace actions {
Severity::Severity(std::string action) Severity::Severity(std::string action)
: Action(action, RunTimeOnlyIfMatchKind) { : Action(action, RunTimeOnlyIfMatchKind) {
std::string a = action; std::string a = action;
a.erase(0, 9);
if (tolower(a) == "emergency") { if (tolower(a) == "emergency") {
this->m_severity = 0; this->m_severity = 0;
} else if (tolower(a) == "alert") { } else if (tolower(a) == "alert") {

View File

@ -75,6 +75,7 @@ bool DebugLog::setOutputFile(const std::string& file_path) {
* *
*/ */
bool DebugLog::write_log(int debug_level, const std::string &text) { bool DebugLog::write_log(int debug_level, const std::string &text) {
std::cout << "?" << std::to_string(is_open()) << ":" << std::to_string(m_debug_level) <<" [" << debug_level << "] " << text << std::endl;
if (!is_open()) { if (!is_open()) {
return false; return false;
} }

View File

@ -59,6 +59,14 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
node = NULL; node = NULL;
} }
void Pm::replaceAll(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
size_t end_pos = start_pos + from.length();
str.replace(start_pos, end_pos, to);
start_pos += to.length();
}
}
bool Pm::evaluate(Assay *assay, const std::string &input) { bool Pm::evaluate(Assay *assay, const std::string &input) {
int rc = 0; int rc = 0;
@ -79,6 +87,8 @@ bool Pm::evaluate(Assay *assay, const std::string &input) {
bool Pm::init(const char **error) { bool Pm::init(const char **error) {
std::vector<std::string> vec; std::vector<std::string> vec;
replaceAll(param, "\\", "\\\\");
char *content = parse_pm_content(param.c_str(), param.length(), error); char *content = parse_pm_content(param.c_str(), param.length(), error);
if (content == NULL) { if (content == NULL) {
return false; return false;

View File

@ -35,7 +35,7 @@ class Pm : public Operator {
m_p = acmp_create(0); m_p = acmp_create(0);
} }
~Pm(); ~Pm();
void replaceAll(std::string& str, const std::string& from, const std::string& to);
bool evaluate(Assay *assay, const std::string &input); bool evaluate(Assay *assay, const std::string &input);
virtual bool init(const char **error); virtual bool init(const char **error);

View File

@ -24,10 +24,12 @@ namespace ModSecurity {
namespace operators { namespace operators {
bool Rx::evaluate(Assay *assay, const std::string& input) { bool Rx::evaluate(Assay *assay, const std::string& input) {
SMatch match; SMatch match;
if (regex_search(input, &match, m_re) && match.size() >= 1) { std::string i = input;
if (regex_search(i, &match, m_re) && match.size() >= 1) {
this->matched.push_back(match.match); this->matched.push_back(match.match);
return true; return true;
} }

View File

@ -25,8 +25,8 @@ namespace ModSecurity {
namespace Parser { namespace Parser {
Driver::Driver() Driver::Driver()
: trace_scanning(true), : trace_scanning(false),
trace_parsing(true) { trace_parsing(false) {
audit_log = new AuditLog(); audit_log = new AuditLog();
} }
@ -46,11 +46,13 @@ int Driver::addSecRule(Rule *rule) {
if (size == 0) { if (size == 0) {
this->rules[rule->phase].push_back(rule); this->rules[rule->phase].push_back(rule);
lastRule = rule;
return true; return true;
} }
Rule *lastRule = this->rules[rule->phase][size-1];
if (lastRule->chained && lastRule->chainedRule == NULL) { if (lastRule->chained && lastRule->chainedRule == NULL) {
rule->phase = lastRule->phase;
lastRule->chainedRule = rule; lastRule->chainedRule = rule;
return true; return true;
} }
@ -64,7 +66,7 @@ int Driver::addSecRule(Rule *rule) {
return true; return true;
} }
} }
lastRule = rule;
rules[rule->phase].push_back(rule); rules[rule->phase].push_back(rule);
return true; return true;
} }

View File

@ -79,6 +79,7 @@ class Driver : public RulesProperties {
std::list<std::string> ref; std::list<std::string> ref;
std::string buffer; std::string buffer;
Rule *lastRule;
}; };

View File

@ -18,7 +18,9 @@ class Driver;
#include "actions/action.h" #include "actions/action.h"
#include "actions/set_var.h" #include "actions/set_var.h"
#include "actions/severity.h"
#include "actions/msg.h" #include "actions/msg.h"
#include "actions/log_data.h"
#include "actions/rev.h" #include "actions/rev.h"
#include "actions/tag.h" #include "actions/tag.h"
#include "actions/transformations/transformation.h" #include "actions/transformations/transformation.h"
@ -45,9 +47,11 @@ class Driver;
using ModSecurity::actions::Action; using ModSecurity::actions::Action;
using ModSecurity::actions::SetVar; using ModSecurity::actions::SetVar;
using ModSecurity::actions::Severity;
using ModSecurity::actions::Tag; using ModSecurity::actions::Tag;
using ModSecurity::actions::Rev; using ModSecurity::actions::Rev;
using ModSecurity::actions::Msg; using ModSecurity::actions::Msg;
using ModSecurity::actions::LogData;
using ModSecurity::actions::transformations::Transformation; using ModSecurity::actions::transformations::Transformation;
using ModSecurity::operators::Operator; using ModSecurity::operators::Operator;
using ModSecurity::Rule; using ModSecurity::Rule;
@ -125,7 +129,7 @@ using ModSecurity::Variables::Variable;
PIPE PIPE
; ;
%left CONFIG_VALUE_RELEVANT_ONLY CONFIG_VALUE_ON CONFIG_VALUE_OFF %left SPACE CONFIG_VALUE_RELEVANT_ONLY CONFIG_VALUE_ON CONFIG_VALUE_OFF
%token <std::string> QUOTATION_MARK %token <std::string> QUOTATION_MARK
%token <std::string> DIRECTIVE %token <std::string> DIRECTIVE
%token <std::string> CONFIG_DIR_REQ_BODY_LIMIT %token <std::string> CONFIG_DIR_REQ_BODY_LIMIT
@ -202,9 +206,11 @@ using ModSecurity::Variables::Variable;
%token <std::string> ACTION_MSG %token <std::string> ACTION_MSG
%token <std::string> ACTION_TAG %token <std::string> ACTION_TAG
%token <std::string> ACTION_REV %token <std::string> ACTION_REV
%token <std::string> LOG_DATA
%token <std::string> TRANSFORMATION %token <std::string> TRANSFORMATION
%token <std::string> ACTION_CTL_BDY_XML %token <std::string> ACTION_CTL_BDY_XML
%token <std::string> ACTION_CTL_BDY_JSON %token <std::string> ACTION_CTL_BDY_JSON
%token <std::string> ACTION_CTL_AUDIT_LOG_PARTS
%type <std::vector<Action *> *> actions %type <std::vector<Action *> *> actions
%type <std::vector<Variable *> *> variables %type <std::vector<Variable *> *> variables
@ -223,6 +229,8 @@ input:
line: expression line: expression
| SPACE expression | SPACE expression
| SPACE expression SPACE
| expression SPACE
; ;
audit_log: audit_log:
@ -298,6 +306,7 @@ audit_log:
expression: expression:
audit_log audit_log
| DIRECTIVE SPACE variables SPACE OPERATOR SPACE QUOTATION_MARK actions SPACE QUOTATION_MARK
| DIRECTIVE SPACE variables SPACE OPERATOR SPACE QUOTATION_MARK actions QUOTATION_MARK | DIRECTIVE SPACE variables SPACE OPERATOR SPACE QUOTATION_MARK actions QUOTATION_MARK
{ {
Operator *op = Operator::instantiate($5); Operator *op = Operator::instantiate($5);
@ -313,6 +322,7 @@ expression:
); );
driver.addSecRule(rule); driver.addSecRule(rule);
} }
| DIRECTIVE SPACE variables SPACE FREE_TEXT SPACE QUOTATION_MARK actions SPACE QUOTATION_MARK
| DIRECTIVE SPACE variables SPACE FREE_TEXT SPACE QUOTATION_MARK actions QUOTATION_MARK | DIRECTIVE SPACE variables SPACE FREE_TEXT SPACE QUOTATION_MARK actions QUOTATION_MARK
{ {
Operator *op = Operator::instantiate("@pm " + $5); Operator *op = Operator::instantiate("@pm " + $5);
@ -577,14 +587,14 @@ act:
{ {
$$ = Action::instantiate($1); $$ = Action::instantiate($1);
} }
| ACTION_SEVERITY
{
$$ = Action::instantiate($1);
}
| TRANSFORMATION | TRANSFORMATION
{ {
$$ = Transformation::instantiate($1); $$ = Transformation::instantiate($1);
} }
| ACTION_SEVERITY
{
$$ = new Severity($1);
}
| ACTION_SETVAR | ACTION_SETVAR
{ {
std::string error; std::string error;
@ -597,6 +607,10 @@ act:
$$ = setVar; $$ = setVar;
} }
| LOG_DATA
{
$$ = new LogData($1);
}
| ACTION_MSG | ACTION_MSG
{ {
$$ = new Msg($1); $$ = new Msg($1);
@ -619,6 +633,11 @@ act:
/* not ready yet. */ /* not ready yet. */
$$ = Action::instantiate($1); $$ = Action::instantiate($1);
} }
| ACTION_CTL_AUDIT_LOG_PARTS
{
/* not ready yet. */
$$ = Action::instantiate($1);
}
; ;
actions: actions:

View File

@ -23,16 +23,18 @@ using ModSecurity::split;
%} %}
%option noyywrap nounput batch debug noinput %option noyywrap nounput batch debug noinput
ACTION (?i:accuracy|allow|append|auditlog|block|capture|chain|deny|deprecatevar|drop|exec|expirevar|id:[0-9]+|id:'[0-9]+'|initcol|log|logdata|maturity|multiMatch|noauditlog|nolog|pass|pause|phase:[0-9]+|prepend|proxy|redirect:[A-Z0-9_\|\&\:\/\/\.]+|sanitiseArg|sanitiseMatched|sanitiseMatchedBytes|sanitiseRequestHeader|sanitiseResponseHeader|setuid|setrsc|setsid|setenv|skip|skipAfter|status:[0-9]+|ver|xmlns) ACTION (?i:accuracy|allow|append|auditlog|block|capture|chain|deny|deprecatevar|drop|exec|expirevar|id:[0-9]+|id:'[0-9]+'|initcol|log|maturity|multiMatch|noauditlog|nolog|pass|pause|phase:[0-9]+|prepend|proxy|redirect:[A-Z0-9_\|\&\:\/\/\.]+|sanitiseArg|sanitiseMatched|sanitiseMatchedBytes|sanitiseRequestHeader|sanitiseResponseHeader|setuid|setrsc|setsid|setenv|skip|skipAfter|status:[0-9]+|ver|xmlns)
ACTION_SEVERITY (?i:severity:[0-9]+|severity:'[0-9]+'|severity:(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)|severity:'(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)') ACTION_SEVERITY (?i:severity)
ACTION_SEVERITY_VALUE (?i:(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)|[0-9]+)
ACTION_SETVAR (?i:setvar) ACTION_SETVAR (?i:setvar)
ACTION_MSG (?i:msg) ACTION_MSG (?i:msg)
ACTION_TAG (?i:tag) ACTION_TAG (?i:tag)
ACTION_REV (?i:rev) ACTION_REV (?i:rev)
ACTION_CTL_BDY_XML ctl:requestBodyProcessor=XML ACTION_CTL_BDY_XML ctl:requestBodyProcessor=XML
ACTION_CTL_BDY_JSON ctl:requestBodyProcessor=JSON ACTION_CTL_BDY_JSON ctl:requestBodyProcessor=JSON
ACTION_CTL_AUDIT_LOG_PARTS (?i:ctl:auditLogParts)
DIRECTIVE SecRule DIRECTIVE SecRule
LOG_DATA (?i:logdata)
CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (?i:SecPcreMatchLimitRecursion) CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (?i:SecPcreMatchLimitRecursion)
CONFIG_DIR_PCRE_MATCH_LIMIT (?i:SecPcreMatchLimit) CONFIG_DIR_PCRE_MATCH_LIMIT (?i:SecPcreMatchLimit)
@ -78,7 +80,7 @@ CONFIG_SEC_REMOTE_RULES (?i:SecRemoteRules)
CONFIG_SEC_REMOTE_RULES_FAIL_ACTION (?i:SecRemoteRulesFailAction) CONFIG_SEC_REMOTE_RULES_FAIL_ACTION (?i:SecRemoteRulesFailAction)
DICT_ELEMENT [A-Za-z_0-9-]+ DICT_ELEMENT [^ \|\t]+
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 (?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))
@ -86,7 +88,7 @@ OPERATOR (?i:(?:@inspectFile|@fuzzyHash|@validateByteRange|@validateDTD|@
OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@validateUtf8Encoding) OPERATORNOARG (?i:@detectSQLi|@detectXSS|@geoLookup|@validateUrlEncoding|@validateUtf8Encoding)
TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim) TRANSFORMATION t:(lowercase|urlDecodeUni|urlDecode|none|compressWhitespace|removeWhitespace|replaceNulls|removeNulls|htmlEntityDecode|jsDecode|cssDecode|trim|normalizePathWin|length)
VARIABLE (?i:UNIQUE_ID|SERVER_PORT|SERVER_ADDR|REMOTE_PORT|REMOTE_HOST|MULTIPART_STRICT_ERROR|PATH_INFO|MULTIPART_NAME|MULTIPART_FILENAME|MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|OUTBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO) VARIABLE (?i:UNIQUE_ID|SERVER_PORT|SERVER_ADDR|REMOTE_PORT|REMOTE_HOST|MULTIPART_STRICT_ERROR|PATH_INFO|MULTIPART_NAME|MULTIPART_FILENAME|MULTIPART_CRLF_LF_LINES|MATCHED_VAR_NAME|MATCHED_VARS_NAMES|MATCHED_VAR|MATCHED_VARS|INBOUND_DATA_ERROR|OUTBOUND_DATA_ERROR|FULL_REQUEST|FILES|AUTH_TYPE|ARGS_NAMES|ARGS|QUERY_STRING|REMOTE_ADDR|REQUEST_BASENAME|REQUEST_BODY|REQUEST_COOKIES_NAMES|REQUEST_COOKIES|REQUEST_FILENAME|REQUEST_HEADERS_NAMES|REQUEST_HEADERS|REQUEST_METHOD|REQUEST_PROTOCOL|REQUEST_URI|RESPONSE_BODY|RESPONSE_CONTENT_LENGTH|RESPONSE_CONTENT_TYPE|RESPONSE_HEADERS_NAMES|RESPONSE_HEADERS|RESPONSE_PROTOCOL|RESPONSE_STATUS|TX|GEO)
RUN_TIME_VAR_DUR (?i:DURATION) RUN_TIME_VAR_DUR (?i:DURATION)
@ -123,8 +125,16 @@ CONFIG_VALUE_PATH [0-9A-Za-z_/\.\-]+
AUDIT_PARTS [ABCDEFHJKIZ]+ AUDIT_PARTS [ABCDEFHJKIZ]+
CONFIG_VALUE_NUMBER [0-9]+ CONFIG_VALUE_NUMBER [0-9]+
FREE_TEXT [^\"]+ FREE_TEXT ([^\"]|([^\\]\\\"))+
FREE_TEXT_NEW_LINE [^\"|\n]+ FREE_TEXT_NEW_LINE [^\"|\n]+
FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+
FREE_TEXT_SPACE [^ \t]+
FREE_TEXT_SPACE_COMMA [^, \t]+
VAR_FREE_TEXT_QUOTE ([^\']|([^\\]\\\'))+
VAR_FREE_TEXT_SPACE_COMMA [^, \t\"]+
VAR_FREE_TEXT_SPACE [^ \t\"]+
CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile) CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
@ -158,6 +168,7 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
{CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); } {CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }
{ACTION_CTL_AUDIT_LOG_PARTS}=[+|-]{AUDIT_PARTS} { return yy::seclang_parser::make_ACTION_CTL_AUDIT_LOG_PARTS(yytext, *driver.loc.back()); }
%{ /* Debug log entries */ %} %{ /* Debug log entries */ %}
{CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); } {CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
@ -165,23 +176,30 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
<INITIAL,EXPECTING_OPERATOR>{ <INITIAL,EXPECTING_OPERATOR>{
%{ /* Variables */ %} %{ /* Variables */ %}
[!|&]?{VARIABLE}:?{DICT_ELEMENT}? { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); } [!&]?{VARIABLE}:?{DICT_ELEMENT}? { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_DUR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_DUR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_BLD} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_BLD} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_HSV} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_HSV} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }
[!|&]?{VARIABLENOCOLON} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); } [!&]?{VARIABLENOCOLON} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
["][!&]?{VARIABLE}:?{DICT_ELEMENT}?["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
["][!&]?{RUN_TIME_VAR_DUR}["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }
["][!&]?{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}?["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); }
["][!&]?{RUN_TIME_VAR_BLD}["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }
["][!&]?{RUN_TIME_VAR_HSV}["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }
["][!&]?{VARIABLENOCOLON}["] { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
%{ /* Variables: TIME */ %} %{ /* Variables: TIME */ %}
[!|&]?{RUN_TIME_VAR_TIME} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_DAY} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_DAY} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_EPOCH} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_EPOCH} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_HOUR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_HOUR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_MIN} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_MIN} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_MON} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_MON} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_SEC} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_SEC} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_WDAY} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); } [&]?{RUN_TIME_VAR_TIME_WDAY} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); }
[!|&]?{RUN_TIME_VAR_TIME_YEAR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); } [!&]?{RUN_TIME_VAR_TIME_YEAR} { BEGIN(EXPECTING_OPERATOR); return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); }
} }
@ -225,20 +243,32 @@ CONFIG_DIR_UNICODE_MAP_FILE (?i:SecUnicodeMapFile)
<EXPECTING_OPERATOR>{ <EXPECTING_OPERATOR>{
["][^@]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_FREE_TEXT(yytext, *driver.loc.back()); } ["][^@]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_FREE_TEXT(yytext, *driver.loc.back()); }
["]{OPERATOR}[ ]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); } ["]{OPERATOR}[ ]{FREE_TEXT}["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
["]{OPERATORNOARG}["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); } ["]{OPERATORNOARG}[\t ]*["] { BEGIN(INITIAL); return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
} }
{ACTION} { return yy::seclang_parser::make_ACTION(yytext, *driver.loc.back()); } {ACTION} { return yy::seclang_parser::make_ACTION(yytext, *driver.loc.back()); }
{ACTION_SEVERITY} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }
{ACTION_SETVAR}:{FREE_TEXT}={FREE_TEXT} { {ACTION_SEVERITY}:{ACTION_SEVERITY_VALUE} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext + 9, *driver.loc.back()); }
{ACTION_SEVERITY}:'{ACTION_SEVERITY_VALUE}' { return yy::seclang_parser::make_ACTION_SEVERITY(std::string(yytext, 10, yyleng - 11), *driver.loc.back()); }
{ACTION_SETVAR}:'{VAR_FREE_TEXT_QUOTE}={VAR_FREE_TEXT_QUOTE}' {
return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back()); return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back());
} }
{ACTION_SETVAR}:{FREE_TEXT} { {ACTION_SETVAR}:'{VAR_FREE_TEXT_QUOTE}' {
return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back()); return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back());
} }
{ACTION_MSG}:'{FREE_TEXT}' { return yy::seclang_parser::make_ACTION_MSG(strchr(yytext, ':') + 1, *driver.loc.back()); } {ACTION_SETVAR}:{VAR_FREE_TEXT_SPACE}={VAR_FREE_TEXT_SPACE_COMMA} {
{ACTION_TAG}:'{FREE_TEXT}' { return yy::seclang_parser::make_ACTION_TAG(strchr(yytext, ':') + 1, *driver.loc.back()); } return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back());
{ACTION_REV}:'{FREE_TEXT}' { return yy::seclang_parser::make_ACTION_REV(strchr(yytext, ':') + 1, *driver.loc.back()); } }
{ACTION_SETVAR}:{VAR_FREE_TEXT_SPACE_COMMA} {
return yy::seclang_parser::make_ACTION_SETVAR(strchr(yytext, ':') + 1, *driver.loc.back());
}
{LOG_DATA}:'{FREE_TEXT_QUOTE}' { return yy::seclang_parser::make_LOG_DATA(strchr(yytext, ':') + 1, *driver.loc.back()); }
{ACTION_MSG}:'{FREE_TEXT_QUOTE}' { return yy::seclang_parser::make_ACTION_MSG(strchr(yytext, ':') + 1, *driver.loc.back()); }
{ACTION_TAG}:'{FREE_TEXT_QUOTE}' { return yy::seclang_parser::make_ACTION_TAG(strchr(yytext, ':') + 1, *driver.loc.back()); }
{ACTION_REV}:'{CONFIG_VALUE_NUMBER}' { return yy::seclang_parser::make_ACTION_REV(strchr(yytext, ':') + 1, *driver.loc.back()); }
{ACTION_CTL_BDY_XML} { return yy::seclang_parser::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); } {ACTION_CTL_BDY_XML} { return yy::seclang_parser::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); }
{ACTION_CTL_BDY_JSON} { return yy::seclang_parser::make_ACTION_CTL_BDY_JSON(yytext, *driver.loc.back()); } {ACTION_CTL_BDY_JSON} { return yy::seclang_parser::make_ACTION_CTL_BDY_JSON(yytext, *driver.loc.back()); }

View File

@ -104,52 +104,53 @@ Rules::~Rules() {
* *
* @param uri Full path to the rules file. * @param uri Full path to the rules file.
* *
* @return If rules were loaded successfully or not. * @return Number of rules loaded, -1 if failed.
* @retval true Rules where loaded successfully. * @retval true Rules where loaded successfully.
* @retval false Problem loading the rules. * @retval false Problem loading the rules.
* *
*/ */
bool Rules::loadFromUri(const char *uri) { int Rules::loadFromUri(const char *uri) {
Driver *driver = new Driver(); Driver *driver = new Driver();
if (driver->parseFile(uri) == false) { if (driver->parseFile(uri) == false) {
parserError << driver->parserError.str(); parserError << driver->parserError.str();
return false; return -1;
} }
this->merge(driver); int rules = this->merge(driver);
delete driver; delete driver;
return true; return rules;
} }
bool Rules::load(const char *file, const std::string &ref) { int Rules::load(const char *file, const std::string &ref) {
Driver *driver = new Driver(); Driver *driver = new Driver();
if (driver->parse(file, ref) == false) { if (driver->parse(file, ref) == false) {
parserError << driver->parserError.str(); parserError << driver->parserError.str();
return false; return -1;
} }
this->merge(driver); int rules = this->merge(driver);
delete driver; delete driver;
return true; return rules;
} }
bool Rules::loadRemote(const char *key, const char *uri) { int Rules::loadRemote(const char *key, const char *uri) {
HttpsClient client; HttpsClient client;
client.setKey(key);
bool ret = client.download(uri); bool ret = client.download(uri);
if (ret) { if (ret) {
return this->load(client.content.c_str(), uri); return this->load(client.content.c_str(), uri);
} }
return false; return -1;
} }
bool Rules::load(const char *plainRules) { int Rules::load(const char *plainRules) {
return this->load(plainRules, ""); return this->load(plainRules, "");
} }
@ -178,9 +179,11 @@ int Rules::evaluate(int phase, Assay *assay) {
int Rules::merge(Driver *from) { int Rules::merge(Driver *from) {
int amount_of_rules = 0;
for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) {
std::vector<Rule *> rules = from->rules[i]; std::vector<Rule *> rules = from->rules[i];
for (int j = 0; j < rules.size(); j++) { for (int j = 0; j < rules.size(); j++) {
amount_of_rules++;
Rule *rule = rules[j]; Rule *rule = rules[j];
this->rules[i].push_back(rule); this->rules[i].push_back(rule);
rule->refCountIncrease(); rule->refCountIncrease();
@ -208,17 +211,19 @@ int Rules::merge(Driver *from) {
this->audit_log = from->audit_log; this->audit_log = from->audit_log;
this->audit_log->refCountIncrease(); this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debugLevel); this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(this->debug_log_path); this->debugLog->setOutputFile(from->debug_log_path);
return 0; return amount_of_rules;
} }
int Rules::merge(Rules *from) { int Rules::merge(Rules *from) {
int amount_of_rules = 0;
for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) { for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) {
std::vector<Rule *> rules = from->rules[i]; std::vector<Rule *> rules = from->rules[i];
for (int j = 0; j < rules.size(); j++) { for (int j = 0; j < rules.size(); j++) {
amount_of_rules++;
Rule *rule = rules[j]; Rule *rule = rules[j];
this->rules[i].push_back(rule); this->rules[i].push_back(rule);
rule->refCountIncrease(); rule->refCountIncrease();
@ -244,10 +249,10 @@ int Rules::merge(Rules *from) {
this->audit_log = from->audit_log; this->audit_log = from->audit_log;
this->audit_log->refCountIncrease(); this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debugLevel); this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(this->debug_log_path); this->debugLog->setOutputFile(from->debug_log_path);
return 0; return amount_of_rules;
} }
@ -267,7 +272,7 @@ void Rules::dump() {
std::cout << " rules)" << std::endl; std::cout << " rules)" << std::endl;
for (int j = 0; j < rules.size(); j++) { for (int j = 0; j < rules.size(); j++) {
std::cout << " Rule ID: " << std::to_string(rules[j]->rule_id); std::cout << " Rule ID: " << std::to_string(rules[j]->rule_id);
std::cout << std::endl; std::cout << "--" << rules[j] << std::endl;
} }
} }
} }
@ -297,7 +302,7 @@ extern "C" int msc_rules_add_remote(Rules *rules,
const char *key, const char *uri, const char **error) { const char *key, const char *uri, const char **error) {
int ret = rules->loadRemote(key, uri); int ret = rules->loadRemote(key, uri);
if (ret == 0) { if (ret == 0) {
*error = rules->getParserError().c_str(); *error = strdup(rules->getParserError().c_str());
} }
return ret; return ret;
} }
@ -307,7 +312,7 @@ extern "C" int msc_rules_add_file(Rules *rules, const char *file,
const char **error) { const char **error) {
int ret = rules->loadFromUri(file); int ret = rules->loadFromUri(file);
if (ret == 0) { if (ret == 0) {
*error = rules->getParserError().c_str(); *error = strdup(rules->getParserError().c_str());
} }
return ret; return ret;
} }
@ -317,7 +322,7 @@ extern "C" int msc_rules_add(Rules *rules, const char *plain_rules,
const char **error) { const char **error) {
int ret = rules->load(plain_rules); int ret = rules->load(plain_rules);
if (ret == 0) { if (ret == 0) {
*error = rules->getParserError().c_str(); *error = strdup(rules->getParserError().c_str());
} }
return ret; return ret;
} }

View File

@ -29,6 +29,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "modsecurity/modsecurity.h"
#include "src/unique_id.h" #include "src/unique_id.h"
namespace ModSecurity { namespace ModSecurity {
@ -45,12 +46,16 @@ size_t HttpsClient::handle_impl(char* data, size_t size, size_t nmemb) {
return size * nmemb; return size * nmemb;
} }
void HttpsClient::setKey(const std::string& key) {
m_key = "ModSec-key: " + key;
}
#ifdef MSC_WITH_CURL #ifdef MSC_WITH_CURL
bool HttpsClient::download(const std::string &uri) { bool HttpsClient::download(const std::string &uri) {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
std::string uniqueId = "ModSec-unique-id: " + UniqueId::uniqueId(); std::string uniqueId = "ModSec-unique-id: " + UniqueId::uniqueId();
std::string status = "ModSec-status: " MODSECURITY_VERSION_NUM;
curl = curl_easy_init(); curl = curl_easy_init();
if (!curl) { if (!curl) {
@ -62,6 +67,10 @@ bool HttpsClient::download(const std::string &uri) {
curl_easy_setopt(curl, CURLOPT_URL, uri.c_str()); curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str()); headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str());
headers_chunk = curl_slist_append(headers_chunk, status.c_str());
if (m_key.empty() == false) {
headers_chunk = curl_slist_append(headers_chunk, m_key.c_str());
}
/* Make it TLS 1.x only. */ /* Make it TLS 1.x only. */
curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

View File

@ -37,15 +37,19 @@ class HttpsClient {
public: public:
HttpsClient() HttpsClient()
: content(""), : content(""),
error("") { } error(""),
m_key("") { }
bool download(const std::string &uri); bool download(const std::string &uri);
std::string content; std::string content;
static size_t handle(char * data, size_t size, size_t nmemb, void * p); static size_t handle(char * data, size_t size, size_t nmemb, void * p);
size_t handle_impl(char * data, size_t size, size_t nmemb); size_t handle_impl(char * data, size_t size, size_t nmemb);
void setKey(const std::string& key);
std::string error; std::string error;
private:
std::string m_key;
}; };