Skip to content

Commit e5acc95

Browse files
committed
First version of global' and ip' collections
1 parent 214cc15 commit e5acc95

File tree

9 files changed

+368
-10
lines changed

9 files changed

+368
-10
lines changed

headers/modsecurity/modsecurity.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ typedef struct ModSecurity_t modsecurity;
9393
#include "modsecurity/transaction.h"
9494
#include "modsecurity/debug_log.h"
9595
#include "modsecurity/rules.h"
96+
#include "modsecurity/transaction/global_variables.h"
9697

9798
/**
9899
* TAG_NUM:
@@ -222,6 +223,8 @@ class ModSecurity {
222223
NUMBER_OF_PHASES,
223224
};
224225

226+
transaction::GlobalVariables m_global_collection;
227+
transaction::GlobalVariables m_ip_collection;
225228
private:
226229
std::string m_connector;
227230
LogCb m_logCb;

headers/modsecurity/transaction/collections.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <list>
2828
#endif
2929

30+
#include "modsecurity/transaction/global_variables.h"
3031
#include "modsecurity/transaction/variables.h"
3132
#include "modsecurity/transaction/variable.h"
3233
#include "modsecurity/transaction/collection.h"
@@ -45,7 +46,7 @@ namespace transaction {
4546
class Collections :
4647
public std::unordered_map<std::string, Collection *> {
4748
public:
48-
Collections();
49+
Collections(GlobalVariables *global, GlobalVariables *ip);
4950
~Collections();
5051

5152
void init(const std::string& name, const std::string& key);
@@ -84,6 +85,12 @@ class Collections :
8485
* Notice that it is not the TX collection.
8586
*/
8687
transaction::Variables m_transient;
88+
89+
std::string m_global_collection_key;
90+
std::string m_ip_collection_key;
91+
92+
transaction::GlobalVariables *m_global_collection;
93+
transaction::GlobalVariables *m_ip_collection;
8794
};
8895

8996
} // namespace transaction
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* ModSecurity, http://www.modsecurity.org/
3+
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
4+
*
5+
* You may not use this file except in compliance with
6+
* the License. You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* If any of the files related to licensing are missing or if you have any
11+
* other questions related to licensing please contact Trustwave Holdings, Inc.
12+
* directly using the email address security@modsecurity.org.
13+
*
14+
*/
15+
16+
17+
#ifdef __cplusplus
18+
#include <string>
19+
#include <iostream>
20+
#include <unordered_map>
21+
#include <list>
22+
#include <vector>
23+
#include <algorithm>
24+
#endif
25+
26+
27+
#include "modsecurity/transaction/variable.h"
28+
29+
#ifndef HEADERS_MODSECURITY_TRANSACTION_GLOBAL_VARIABLES_H_
30+
#define HEADERS_MODSECURITY_TRANSACTION_GLOBAL_VARIABLES_H_
31+
32+
#ifndef __cplusplus
33+
typedef struct Variable_t Variables;
34+
#endif
35+
36+
#ifdef __cplusplus
37+
namespace modsecurity {
38+
namespace transaction {
39+
40+
41+
class CollectionKey {
42+
public:
43+
CollectionKey()
44+
: m_compartiment(""),
45+
m_name("") { };
46+
CollectionKey(std::string name)
47+
: m_compartiment(""),
48+
m_name(name) { };
49+
CollectionKey(std::string name, std::string compartiment)
50+
: m_compartiment(compartiment),
51+
m_name(name) { };
52+
53+
std::string m_name;
54+
std::string m_compartiment;
55+
};
56+
57+
58+
class collection_hash
59+
{
60+
public:
61+
size_t operator()(const CollectionKey *v) const
62+
{
63+
size_t h = 0;
64+
std::for_each(v->m_name.begin(), v->m_name.end(), [&](char c) {
65+
h += tolower(c);
66+
});
67+
std::for_each(v->m_compartiment.begin(), v->m_compartiment.end(), [&](char c) {
68+
h += tolower(c);
69+
});
70+
71+
return h;
72+
};
73+
};
74+
75+
76+
class collection_equal
77+
{
78+
public:
79+
bool operator()(const CollectionKey *u, const CollectionKey *v) const
80+
{
81+
return u->m_name == v->m_name && u->m_compartiment == v->m_compartiment;
82+
};
83+
};
84+
85+
86+
class GlobalVariables :
87+
public std::unordered_multimap<CollectionKey *, std::string,
88+
collection_hash, collection_equal> {
89+
public:
90+
GlobalVariables();
91+
~GlobalVariables();
92+
void store(std::string key, std::string compartment, std::string value);
93+
94+
bool storeOrUpdateFirst(const std::string &key, std::string compartment,
95+
const std::string &value);
96+
97+
bool updateFirst(const std::string &key, std::string compartment,
98+
const std::string &value);
99+
100+
void del(const std::string& key, std::string compartment);
101+
102+
std::string* resolveFirst(const std::string& var, std::string compartment);
103+
void resolveSingleMatch(const std::string& var, std::string compartment,
104+
std::vector<const transaction::Variable *> *l);
105+
void resolveMultiMatches(const std::string& var, std::string compartment,
106+
std::vector<const transaction::Variable *> *l);
107+
108+
void resolveRegularExpression(const std::string& var, std::string compartment,
109+
std::vector<const transaction::Variable *> *l);
110+
111+
112+
};
113+
114+
} // namespace transaction
115+
} // namespace modsecurity
116+
#endif
117+
118+
119+
#endif // HEADERS_MODSECURITY_TRANSACTION_GLOBAL_VARIABLES_H_

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ libmodsecurity_includesub_HEADERS = \
3636
../headers/modsecurity/transaction/collections.h \
3737
../headers/modsecurity/transaction/variable.h \
3838
../headers/modsecurity/transaction/variables.h
39+
../headers/modsecurity/transaction/global_variables.h
3940

4041

4142

@@ -188,6 +189,7 @@ libmodsecurity_la_SOURCES = \
188189
utils.cc \
189190
collections.cc \
190191
variables.cc \
192+
global_variables.cc \
191193
debug_log.cc \
192194
debug_log_writer.cc \
193195
debug_log_writer_agent.cc \

src/actions/init_col.cc

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,30 @@ bool InitCol::init(std::string *error) {
4646
m_collection_key = std::string(action, posInit, posEquals - posInit);
4747
m_collection_value = std::string(action, posEquals + 1);
4848

49+
if (m_collection_key != "ip" && m_collection_key != "global") {
50+
return false;
51+
}
52+
4953
return true;
5054
}
5155

5256

53-
bool InitCol::evaluate(Rule *rule, Transaction *transaction) {
57+
bool InitCol::evaluate(Rule *rule, Transaction *t) {
5458
std::string collectionName;
55-
collectionName = MacroExpansion::expand(m_collection_value, transaction);
56-
std::cout << "Collection is not implemented yet, here is the ";
57-
std::cout << "collection name: " << collectionName << std::endl;
59+
collectionName = MacroExpansion::expand(m_collection_value, t);
60+
61+
62+
if (m_collection_key == "ip") {
63+
t->m_collections.m_ip_collection_key = collectionName;
64+
} else if (m_collection_key == "global") {
65+
t->m_collections.m_global_collection_key = collectionName;
66+
} else {
67+
return false;
68+
}
69+
70+
t->debug(5, "Collection `" + m_collection_key + "' initialized with " \
71+
"value: " + collectionName);
72+
5873
return true;
5974
}
6075

src/collections.cc

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ namespace modsecurity {
3131
namespace transaction {
3232

3333

34-
Collections::Collections() {
34+
Collections::Collections(transaction::GlobalVariables *global,
35+
transaction::GlobalVariables *ip)
36+
: m_global_collection_key(""),
37+
m_ip_collection_key(""),
38+
m_global_collection(global),
39+
m_ip_collection(ip) {
3540
/* Create collection TX */
3641
this->emplace("TX", new Collection("TX", ""));
3742
}
@@ -53,6 +58,20 @@ void Collections::init(const std::string& name, const std::string& key) {
5358
void Collections::storeOrUpdateFirst(const std::string& collectionName,
5459
const std::string& variableName,
5560
const std::string& targetValue) {
61+
if (tolower(collectionName) == "ip"
62+
&& !m_ip_collection_key.empty()) {
63+
m_ip_collection->storeOrUpdateFirst(collectionName + ":"
64+
+ variableName, m_ip_collection_key, targetValue);
65+
return;
66+
}
67+
68+
if (tolower(collectionName) == "global"
69+
&& !m_global_collection_key.empty()) {
70+
m_global_collection->storeOrUpdateFirst(collectionName + ":"
71+
+ variableName, m_global_collection_key, targetValue);
72+
return;
73+
}
74+
5675
try {
5776
transaction::Variables *collection;
5877
collection = this->at(collectionName);
@@ -99,7 +118,7 @@ std::string* Collections::resolveFirst(const std::string& var) {
99118
for (auto &a : *this) {
100119
auto range = a.second->equal_range(var);
101120
for (auto it = range.first; it != range.second; ++it) {
102-
return &it->second;
121+
return & it->second;
103122
}
104123
}
105124

@@ -109,6 +128,19 @@ std::string* Collections::resolveFirst(const std::string& var) {
109128

110129
std::string* Collections::resolveFirst(const std::string& collectionName,
111130
const std::string& var) {
131+
132+
if (tolower(collectionName) == "ip"
133+
&& !m_ip_collection_key.empty()) {
134+
return m_ip_collection->resolveFirst(toupper(collectionName)
135+
+ ":" + var, m_ip_collection_key);
136+
}
137+
138+
if (tolower(collectionName) == "global"
139+
&& !m_global_collection_key.empty()) {
140+
return m_global_collection->resolveFirst(toupper(collectionName)
141+
+ ":" + var, m_global_collection_key);
142+
}
143+
112144
for (auto &a : *this) {
113145
if (tolower(a.first) == tolower(collectionName)) {
114146
transaction::Variables *t = a.second;
@@ -135,6 +167,18 @@ void Collections::resolveSingleMatch(const std::string& var,
135167
const std::string& collection,
136168
std::vector<const transaction::Variable *> *l) {
137169

170+
if (tolower(collection) == "ip"
171+
&& !m_ip_collection_key.empty()) {
172+
m_ip_collection->resolveSingleMatch(var, m_ip_collection_key, l);
173+
return;
174+
}
175+
176+
if (tolower(collection) == "global"
177+
&& !m_global_collection_key.empty()) {
178+
m_global_collection->resolveSingleMatch(var, m_global_collection_key, l);
179+
return;
180+
}
181+
138182
try {
139183
this->at(collection)->resolveSingleMatch(var, l);
140184
} catch (...) { }
@@ -150,6 +194,18 @@ void Collections::resolveMultiMatches(const std::string& var,
150194
void Collections::resolveMultiMatches(const std::string& var,
151195
const std::string& collection,
152196
std::vector<const transaction::Variable *> *l) {
197+
if (tolower(collection) == "ip"
198+
&& !m_ip_collection_key.empty()) {
199+
m_ip_collection->resolveMultiMatches(var, m_ip_collection_key, l);
200+
return;
201+
}
202+
203+
if (tolower(collection) == "global"
204+
&& !m_global_collection_key.empty()) {
205+
m_global_collection->resolveMultiMatches(var, m_global_collection_key, l);
206+
return;
207+
}
208+
153209
try {
154210
this->at(collection)->resolveMultiMatches(var, l);
155211
} catch (...) { }
@@ -164,6 +220,19 @@ void Collections::resolveRegularExpression(const std::string& var,
164220
void Collections::resolveRegularExpression(const std::string& var,
165221
const std::string& collection,
166222
std::vector<const transaction::Variable *> *l) {
223+
if (tolower(collection) == "ip"
224+
&& !m_ip_collection_key.empty()) {
225+
m_ip_collection->resolveRegularExpression(toupper(collection)
226+
+ ":" + var, m_ip_collection_key, l);
227+
return;
228+
}
229+
230+
if (tolower(collection) == "global"
231+
&& !m_global_collection_key.empty()) {
232+
m_global_collection->resolveRegularExpression(toupper(collection)
233+
+ ":" + var, m_global_collection_key, l);
234+
return;
235+
}
167236

168237
try {
169238
this->at(collection)->resolveRegularExpression(var, l);

0 commit comments

Comments
 (0)