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