1 /*
2 * ModSecurity for Apache 2.x, http://www.modsecurity.org/
3 * Copyright (c) 2004-2013 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 #ifndef _MSC_RE_H_
16 #define _MSC_RE_H_
17 
18 #define ABSOLUTE_VALUE 0
19 #define POSITIVE_VALUE 1
20 #define NEGATIVE_VALUE 2
21 
22 typedef struct msre_engine msre_engine;
23 typedef struct msre_ruleset msre_ruleset;
24 typedef struct msre_ruleset_internal msre_ruleset_internal;
25 typedef struct msre_rule msre_rule;
26 typedef struct msre_var_metadata msre_var_metadata;
27 typedef struct msre_var msre_var;
28 typedef struct msre_op_metadata msre_op_metadata;
29 typedef struct msre_tfn_metadata msre_tfn_metadata;
30 typedef struct msre_actionset msre_actionset;
31 typedef struct msre_action_metadata msre_action_metadata;
32 typedef struct msre_action msre_action;
33 typedef struct msre_reqbody_processor_metadata msre_reqbody_processor_metadata;
34 typedef struct msre_cache_rec msre_cache_rec;
35 
36 #include "apr_general.h"
37 #include "apr_tables.h"
38 #include "modsecurity.h"
39 #include "msc_pcre.h"
40 #include "msc_tree.h"
41 #include "persist_dbm.h"
42 #include "apache2.h"
43 #include "http_config.h"
44 
45 #if defined(WITH_LUA)
46 #include "msc_lua.h"
47 #endif
48 
49 /* Actions, variables, functions and operator functions */
50 char DSOLOCAL *update_rule_target_ex(modsec_rec *msr, msre_ruleset *ruleset, msre_rule *rule, const char *p2,
51         const char *p3);
52 
53 int DSOLOCAL msre_ruleset_rule_matches_exception(msre_rule *rule, rule_exception *re);
54 
55 char DSOLOCAL *msre_ruleset_rule_update_target_matching_exception(modsec_rec *msr, msre_ruleset *ruleset, rule_exception *re,
56     const char *p2, const char *p3);
57 
58 char DSOLOCAL *msre_ruleset_phase_rule_update_target_matching_exception(modsec_rec *msr, msre_ruleset *ruleset, rule_exception *re,
59      apr_array_header_t *phase_arr, const char *p2, const char *p3);
60 
61 apr_status_t DSOLOCAL collection_original_setvar(modsec_rec *msr, const char *col_name, const msc_string *orig_var);
62 
63 int DSOLOCAL expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t *mptmp);
64 
65 msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
66 
67 msre_var DSOLOCAL *msre_create_var_ex(apr_pool_t *pool, msre_engine *engine, const char *name, const char *param,
68     modsec_rec *msr, char **error_msg);
69 
70 int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
71     char **error_msg);
72 
73 int DSOLOCAL rule_id_in_range(int ruleid, const char *range);
74 
75 msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
76     msre_rule *rule, apr_pool_t *mptmp);
77 
78 #if defined(WITH_LUA)
79 apr_table_t DSOLOCAL *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
80     msre_rule *rule, apr_pool_t *mptmp);
81 #endif
82 
83 /* Structures with the corresponding functions */
84 
85 struct msre_engine {
86     apr_pool_t              *mp;
87     apr_table_t             *variables;
88     apr_table_t             *operators;
89     apr_table_t             *actions;
90     apr_table_t             *tfns;
91     apr_table_t             *reqbody_processors;
92 };
93 
94 msre_engine DSOLOCAL *msre_engine_create(apr_pool_t *parent_pool);
95 
96 void DSOLOCAL msre_engine_destroy(msre_engine *engine);
97 
98 msre_op_metadata DSOLOCAL *msre_engine_op_resolve(msre_engine *engine, const char *name);
99 
100 struct msre_ruleset {
101     apr_pool_t              *mp;
102     msre_engine             *engine;
103 
104     apr_array_header_t      *phase_request_headers;
105     apr_array_header_t      *phase_request_body;
106     apr_array_header_t      *phase_response_headers;
107     apr_array_header_t      *phase_response_body;
108     apr_array_header_t      *phase_logging;
109 };
110 
111 apr_status_t DSOLOCAL msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr);
112 
113 apr_status_t DSOLOCAL msre_ruleset_process_phase_internal(msre_ruleset *ruleset, modsec_rec *msr);
114 
115 msre_ruleset DSOLOCAL *msre_ruleset_create(msre_engine *engine, apr_pool_t *mp);
116 
117 int DSOLOCAL msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase);
118 
119 msre_rule DSOLOCAL *msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id, int offset);
120 
121 int DSOLOCAL msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re);
122 
123 /*
124 int DSOLOCAL msre_ruleset_phase_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re,
125     apr_array_header_t *phase_arr);
126 */
127 
128 #define RULE_NO_MATCH           0
129 #define RULE_MATCH              1
130 
131 #define RULE_PH_NONE            0  /* Not a placeholder */
132 #define RULE_PH_SKIPAFTER       1  /* Implicit placeholder for skipAfter */
133 #define RULE_PH_MARKER          2  /* Explicit placeholder for SecMarker */
134 
135 #define RULE_TYPE_NORMAL        0  /* SecRule */
136 #define RULE_TYPE_ACTION        1  /* SecAction */
137 #define RULE_TYPE_MARKER        2  /* SecMarker */
138 #if defined(WITH_LUA)
139 #define RULE_TYPE_LUA           3  /* SecRuleScript */
140 #endif
141 
142 struct msre_rule {
143     apr_array_header_t      *targets;
144     const char              *op_name;
145     const char              *op_param;
146     void                    *op_param_data;
147     msre_op_metadata        *op_metadata;
148     unsigned int             op_negated;
149     msre_actionset          *actionset;
150     const char              *p1;
151     const char              *unparsed;
152     const char              *filename;
153     int                      line_num;
154     int                      placeholder;
155     int                      type;
156 
157     msre_ruleset            *ruleset;
158     msre_rule               *chain_starter;
159     #if defined(PERFORMANCE_MEASUREMENT)
160     unsigned int             execution_time;
161     unsigned int             trans_time;
162     unsigned int             op_time;
163     #endif
164 
165     #if defined(WITH_LUA)
166     /* Compiled Lua script. */
167     msc_script              *script;
168     #endif
169 
170 #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 0
171     ap_regex_t              *sub_regex;
172 #else
173     regex_t                 *sub_regex;
174 #endif
175     char                    *sub_str;
176     char                    *re_str;
177     int                     re_precomp;
178     int                     escape_re;
179 
180     TreeRoot                *ip_op;
181 };
182 
183 char DSOLOCAL *msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, const char *targets, const char *args, const char *actions);
184 
185 msre_rule DSOLOCAL *msre_rule_create(msre_ruleset *ruleset, int type,
186     const char *fn, int line, const char *targets,
187     const char *args, const char *actions, char **error_msg);
188 
189 #if defined(WITH_LUA)
190 msre_rule DSOLOCAL *msre_rule_lua_create(msre_ruleset *ruleset,
191     const char *fn, int line, const char *script_filename,
192     const char *actions, char **error_msg);
193 #endif
194 
195 #define VAR_SIMPLE              0    /* REQUEST_URI */
196 #define VAR_LIST                1
197 
198 #define PHASE_REQUEST_HEADERS   1
199 #define PHASE_REQUEST_BODY      2
200 #define PHASE_RESPONSE_HEADERS  3
201 #define PHASE_RESPONSE_BODY     4
202 #define PHASE_LOGGING           5
203 
204 typedef int (*fn_op_param_init_t)(msre_rule *rule, char **error_msg);
205 typedef int (*fn_op_execute_t)(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg);
206 
207 struct msre_op_metadata {
208     const char              *name;
209     fn_op_param_init_t       param_init;
210     fn_op_execute_t          execute;
211 };
212 
213 typedef int (*fn_tfn_execute_t)(apr_pool_t *pool, unsigned char *input, long int input_length, char **rval, long int *rval_length);
214 
215 struct msre_tfn_metadata {
216     const char              *name;
217 
218     /* Functions should populate *rval and return 1 on
219      * success, or return -1 on failure (in which case *rval
220      * should contain the error message. Strict functions
221      * (those that validate in
222      * addition to transforming) can return 0 when input
223      * fails validation. Functions are free to perform
224      * in-place transformation, or to allocate a new buffer
225      * from the provideded temporary (per-rule) memory pool.
226      *
227      * NOTE Strict transformation functions not supported yet.
228      */
229     fn_tfn_execute_t execute;
230 };
231 
232 void DSOLOCAL msre_engine_tfn_register(msre_engine *engine, const char *name,
233     fn_tfn_execute_t execute);
234 
235 void DSOLOCAL msre_engine_op_register(msre_engine *engine, const char *name,
236     fn_op_param_init_t fn1, fn_op_execute_t fn2);
237 
238 void DSOLOCAL msre_engine_register_default_tfns(msre_engine *engine);
239 
240 void DSOLOCAL msre_engine_register_default_variables(msre_engine *engine);
241 
242 void DSOLOCAL msre_engine_register_default_operators(msre_engine *engine);
243 
244 void DSOLOCAL msre_engine_register_default_actions(msre_engine *engine);
245 
246 msre_tfn_metadata DSOLOCAL *msre_engine_tfn_resolve(msre_engine *engine, const char *name);
247 
248 #define VAR_DONT_CACHE  0
249 #define VAR_CACHE       1
250 
251 typedef char *(*fn_var_validate_t)(msre_ruleset *ruleset, msre_var *var);
252 typedef int (*fn_var_generate_t)(modsec_rec *msr, msre_var *var, msre_rule *rule, apr_table_t *table, apr_pool_t *mptmp);
253 
254 struct msre_var_metadata {
255     const char              *name;
256     unsigned int             type;          /* VAR_TYPE_ constants */
257     unsigned int             argc_min;
258     unsigned int             argc_max;
259     fn_var_validate_t        validate;
260     fn_var_generate_t        generate;
261     unsigned int             is_cacheable;  /* 0 - no, 1 - yes */
262     unsigned int             availability;  /* when does this variable become available? */
263 };
264 
265 struct msre_var {
266     char                    *name;
267     const char              *value;
268     unsigned int             value_len;
269     char                    *param;
270     const void              *param_data;
271     msre_var_metadata       *metadata;
272     msc_regex_t             *param_regex;
273     unsigned int             is_negated;
274     unsigned int             is_counting;
275 };
276 
277 
278 struct msre_actionset {
279     apr_table_t             *actions;
280 
281     /* Metadata */
282     const char              *id;
283     const char              *rev;
284     const char              *msg;
285     const char              *logdata;
286     const char              *version;
287     int                      maturity;
288     int                      accuracy;
289     int                      severity;
290     int                      phase;
291     msre_rule               *rule;
292     int                     arg_min;
293     int                     arg_max;
294 
295     /* Flow */
296     int                      is_chained;
297     int                      skip_count;
298     const char              *skip_after;
299 
300     /* Disruptive */
301     int                      intercept_action;
302     const char              *intercept_uri;
303     int                      intercept_status;
304     const char              *intercept_pause;
305 
306     /* "block" needs parent action to reset it */
307     msre_action             *parent_intercept_action_rec;
308     msre_action             *intercept_action_rec;
309     int                      parent_intercept_action;
310 
311     /* Other */
312     int                      log;
313     int                      auditlog;
314     int                      block;
315 };
316 
317 void DSOLOCAL msre_engine_variable_register(msre_engine *engine, const char *name,
318     unsigned int type, unsigned int argc_min, unsigned int argc_max,
319     fn_var_validate_t validate, fn_var_generate_t generate,
320     unsigned int is_cacheable, unsigned int availability);
321 
322 msre_actionset DSOLOCAL *msre_actionset_create(msre_engine *engine, apr_pool_t *mp, const char *text,
323     char **error_msg);
324 
325 msre_actionset DSOLOCAL *msre_actionset_merge(msre_engine *engine, apr_pool_t *mp, msre_actionset *parent,
326     msre_actionset *child, int inherit_by_default);
327 
328 msre_actionset DSOLOCAL *msre_actionset_create_default(msre_engine *engine);
329 
330 void DSOLOCAL msre_actionset_set_defaults(msre_actionset *actionset);
331 
332 void DSOLOCAL msre_actionset_init(msre_actionset *actionset, msre_rule *rule);
333 
334 typedef char *(*fn_action_validate_t)(msre_engine *engine, apr_pool_t *mp, msre_action *action);
335 typedef apr_status_t (*fn_action_init_t)(msre_engine *engine, apr_pool_t *mp, msre_actionset *actionset, msre_action *action);
336 typedef apr_status_t (*fn_action_execute_t)(modsec_rec *msr, apr_pool_t *mptmp, msre_rule *rule, msre_action *action);
337 
338 #define ACTION_DISRUPTIVE       1
339 #define ACTION_NON_DISRUPTIVE   2
340 #define ACTION_METADATA         3
341 #define ACTION_FLOW             4
342 
343 #define NO_PLUS_MINUS           0
344 #define ALLOW_PLUS_MINUS        1
345 
346 #define ACTION_CARDINALITY_ONE  1
347 #define ACTION_CARDINALITY_MANY 2
348 
349 #define ACTION_CGROUP_NONE       0
350 #define ACTION_CGROUP_DISRUPTIVE 1
351 #define ACTION_CGROUP_LOG        2
352 #define ACTION_CGROUP_AUDITLOG   3
353 
354 struct msre_action_metadata {
355     const char              *name;
356     unsigned int             type;
357     unsigned int             argc_min;
358     unsigned int             argc_max;
359     unsigned int             allow_param_plusminus;
360     unsigned int             cardinality;
361     unsigned int             cardinality_group;
362     fn_action_validate_t     validate;
363     fn_action_init_t         init;
364     fn_action_execute_t      execute;
365 };
366 
367 struct msre_action {
368     msre_action_metadata    *metadata;
369     const char              *param;
370     const void              *param_data;
371     unsigned int             param_plusminus; /* ABSOLUTE_VALUE, POSITIVE_VALUE, NEGATIVE_VALUE */
372 };
373 
374 void DSOLOCAL msre_engine_reqbody_processor_register(msre_engine *engine,
375     const char *name, void *fn_init, void *fn_process, void *fn_complete);
376 
377 typedef int (*fn_reqbody_processor_init_t)(modsec_rec *msr, char **error_msg);
378 typedef int (*fn_reqbody_processor_process_t)(modsec_rec *msr, const char *buf,
379             unsigned int size, char **error_msg);
380 typedef int (*fn_reqbody_processor_complete_t)(modsec_rec *msr, char **error_msg);
381 
382 struct msre_reqbody_processor_metadata {
383     const char                       *name;
384     fn_reqbody_processor_init_t       init;
385     fn_reqbody_processor_process_t    process;
386     fn_reqbody_processor_complete_t   complete;
387 };
388 
389 /* -- MSRE Function Prototypes ---------------------------------------------- */
390 
391 msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
392 
393 int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
394     char **error_msg);
395 
396 apr_status_t DSOLOCAL msre_parse_vars(msre_ruleset *ruleset, const char *text,
397     apr_array_header_t *arr, char **error_msg);
398 
399 char DSOLOCAL *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset);
400 
401 /* -- Data Cache -- */
402 
403 struct msre_cache_rec {
404     int                      hits;
405     int                      changed;
406     int                      num;
407     const char              *path;
408     const char              *val;
409     apr_size_t               val_len;
410 };
411 
412 struct fuzzy_hash_chunk {
413     const char *data;
414     struct fuzzy_hash_chunk *next;
415 };
416 
417 struct fuzzy_hash_param_data {
418     const char *file;
419     struct fuzzy_hash_chunk *head;
420     int threshold;
421 };
422 
423 #endif
424