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