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] == '  ' ' \t ' 
152+         offset++;
153+     };
154+ 
155+     op_len = strlen (content);
156+ 
157+     if  (content[offset] == ' \" ' 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' ' a' 
203+                     parm[i] == ' B' ' b' 
204+                     parm[i] == ' C' ' c' 
205+                     parm[i] == ' D' ' d' 
206+                     parm[i] == ' E' ' e' 
207+                     parm[i] == ' F' ' 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