25
25
#include < list>
26
26
#include < memory>
27
27
28
- #ifdef WITH_HS
29
- #include < hs.h>
30
- #endif
31
-
32
-
33
28
#include " src/operators/operator.h"
34
29
#ifndef WITH_HS
35
30
#include " src/utils/acmp.h"
@@ -41,17 +36,18 @@ namespace operators {
41
36
42
37
Pm::~Pm () {
43
38
#ifdef WITH_HS
39
+ m_hs = NULL ;
44
40
#else
45
41
acmp_node_t *root = m_p->root_node ;
46
42
47
43
cleanup (root);
48
44
49
45
free (m_p);
50
46
m_p = NULL ;
47
+ #endif
51
48
#ifdef MODSEC_MUTEX_ON_PM
52
49
pthread_mutex_destroy (&m_lock);
53
50
#endif
54
- #endif
55
51
}
56
52
57
53
#ifndef WITH_HS
@@ -95,22 +91,28 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
95
91
96
92
bool Pm::evaluate (Transaction *transaction, RuleWithActions *rule,
97
93
const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
94
+ int rc = 0 ;
95
+ const char *match = NULL ;
98
96
#ifdef WITH_HS
99
- return 0 ;
97
+ #ifdef MODSEC_MUTEX_ON_PM
98
+ pthread_mutex_lock (&m_lock);
99
+ #endif
100
+ rc = m_hs->search (input.c_str (), input.length (), &match);
101
+ #ifdef MODSEC_MUTEX_ON_PM
102
+ pthread_mutex_unlock (&m_lock);
103
+ #endif
100
104
#else
101
- int rc;
102
105
ACMPT pt;
103
106
pt.parser = m_p;
104
107
pt.ptr = NULL ;
105
- const char *match = NULL ;
106
108
#ifdef MODSEC_MUTEX_ON_PM
107
109
pthread_mutex_lock (&m_lock);
108
110
#endif
109
111
rc = acmp_process_quick (&pt, &match, input.c_str (), input.length ());
110
112
#ifdef MODSEC_MUTEX_ON_PM
111
113
pthread_mutex_unlock (&m_lock);
112
114
#endif
113
-
115
+ # endif
114
116
if (rc >= 0 && transaction) {
115
117
std::string match_ (match?match:" " );
116
118
logOffset (ruleMessage, rc - match_.size () + 1 , match_.size ());
@@ -125,16 +127,138 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
125
127
}
126
128
127
129
return rc >= 0 ;
130
+ }
131
+
132
+ static
133
+ char *parse_pm_content (const char *op_parm, unsigned short int op_len, const char **error_msg) {
134
+ char *parm = NULL ;
135
+ char *content;
136
+ unsigned short int offset = 0 ;
137
+ // char converted = 0;
138
+ int i, x;
139
+ unsigned char bin = 0 , esc = 0 , bin_offset = 0 ;
140
+ unsigned char c;
141
+ unsigned char bin_parm[3 ] = { 0 };
142
+ char *processed = NULL ;
143
+
144
+ content = strdup (op_parm);
145
+
146
+ if (content == NULL ) {
147
+ *error_msg = std::string (" Error allocating memory for pattern matching content." ).c_str ();
148
+ return NULL ;
149
+ }
150
+
151
+ while (offset < op_len && (content[offset] == ' ' || content[offset] == ' \t ' )) {
152
+ offset++;
153
+ };
154
+
155
+ op_len = strlen (content);
156
+
157
+ if (content[offset] == ' \" ' && content[op_len-1 ] == ' \" ' ) {
158
+ parm = strdup (content + offset + 1 );
159
+ if (parm == NULL ) {
160
+ *error_msg = std::string (" Error allocating memory for pattern matching content." ).c_str ();
161
+ free (content);
162
+ content = NULL ;
163
+ return NULL ;
164
+ }
165
+ parm[op_len - offset - 2 ] = ' \0 ' ;
166
+ } else {
167
+ parm = strdup (content + offset);
168
+ if (parm == NULL ) {
169
+ free (content);
170
+ content = NULL ;
171
+ *error_msg = std::string (" Error allocating memory for pattern matching content." ).c_str ();
172
+ return NULL ;
173
+ }
174
+ }
175
+
176
+ free (content);
177
+ content = NULL ;
178
+
179
+ op_len = strlen (parm);
180
+
181
+ if (op_len == 0 ) {
182
+ *error_msg = " Content length is 0." ;
183
+ free (parm);
184
+ return NULL ;
185
+ }
186
+
187
+ for (i = 0 , x = 0 ; i < op_len; i++) {
188
+ if (parm[i] == ' |' ) {
189
+ if (bin) {
190
+ bin = 0 ;
191
+ } else {
192
+ bin = 1 ;
193
+ }
194
+ } else if (!esc && parm[i] == ' \\ ' ) {
195
+ esc = 1 ;
196
+ } else {
197
+ if (bin) {
198
+ if (parm[i] == 0 || parm[i] == 1 || parm[i] == 2 ||
199
+ parm[i] == 3 || parm[i] == 4 || parm[i] == 5 ||
200
+ parm[i] == 6 || parm[i] == 7 || parm[i] == 8 ||
201
+ parm[i] == 9 ||
202
+ parm[i] == ' A' || parm[i] == ' a' ||
203
+ parm[i] == ' B' || parm[i] == ' b' ||
204
+ parm[i] == ' C' || parm[i] == ' c' ||
205
+ parm[i] == ' D' || parm[i] == ' d' ||
206
+ parm[i] == ' E' || parm[i] == ' e' ||
207
+ parm[i] == ' F' || parm[i] == ' f' )
208
+ {
209
+ bin_parm[bin_offset] = (char )parm[i];
210
+ bin_offset++;
211
+ if (bin_offset == 2 ) {
212
+ c = strtol ((char *)bin_parm, (char **) NULL , 16 ) & 0xFF ;
213
+ bin_offset = 0 ;
214
+ parm[x] = c;
215
+ x++;
216
+ // converted = 1;
217
+ }
218
+ } else if (parm[i] == ' ' ) {
219
+ }
220
+ } else if (esc) {
221
+ if (parm[i] == ' :' ||
222
+ parm[i] == ' ;' ||
223
+ parm[i] == ' \\ ' ||
224
+ parm[i] == ' \" ' )
225
+ {
226
+ parm[x] = parm[i];
227
+ x++;
228
+ } else {
229
+ *error_msg = std::string (" Unsupported escape sequence." ).c_str ();
230
+ free (parm);
231
+ return NULL ;
232
+ }
233
+ esc = 0 ;
234
+ // converted = 1;
235
+ } else {
236
+ parm[x] = parm[i];
237
+ x++;
238
+ }
239
+ }
240
+ }
241
+
242
+ #if 0
243
+ if (converted) {
244
+ op_len = x;
245
+ }
128
246
#endif
129
247
130
- return 0 ;
131
- }
248
+ // processed = memcpy(processed, parm, op_len);
249
+ processed = strdup (parm);
250
+ free (parm);
251
+ parm = NULL ;
132
252
253
+ if (processed == NULL ) {
254
+ *error_msg = std::string (" Error allocating memory for pattern matching content." ).c_str ();
255
+ return NULL ;
256
+ }
257
+
258
+ return processed;
259
+ }
133
260
134
261
bool Pm::init (const std::string &file, std::string *error) {
135
- #ifdef WITH_HS
136
- fprintf (stdout, " Sopport for HS is on the way: %s\n " , hs_version ());
137
- #else
138
262
std::vector<std::string> vec;
139
263
std::istringstream *iss;
140
264
const char *err = NULL ;
@@ -154,20 +278,32 @@ bool Pm::init(const std::string &file, std::string *error) {
154
278
back_inserter (vec));
155
279
156
280
for (auto &a : vec) {
281
+ #ifdef WITH_HS
282
+ m_hs->addPattern (a.c_str (), a.length ());
283
+ }
284
+ if (m_hs->compile (error) == false ) {
285
+ if (content) {
286
+ free (content);
287
+ content = NULL ;
288
+ }
289
+ delete iss;
290
+ return false ;
291
+ }
292
+ #else
157
293
acmp_add_pattern (m_p, a.c_str (), NULL , NULL , a.length ());
158
294
}
159
295
160
296
while (m_p->is_failtree_done == 0 ) {
161
297
acmp_prepare (m_p);
162
298
}
299
+ #endif
163
300
164
301
if (content) {
165
302
free (content);
166
303
content = NULL ;
167
304
}
168
305
169
306
delete iss;
170
- #endif
171
307
return true ;
172
308
}
173
309
0 commit comments