2 * ModSecurity for Apache 2.x, http://www.modsecurity.org/
3 * Copyright (c) 2004-2009 Breach Security, Inc. (http://www.breach.com/)
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.
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
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.
22 #define ABSOLUTE_VALUE 0
23 #define POSITIVE_VALUE 1
24 #define NEGATIVE_VALUE 2
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;
39 #include "apr_general.h"
40 #include "apr_tables.h"
41 #include "modsecurity.h"
43 #include "persist_dbm.h"
50 /* Actions, variables, functions and operator functions */
52 apr_status_t DSOLOCAL collection_original_setvar(modsec_rec *msr, const char *col_name, const msc_string *orig_var);
54 int DSOLOCAL expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t *mptmp);
56 apr_status_t DSOLOCAL msre_parse_targets(msre_ruleset *ruleset, const char *text,
57 apr_array_header_t *arr, char **error_msg);
59 apr_status_t DSOLOCAL msre_parse_actions(msre_engine *engine, msre_actionset *actionset,
60 const char *text, char **error_msg);
62 msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
64 msre_action_metadata DSOLOCAL *msre_resolve_action(msre_engine *engine, const char *name);
66 msre_var DSOLOCAL *msre_create_var(msre_ruleset *ruleset, const char *name, const char *param,
67 modsec_rec *msr, char **error_msg);
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);
72 msre_action DSOLOCAL *msre_create_action(msre_engine *engine, const char *name,
73 const char *param, char **error_msg);
75 int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
78 int DSOLOCAL rule_id_in_range(int ruleid, const char *range);
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);
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);
86 /* Structures with the corresponding functions */
90 apr_table_t *variables;
91 apr_table_t *operators;
96 msre_engine DSOLOCAL *msre_engine_create(apr_pool_t *parent_pool);
98 void DSOLOCAL msre_engine_destroy(msre_engine *engine);
100 msre_op_metadata DSOLOCAL *msre_engine_op_resolve(msre_engine *engine, const char *name);
102 struct msre_ruleset {
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;
113 apr_status_t DSOLOCAL msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr);
115 apr_status_t DSOLOCAL msre_ruleset_process_phase_internal(msre_ruleset *ruleset, modsec_rec *msr);
117 msre_ruleset DSOLOCAL *msre_ruleset_create(msre_engine *engine, apr_pool_t *mp);
119 int DSOLOCAL msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase);
121 msre_rule DSOLOCAL *msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id);
123 int DSOLOCAL msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re);
126 int DSOLOCAL msre_ruleset_phase_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re,
127 apr_array_header_t *phase_arr);
130 #define RULE_NO_MATCH 0
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 */
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 */
145 apr_array_header_t *targets;
147 const char *op_param;
149 msre_op_metadata *op_metadata;
150 unsigned int op_negated;
151 msre_actionset *actionset;
153 const char *unparsed;
154 const char *filename;
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;
167 #if defined(WITH_LUA)
168 /* Compiled Lua script. */
173 char DSOLOCAL *msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, const char *targets, const char *args, const char *actions);
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);
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);
185 apr_status_t DSOLOCAL msre_rule_process(msre_rule *rule, modsec_rec *msr);
187 #define VAR_SIMPLE 0 /* REQUEST_URI */
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
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);
199 struct msre_op_metadata {
201 fn_op_param_init_t param_init;
202 fn_op_execute_t execute;
205 typedef int (*fn_tfn_execute_t)(apr_pool_t *pool, unsigned char *input, long int input_length, char **rval, long int *rval_length);
207 struct msre_tfn_metadata {
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.
219 * NOTE Strict transformation functions not supported yet.
221 fn_tfn_execute_t execute;
224 void DSOLOCAL msre_engine_tfn_register(msre_engine *engine, const char *name,
225 fn_tfn_execute_t execute);
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);
230 void DSOLOCAL msre_engine_register_default_tfns(msre_engine *engine);
232 void DSOLOCAL msre_engine_register_default_variables(msre_engine *engine);
234 void DSOLOCAL msre_engine_register_default_operators(msre_engine *engine);
236 void DSOLOCAL msre_engine_register_default_actions(msre_engine *engine);
238 msre_tfn_metadata DSOLOCAL *msre_engine_tfn_resolve(msre_engine *engine, const char *name);
240 #define VAR_DONT_CACHE 0
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);
246 struct msre_var_metadata {
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? */
260 unsigned int value_len;
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;
270 struct msre_actionset {
271 apr_table_t *actions;
285 const char *skip_after;
288 int intercept_action;
289 const char *intercept_uri;
290 int intercept_status;
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;
304 char DSOLOCAL *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actionset *actionset);
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);
311 msre_actionset DSOLOCAL *msre_actionset_create(msre_engine *engine, const char *text,
314 msre_actionset DSOLOCAL *msre_actionset_merge(msre_engine *engine, msre_actionset *parent,
315 msre_actionset *child, int inherit_by_default);
317 msre_actionset DSOLOCAL *msre_actionset_create_default(msre_engine *engine);
319 void DSOLOCAL msre_actionset_set_defaults(msre_actionset *actionset);
321 void DSOLOCAL msre_actionset_init(msre_actionset *actionset, msre_rule *rule);
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);
327 #define ACTION_DISRUPTIVE 1
328 #define ACTION_NON_DISRUPTIVE 2
329 #define ACTION_METADATA 3
330 #define ACTION_FLOW 4
332 #define NO_PLUS_MINUS 0
333 #define ALLOW_PLUS_MINUS 1
335 #define ACTION_CARDINALITY_ONE 1
336 #define ACTION_CARDINALITY_MANY 2
338 #define ACTION_CGROUP_NONE 0
339 #define ACTION_CGROUP_DISRUPTIVE 1
340 #define ACTION_CGROUP_LOG 2
341 #define ACTION_CGROUP_AUDITLOG 3
343 struct msre_action_metadata {
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;
357 msre_action_metadata *metadata;
359 const void *param_data;
360 unsigned int param_plusminus; /* ABSOLUTE_VALUE, POSITIVE_VALUE, NEGATIVE_VALUE */
363 /* -- MSRE Function Prototypes ---------------------------------------------- */
365 msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
367 int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
370 apr_status_t DSOLOCAL msre_parse_vars(msre_ruleset *ruleset, const char *text,
371 apr_array_header_t *arr, char **error_msg);
373 char DSOLOCAL *msre_format_metadata(modsec_rec *msr, msre_actionset *actionset);
376 /* -- Data Cache -- */
378 struct msre_cache_rec {