2525#include < list>
2626#include < memory>
2727
28- #ifdef WITH_HS
29- #include < hs.h>
30- #endif
31-
32-
3328#include " src/operators/operator.h"
3429#ifndef WITH_HS
3530#include " src/utils/acmp.h"
@@ -41,17 +36,18 @@ namespace operators {
4136
4237Pm::~Pm () {
4338#ifdef WITH_HS
39+ m_hs = NULL ;
4440#else
4541 acmp_node_t *root = m_p->root_node ;
4642
4743 cleanup (root);
4844
4945 free (m_p);
5046 m_p = NULL ;
47+ #endif
5148#ifdef MODSEC_MUTEX_ON_PM
5249 pthread_mutex_destroy (&m_lock);
5350#endif
54- #endif
5551}
5652
5753#ifndef WITH_HS
@@ -95,22 +91,28 @@ void Pm::postOrderTraversal(acmp_btree_node_t *node) {
9591
9692bool Pm::evaluate (Transaction *transaction, RuleWithActions *rule,
9793 const std::string &input, std::shared_ptr<RuleMessage> ruleMessage) {
94+ int rc = 0 ;
95+ const char *match = NULL ;
9896#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
100104#else
101- int rc;
102105 ACMPT pt;
103106 pt.parser = m_p;
104107 pt.ptr = NULL ;
105- const char *match = NULL ;
106108#ifdef MODSEC_MUTEX_ON_PM
107109 pthread_mutex_lock (&m_lock);
108110#endif
109111 rc = acmp_process_quick (&pt, &match, input.c_str (), input.length ());
110112#ifdef MODSEC_MUTEX_ON_PM
111113 pthread_mutex_unlock (&m_lock);
112114#endif
113-
115+ # endif
114116 if (rc >= 0 && transaction) {
115117 std::string match_ (match?match:" " );
116118 logOffset (ruleMessage, rc - match_.size () + 1 , match_.size ());
@@ -125,16 +127,138 @@ bool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,
125127 }
126128
127129 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+ }
128246#endif
129247
130- return 0 ;
131- }
248+ // processed = memcpy(processed, parm, op_len);
249+ processed = strdup (parm);
250+ free (parm);
251+ parm = NULL ;
132252
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+ }
133260
134261bool 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
138262 std::vector<std::string> vec;
139263 std::istringstream *iss;
140264 const char *err = NULL ;
@@ -154,20 +278,32 @@ bool Pm::init(const std::string &file, std::string *error) {
154278 back_inserter (vec));
155279
156280 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
157293 acmp_add_pattern (m_p, a.c_str (), NULL , NULL , a.length ());
158294 }
159295
160296 while (m_p->is_failtree_done == 0 ) {
161297 acmp_prepare (m_p);
162298 }
299+ #endif
163300
164301 if (content) {
165302 free (content);
166303 content = NULL ;
167304 }
168305
169306 delete iss;
170- #endif
171307 return true ;
172308}
173309
0 commit comments