Skip to content

Commit 17c4201

Browse files
committed
Better error handling when loading configurations
1 parent 8de527e commit 17c4201

File tree

11 files changed

+163
-136
lines changed

11 files changed

+163
-136
lines changed

CHANGES

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
v3.x.y - YYYY-MMM-DD (to be released)
2-
-------------------------------------
3-
4-
- IMPORTANT: SecDefaultAction behaves changing: SecDefaultAction specified
2+
-------------------------------------
3+
4+
- Added the basics for supporting better error/warning handling while
5+
loading configurations.
6+
[@zimmerle]
7+
- IMPORTANT: SecDefaultAction behaves changing: SecDefaultAction specified
58
on a child configuration will overwrite the ones specified on the parent;
69
Previously it was concatenating.
710
[@zimmerle]

headers/modsecurity/modsecurity.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include <iostream>
7979
#include <string>
8080
#include <memory>
81+
#include <vector>
8182
#endif
8283

8384

@@ -95,6 +96,10 @@ namespace modsecurity {
9596
*/
9697
using ModSecString = std::string;
9798

99+
using RulesErrors = std::vector<std::unique_ptr<std::string>>;
100+
using RulesWarnings = std::vector<std::unique_ptr<std::string>>;
101+
102+
98103
using RuleId = int64_t;
99104

100105
/**

headers/modsecurity/rules.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,33 +40,35 @@ class Transformation;
4040
}
4141
}
4242

43+
4344
class Rules {
4445
public:
45-
void dump() const;
46+
using container=std::vector<std::shared_ptr<Rule>>;
47+
using iterator=typename container::iterator;
48+
using const_iterator=typename container::const_iterator;
4649

47-
int append(Rules *from,
48-
const std::vector<RuleId> &ids,
49-
std::ostringstream *err);
50+
int append(Rules *from);
5051

5152
bool insert(const std::shared_ptr<Rule> &rule);
5253

53-
bool insert(std::shared_ptr<Rule> rule,
54-
const std::vector<RuleId> *ids,
55-
std::ostringstream *err);
56-
5754
size_t size() const;
5855

5956
std::shared_ptr<Rule> operator[](int index) const;
6057
std::shared_ptr<Rule> at(int index) const;
6158

62-
void fixDefaultActions();
59+
void fixDefaultActions(RulesWarnings *warnings, RulesErrors *errors);
6360

6461
std::vector<std::shared_ptr<actions::Action> > m_defaultActions;
6562
std::vector<std::shared_ptr<actions::transformations::Transformation> > m_defaultTransformations;
6663

67-
std::vector<std::shared_ptr<Rule> > m_rules;
6864
void dump();
6965

66+
inline iterator begin() noexcept { return m_rules.begin(); }
67+
inline const_iterator cbegin() const noexcept { return m_rules.cbegin(); }
68+
inline iterator end() noexcept { return m_rules.end(); }
69+
inline const_iterator cend() const noexcept { return m_rules.cend(); }
70+
private:
71+
container m_rules;
7072
};
7173

7274

headers/modsecurity/rules_set.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <string>
2323
#include <vector>
2424
#include <list>
25+
#include <memory>
2526
#endif
2627

2728

@@ -42,8 +43,6 @@ namespace Parser {
4243
class Driver;
4344
}
4445

45-
46-
4746
/** @ingroup ModSecurity_CPP_API */
4847
class RulesSet : public RulesSetProperties {
4948
public:
@@ -68,19 +67,21 @@ class RulesSet : public RulesSetProperties {
6867
int load(const char *rules);
6968
int load(const char *rules, const std::string &ref);
7069

71-
void dump() const;
70+
void dump();
7271

7372
int merge(Parser::Driver *driver);
7473
int merge(RulesSet *rules);
7574

7675
int evaluate(int phase, Transaction *transaction);
76+
7777
std::string getParserError();
7878

7979
void debug(int level, const std::string &id, const std::string &uri,
8080
const std::string &msg);
8181

8282
RulesSetPhases m_rulesSetPhases;
8383
private:
84+
bool containsDuplicatedIds(RulesWarnings *warnings, RulesErrors *errors);
8485
#ifndef NO_LOGS
8586
uint8_t m_secmarker_skipped;
8687
#endif

headers/modsecurity/rules_set_phases.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <string>
2424
#include <vector>
2525
#include <list>
26+
#include <array>
2627
#endif
2728

2829

@@ -42,18 +43,33 @@ class Driver;
4243
/** @ingroup ModSecurity_CPP_API */
4344
class RulesSetPhases {
4445
public:
46+
using container = std::array<Rules, modsecurity::Phases::NUMBER_OF_PHASES>;
47+
using iterator = typename container::iterator;
48+
using const_iterator = typename container::const_iterator;
4549

46-
bool insert(std::shared_ptr<Rule> rule);
50+
void insert(std::shared_ptr<Rule> rule);
51+
void append(RulesSetPhases *from);
4752

4853
int append(RulesSetPhases *from, std::ostringstream *err);
49-
void dump() const;
54+
void dump();
5055

5156
Rules *operator[](int index);
5257
Rules *at(int index);
58+
static size_t size() { return modsecurity::Phases::NUMBER_OF_PHASES; }
5359

54-
private:
55-
Rules m_rulesAtPhase[8];
60+
void fixDefaultActions(RulesWarnings *warnings, RulesErrors *errors) {
61+
for (auto &phase : m_rulesAtPhase) {
62+
phase.fixDefaultActions(warnings, errors);
63+
}
64+
}
65+
66+
inline iterator begin() noexcept { return m_rulesAtPhase.begin(); }
67+
inline const_iterator cbegin() const noexcept { return m_rulesAtPhase.cbegin(); }
68+
inline iterator end() noexcept { return m_rulesAtPhase.end(); }
69+
inline const_iterator cend() const noexcept { return m_rulesAtPhase.cend(); }
5670

71+
private:
72+
container m_rulesAtPhase;
5773
};
5874

5975

headers/modsecurity/rules_set_properties.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ class RulesSetProperties {
330330

331331

332332
static int mergeProperties(RulesSetProperties *from,
333-
RulesSetProperties *to, std::ostringstream *err) {
333+
RulesSetProperties *to,
334+
RulesWarnings *warning,
335+
RulesErrors *error) {
334336

335337
merge_ruleengine_value(to->m_secRuleEngine, from->m_secRuleEngine,
336338
PropertyNotSetRuleEngine);
@@ -401,23 +403,23 @@ class RulesSetProperties {
401403
}
402404

403405
if (to->m_auditLog) {
404-
std::string error;
405-
to->m_auditLog->merge(from->m_auditLog, &error);
406-
if (error.size() > 0) {
407-
*err << error;
406+
std::string error_;
407+
to->m_auditLog->merge(from->m_auditLog, &error_);
408+
if (error_.size() > 0) {
409+
error->push_back(std::unique_ptr<std::string>(new std::string(error_)));
408410
return -1;
409411
}
410412
}
411413

412414
if (from->m_debugLog && to->m_debugLog &&
413415
from->m_debugLog->isLogFileSet()) {
414416
if (to->m_debugLog->isLogFileSet() == false) {
415-
std::string error;
417+
std::string error_;
416418
to->m_debugLog->setDebugLogFile(
417419
from->m_debugLog->getDebugLogFile(),
418-
&error);
419-
if (error.size() > 0) {
420-
*err << error;
420+
&error_);
421+
if (error_.size() > 0) {
422+
error->push_back(std::unique_ptr<std::string>(new std::string(error_)));
421423
return -1;
422424
}
423425
}

src/parser/driver.cc

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,6 @@ int Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {
176176
return false;
177177
}
178178

179-
for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {
180-
Rules *rules = m_rulesSetPhases[i];
181-
for (int j = 0; j < rules->size(); j++) {
182-
RuleWithOperator *lr = dynamic_cast<RuleWithOperator *>(rules->at(j).get());
183-
if (lr && lr->getId() == rule->getId()) {
184-
m_parserError << "Rule id: " << std::to_string(rule->getId()) \
185-
<< " is duplicated" << std::endl;
186-
return false;
187-
}
188-
}
189-
}
190-
191179
m_lastRule = rule.get();
192180

193181
m_rulesSetPhases.insert(rule);

src/rules.cc

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,23 @@
2020
namespace modsecurity {
2121

2222

23-
int Rules::append(Rules *from, const std::vector<RuleId> &ids, std::ostringstream *err) {
24-
size_t j = 0;
25-
for (; j < from->size(); j++) {
26-
RuleWithActions *rule = dynamic_cast<RuleWithActions*>(from->at(j).get());
27-
if (rule && std::binary_search(ids.begin(), ids.end(), rule->getId())) {
28-
if (err != NULL) {
29-
*err << "Rule id: " << std::to_string(rule->getId()) \
30-
<< " is duplicated" << std::endl;
31-
}
32-
return -1;
23+
int Rules::append(Rules *from) {
24+
m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end());
25+
if (!from->m_defaultActions.empty() || !from->m_defaultTransformations.empty()) {
26+
m_defaultActions.clear();
27+
m_defaultTransformations.clear();
28+
for (auto &a : from->m_defaultActions) {
29+
m_defaultActions.push_back(a);
30+
}
31+
for (auto &a : from->m_defaultTransformations) {
32+
m_defaultTransformations.push_back(a);
3333
}
3434
}
35-
m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end());
36-
return j;
35+
return from->size();
3736
}
3837

3938

4039
bool Rules::insert(const std::shared_ptr<Rule> &rule) {
41-
return insert(rule, nullptr, nullptr);
42-
}
43-
44-
45-
bool Rules::insert(std::shared_ptr<Rule> rule, const std::vector<RuleId> *ids, std::ostringstream *err) {
46-
RuleWithActions*r = dynamic_cast<RuleWithActions*>(rule.get());
47-
if (r && ids != nullptr
48-
&& std::binary_search(ids->begin(), ids->end(), r->getId())) {
49-
if (err != NULL) {
50-
*err << "Rule id: " << std::to_string(r->getId()) \
51-
<< " is duplicated" << std::endl;
52-
}
53-
return false;
54-
}
5540
m_rules.push_back(rule);
5641
return true;
5742
}
@@ -72,7 +57,7 @@ std::shared_ptr<Rule> Rules::at(int index) const {
7257
}
7358

7459

75-
void Rules::dump() const {
60+
void Rules::dump() {
7661
for (int j = 0; j < m_rules.size(); j++) {
7762
std::cout << " Rule ID: " << m_rules.at(j)->getReference();
7863
std::cout << "--" << m_rules.at(j) << std::endl;

0 commit comments

Comments
 (0)