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.
19 #include "http_core.h"
21 #include "modsecurity.h"
26 #include "libxml/xpathInternals.h"
29 * Generates a variable from a string and a length.
31 static int var_simple_generate_ex(msre_var *var, apr_table_t *vartab, apr_pool_t *mptmp,
32 const char *value, int value_len)
34 msre_var *rvar = NULL;
36 if (value == NULL) return 0;
38 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
40 rvar->value_len = value_len;
41 apr_table_addn(vartab, rvar->name, (void *)rvar);
47 * Generates a variable from a NULL-terminated string.
49 static int var_simple_generate(msre_var *var, apr_table_t *vartab, apr_pool_t *mptmp,
52 if (value == NULL) return 0;
53 return var_simple_generate_ex(var, vartab, mptmp, value, strlen(value));
57 * Validate that a target parameter is valid. We only need to take
58 * care of the case when the parameter is a regular expression.
60 static char *var_generic_list_validate(msre_ruleset *ruleset, msre_var *var) {
61 /* It's OK if there's no parameter. */
62 if (var->param == NULL) return NULL;
64 /* Is it a regular expression? */
65 if ((strlen(var->param) > 2)&&(var->param[0] == '/')
66 &&(var->param[strlen(var->param) - 1] == '/'))
68 msc_regex_t *regex = NULL;
69 const char *errptr = NULL;
70 const char *pattern = NULL;
73 pattern = apr_pstrmemdup(ruleset->mp, var->param + 1, strlen(var->param + 1) - 1);
74 if (pattern == NULL) return FATAL_ERROR;
76 regex = msc_pregcomp(ruleset->mp, pattern, PCRE_DOTALL | PCRE_CASELESS | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
78 return apr_psprintf(ruleset->mp, "Error compiling pattern (offset %d): %s",
82 /* Store the compiled regex for later. */
83 var->param_data = regex;
90 /* Custom parameter validation functions */
94 static int var_args_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
95 apr_table_t *vartab, apr_pool_t *mptmp)
97 const apr_array_header_t *arr = NULL;
98 const apr_table_entry_t *te = NULL;
101 /* Loop through the arguments. */
102 arr = apr_table_elts(msr->arguments);
103 te = (apr_table_entry_t *)arr->elts;
104 for (i = 0; i < arr->nelts; i++) {
105 msc_arg *arg = (msc_arg *)te[i].val;
108 /* Figure out if we want to include this argument. */
109 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
111 if (var->param_data != NULL) { /* Regex. */
112 char *my_error_msg = NULL;
113 /* Run the regex against the argument name. */
114 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
115 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
116 } else { /* Simple comparison. */
117 if (strcasecmp(arg->name, var->param) == 0) match = 1;
121 /* If we had a match add this argument to the collection. */
123 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
125 rvar->value = arg->value;
126 rvar->value_len = arg->value_len;
127 rvar->name = apr_psprintf(mptmp, "ARGS:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
128 apr_table_addn(vartab, rvar->name, (void *)rvar);
137 /* ARGS_COMBINED_SIZE */
139 static int var_args_combined_size_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
140 apr_table_t *vartab, apr_pool_t *mptmp)
142 const apr_array_header_t *arr = NULL;
143 const apr_table_entry_t *te = NULL;
144 unsigned int combined_size = 0;
146 msre_var *rvar = NULL;
148 arr = apr_table_elts(msr->arguments);
149 te = (apr_table_entry_t *)arr->elts;
150 for (i = 0; i < arr->nelts; i++) {
151 msc_arg *arg = (msc_arg *)te[i].val;
152 combined_size += arg->name_len;
153 combined_size += arg->value_len;
156 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
157 rvar->value = apr_psprintf(mptmp, "%u", combined_size);
158 rvar->value_len = strlen(rvar->value);
159 apr_table_addn(vartab, rvar->name, (void *)rvar);
166 static int var_args_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
167 apr_table_t *vartab, apr_pool_t *mptmp)
169 const apr_array_header_t *arr = NULL;
170 const apr_table_entry_t *te = NULL;
173 arr = apr_table_elts(msr->arguments);
174 te = (apr_table_entry_t *)arr->elts;
175 for (i = 0; i < arr->nelts; i++) {
176 msc_arg *arg = (msc_arg *)te[i].val;
179 /* Figure out if we want to include this variable. */
180 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
182 if (var->param_data != NULL) { /* Regex. */
183 char *my_error_msg = NULL;
184 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
185 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
186 } else { /* Simple comparison. */
187 if (strcasecmp(arg->name, var->param) == 0) match = 1;
191 /* If we had a match add this argument to the collection. */
193 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
195 rvar->value = arg->name;
196 rvar->value_len = arg->name_len;
197 rvar->name = apr_psprintf(mptmp, "ARGS_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
198 apr_table_addn(vartab, rvar->name, (void *)rvar);
209 static int var_args_get_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
210 apr_table_t *vartab, apr_pool_t *mptmp)
212 const apr_array_header_t *arr = NULL;
213 const apr_table_entry_t *te = NULL;
216 /* Loop through the arguments. */
217 arr = apr_table_elts(msr->arguments);
218 te = (apr_table_entry_t *)arr->elts;
219 for (i = 0; i < arr->nelts; i++) {
220 msc_arg *arg = (msc_arg *)te[i].val;
223 /* Only QUERY_STRING arguments */
224 if (strcmp("QUERY_STRING", arg->origin) != 0) continue;
226 /* Figure out if we want to include this argument. */
227 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
229 if (var->param_data != NULL) { /* Regex. */
230 char *my_error_msg = NULL;
231 /* Run the regex against the argument name. */
232 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
233 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
234 } else { /* Simple comparison. */
235 if (strcasecmp(arg->name, var->param) == 0) match = 1;
239 /* If we had a match add this argument to the collection. */
241 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
243 rvar->value = arg->value;
244 rvar->value_len = arg->value_len;
245 rvar->name = apr_psprintf(mptmp, "ARGS_GET:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
246 apr_table_addn(vartab, rvar->name, (void *)rvar);
257 static int var_args_get_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
258 apr_table_t *vartab, apr_pool_t *mptmp)
260 const apr_array_header_t *arr = NULL;
261 const apr_table_entry_t *te = NULL;
264 arr = apr_table_elts(msr->arguments);
265 te = (apr_table_entry_t *)arr->elts;
266 for (i = 0; i < arr->nelts; i++) {
267 msc_arg *arg = (msc_arg *)te[i].val;
270 /* Only QUERY_STRING arguments */
271 if (strcmp("QUERY_STRING", arg->origin) != 0) continue;
273 /* Figure out if we want to include this variable. */
274 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
276 if (var->param_data != NULL) { /* Regex. */
277 char *my_error_msg = NULL;
278 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
279 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
280 } else { /* Simple comparison. */
281 if (strcasecmp(arg->name, var->param) == 0) match = 1;
285 /* If we had a match add this argument to the collection. */
287 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
289 rvar->value = arg->name;
290 rvar->value_len = arg->name_len;
291 rvar->name = apr_psprintf(mptmp, "ARGS_GET_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
292 apr_table_addn(vartab, rvar->name, (void *)rvar);
303 static int var_args_post_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
304 apr_table_t *vartab, apr_pool_t *mptmp)
306 const apr_array_header_t *arr = NULL;
307 const apr_table_entry_t *te = NULL;
310 /* Loop through the arguments. */
311 arr = apr_table_elts(msr->arguments);
312 te = (apr_table_entry_t *)arr->elts;
313 for (i = 0; i < arr->nelts; i++) {
314 msc_arg *arg = (msc_arg *)te[i].val;
317 /* Only BODY arguments */
318 if (strcmp("BODY", arg->origin) != 0) continue;
320 /* Figure out if we want to include this argument. */
321 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
323 if (var->param_data != NULL) { /* Regex. */
324 char *my_error_msg = NULL;
325 /* Run the regex against the argument name. */
326 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
327 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
328 } else { /* Simple comparison. */
329 if (strcasecmp(arg->name, var->param) == 0) match = 1;
333 /* If we had a match add this argument to the collection. */
335 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
337 rvar->value = arg->value;
338 rvar->value_len = arg->value_len;
339 rvar->name = apr_psprintf(mptmp, "ARGS_POST:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
340 apr_table_addn(vartab, rvar->name, (void *)rvar);
349 /* ARGS_POST_NAMES */
351 static int var_args_post_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
352 apr_table_t *vartab, apr_pool_t *mptmp)
354 const apr_array_header_t *arr = NULL;
355 const apr_table_entry_t *te = NULL;
358 arr = apr_table_elts(msr->arguments);
359 te = (apr_table_entry_t *)arr->elts;
360 for (i = 0; i < arr->nelts; i++) {
361 msc_arg *arg = (msc_arg *)te[i].val;
364 /* Only BODY arguments */
365 if (strcmp("BODY", arg->origin) != 0) continue;
367 /* Figure out if we want to include this variable. */
368 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
370 if (var->param_data != NULL) { /* Regex. */
371 char *my_error_msg = NULL;
372 if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
373 arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
374 } else { /* Simple comparison. */
375 if (strcasecmp(arg->name, var->param) == 0) match = 1;
379 /* If we had a match add this argument to the collection. */
381 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
383 rvar->value = arg->name;
384 rvar->value_len = arg->name_len;
385 rvar->name = apr_psprintf(mptmp, "ARGS_POST_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
386 apr_table_addn(vartab, rvar->name, (void *)rvar);
397 static int var_rule_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
398 apr_table_t *vartab, apr_pool_t *mptmp)
400 msre_actionset *actionset = NULL;
402 if (rule == NULL) return 0;
403 actionset = rule->actionset;
404 if (rule->chain_starter != NULL) actionset = rule->chain_starter->actionset;
406 if ((strcasecmp(var->param, "id") == 0)&&(actionset->id != NULL)) {
407 return var_simple_generate(var, vartab, mptmp, actionset->id);
409 if ((strcasecmp(var->param, "rev") == 0)&&(actionset->rev != NULL)) {
410 return var_simple_generate(var, vartab, mptmp, actionset->rev);
412 if ((strcasecmp(var->param, "severity") == 0)&&(actionset->severity != -1)) {
413 char *value = apr_psprintf(mptmp, "%d", actionset->severity);
414 return var_simple_generate(var, vartab, mptmp, value);
416 if ((strcasecmp(var->param, "msg") == 0)&&(actionset->msg != NULL)) {
417 return var_simple_generate(var, vartab, mptmp, actionset->msg);
419 if ((strcasecmp(var->param, "logdata") == 0)&&(actionset->logdata != NULL)) {
420 return var_simple_generate(var, vartab, mptmp, actionset->logdata);
428 static char *var_env_validate(msre_ruleset *ruleset, msre_var *var) {
429 if (var->param == NULL) {
430 return apr_psprintf(ruleset->mp, "Parameter required for ENV.");
432 if ((strlen(var->param) > 2)&&(var->param[0] == '/')
433 &&(var->param[strlen(var->param) - 1] == '/'))
435 return apr_psprintf(ruleset->mp, "Regular expressions not supported in ENV.");
440 static int var_env_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
441 apr_table_t *vartab, apr_pool_t *mptmp)
443 char *value = get_env_var(msr->r, (char *)var->param);
445 return var_simple_generate(var, vartab, mptmp, value);
450 /* REQUEST_URI_RAW */
452 static int var_request_uri_raw_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
453 apr_table_t *vartab, apr_pool_t *mptmp)
455 return var_simple_generate(var, vartab, mptmp, msr->r->unparsed_uri);
460 static int var_request_uri_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
461 apr_table_t *vartab, apr_pool_t *mptmp) /* dynamic */
465 if (msr->r->parsed_uri.query == NULL) value = msr->r->parsed_uri.path;
466 else value = apr_pstrcat(mptmp, msr->r->parsed_uri.path, "?", msr->r->parsed_uri.query, NULL);
468 return var_simple_generate(var, vartab, mptmp, value);
471 /* REQBODY_PROCESSOR */
473 static int var_reqbody_processor_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
474 apr_table_t *vartab, apr_pool_t *mptmp)
476 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
478 if (msr->msc_reqbody_processor == NULL) {
479 rvar->value = apr_pstrdup(mptmp, "");
482 rvar->value = apr_pstrdup(mptmp, msr->msc_reqbody_processor);
483 rvar->value_len = strlen(rvar->value);
486 apr_table_addn(vartab, rvar->name, (void *)rvar);
493 static int var_reqbody_processor_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
494 apr_table_t *vartab, apr_pool_t *mptmp)
496 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
498 rvar->value = apr_psprintf(mptmp, "%d", msr->msc_reqbody_error);
499 rvar->value_len = strlen(rvar->value);
500 apr_table_addn(vartab, rvar->name, (void *)rvar);
505 /* REQBODY_ERROR_MSG */
507 static int var_reqbody_processor_error_msg_generate(modsec_rec *msr, msre_var *var,
508 msre_rule *rule, apr_table_t *vartab, apr_pool_t *mptmp)
510 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
512 if (msr->msc_reqbody_error_msg == NULL) {
513 rvar->value = apr_pstrdup(mptmp, "");
516 rvar->value = apr_psprintf(mptmp, "%s", msr->msc_reqbody_error_msg);
517 rvar->value_len = strlen(rvar->value);
520 apr_table_addn(vartab, rvar->name, (void *)rvar);
527 static char *var_xml_validate(msre_ruleset *ruleset, msre_var *var) {
528 /* It's OK if there's no parameter. */
529 if (var->param == NULL) return NULL;
531 /* ENH validate XPath expression in advance. */
536 static int var_xml_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
537 apr_table_t *vartab, apr_pool_t *mptmp)
539 const apr_array_header_t *tarr;
540 const apr_table_entry_t *telts;
541 xmlXPathContextPtr xpathCtx;
542 xmlXPathObjectPtr xpathObj;
544 const xmlChar* xpathExpr = NULL;
547 /* Is there an XML document tree at all? */
548 if ((msr->xml == NULL)||(msr->xml->doc == NULL)) {
549 /* Sorry, we've got nothing to give! */
553 if (var->param == NULL) {
554 /* Invocation without an XPath expression makes sense
555 * with functions that manipulate the document tree.
557 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
559 rvar->value = apr_pstrdup(mptmp, "[XML document tree]");
560 rvar->value_len = strlen(rvar->value);
561 apr_table_addn(vartab, rvar->name, (void *)rvar);
566 /* Process the XPath expression. */
569 xpathExpr = (const xmlChar*)var->param;
571 xpathCtx = xmlXPathNewContext(msr->xml->doc);
572 if (xpathCtx == NULL) {
573 msr_log(msr, 1, "XML: Unable to create new XPath context.");
577 /* Look through the actionset of the associated rule
578 * for the namespace information. Register them if any are found.
580 tarr = apr_table_elts(rule->actionset->actions);
581 telts = (const apr_table_entry_t*)tarr->elts;
582 for (i = 0; i < tarr->nelts; i++) {
583 msre_action *action = (msre_action *)telts[i].val;
585 if (strcasecmp(action->metadata->name, "xmlns") == 0) {
588 if (parse_name_eq_value(mptmp, action->param, &prefix, &href) < 0) return -1;
589 if ((prefix == NULL)||(href == NULL)) return -1;
591 if(xmlXPathRegisterNs(xpathCtx, (const xmlChar*)prefix, (const xmlChar*)href) != 0) {
592 msr_log(msr, 1, "Failed to register XML namespace href \"%s\" prefix \"%s\".",
593 log_escape(mptmp, prefix), log_escape(mptmp, href));
597 msr_log(msr, 4, "Registered XML namespace href \"%s\" prefix \"%s\".",
598 log_escape(mptmp, prefix), log_escape(mptmp, href));
602 /* Initialise XPath expression. */
603 xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
604 if (xpathObj == NULL) {
605 msr_log(msr, 1, "XML: Unable to evaluate xpath expression.");
606 xmlXPathFreeContext(xpathCtx);
610 /* Evaluate XPath expression. */
611 nodes = xpathObj->nodesetval;
613 xmlXPathFreeObject(xpathObj);
614 xmlXPathFreeContext(xpathCtx);
618 /* Create one variable for each node in the result. */
619 for(i = 0; i < nodes->nodeNr; i++) {
620 msre_var *rvar = NULL;
621 char *content = NULL;
623 content = (char *)xmlNodeGetContent(nodes->nodeTab[i]);
624 if (content != NULL) {
625 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
626 rvar->value = apr_pstrdup(mptmp, content);
628 rvar->value_len = strlen(rvar->value);
629 apr_table_addn(vartab, rvar->name, (void *)rvar);
635 xmlXPathFreeObject(xpathObj);
636 xmlXPathFreeContext(xpathCtx);
641 /* WEBSERVER_ERROR_LOG */
643 static int var_webserver_error_log_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
644 apr_table_t *vartab, apr_pool_t *mptmp)
646 msre_var *rvar = NULL;
649 for(i = 0; i < msr->error_messages->nelts; i++) {
650 error_message *em = (((error_message**)msr->error_messages->elts)[i]);
653 fem = format_error_log_message(mptmp, em);
655 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
656 rvar->value = apr_pstrdup(mptmp, fem);
657 rvar->value_len = strlen(rvar->value);
658 apr_table_addn(vartab, rvar->name, (void *)rvar);
669 static int var_remote_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
670 apr_table_t *vartab, apr_pool_t *mptmp)
672 return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
677 static int var_remote_host_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
678 apr_table_t *vartab, apr_pool_t *mptmp)
680 const char *value1 = ap_get_remote_host(msr->r->connection, msr->r->per_dir_config,
682 return var_simple_generate(var, vartab, mptmp, value1);
687 static int var_remote_port_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
688 apr_table_t *vartab, apr_pool_t *mptmp)
690 char *value = apr_psprintf(mptmp, "%u", msr->remote_port);
691 return var_simple_generate(var, vartab, mptmp, value);
696 static int var_remote_user_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
697 apr_table_t *vartab, apr_pool_t *mptmp)
699 return var_simple_generate(var, vartab, mptmp, msr->remote_user);
704 static int var_tx_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
705 apr_table_t *vartab, apr_pool_t *mptmp)
707 const apr_array_header_t *arr = NULL;
708 const apr_table_entry_t *te = NULL;
711 arr = apr_table_elts(msr->tx_vars);
712 te = (apr_table_entry_t *)arr->elts;
713 for (i = 0; i < arr->nelts; i++) {
714 msc_string *str = (msc_string *)te[i].val;
717 /* Figure out if we want to include this variable. */
719 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
721 if (var->param_data != NULL) { /* Regex. */
722 char *my_error_msg = NULL;
723 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
724 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
725 } else { /* Simple comparison. */
726 if (strcasecmp(str->name, var->param) == 0) match = 1;
730 /* If we had a match add this argument to the collection. */
732 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
734 rvar->value = str->value;
735 rvar->value_len = str->value_len;
736 rvar->name = apr_psprintf(mptmp, "TX:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
737 apr_table_addn(vartab, rvar->name, (void *)rvar);
748 static int var_geo_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
749 apr_table_t *vartab, apr_pool_t *mptmp)
751 const apr_array_header_t *arr = NULL;
752 const apr_table_entry_t *te = NULL;
755 arr = apr_table_elts(msr->geo_vars);
756 te = (apr_table_entry_t *)arr->elts;
757 for (i = 0; i < arr->nelts; i++) {
758 msc_string *str = (msc_string *)te[i].val;
761 /* Figure out if we want to include this variable. */
763 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
765 if (var->param_data != NULL) { /* Regex. */
766 char *my_error_msg = NULL;
767 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
768 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
769 } else { /* Simple comparison. */
770 if (strcasecmp(str->name, var->param) == 0) match = 1;
774 /* If we had a match add this argument to the collection. */
776 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
778 rvar->value = str->value;
779 rvar->value_len = str->value_len;
780 rvar->name = apr_psprintf(mptmp, "GEO:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
781 apr_table_addn(vartab, rvar->name, (void *)rvar);
790 /* HIGHEST_SEVERITY */
792 static int var_highest_severity_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
793 apr_table_t *vartab, apr_pool_t *mptmp)
795 return var_simple_generate(var, vartab, mptmp,
796 apr_psprintf(mptmp, "%d", msr->highest_severity));
801 static int var_ip_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
802 apr_table_t *vartab, apr_pool_t *mptmp)
804 const apr_array_header_t *arr = NULL;
805 const apr_table_entry_t *te = NULL;
807 apr_table_t *target_col = NULL;
809 target_col = (apr_table_t *)apr_table_get(msr->collections, "ip");
810 if (target_col == NULL) return 0;
812 arr = apr_table_elts(target_col);
813 te = (apr_table_entry_t *)arr->elts;
814 for (i = 0; i < arr->nelts; i++) {
815 msc_string *str = (msc_string *)te[i].val;
818 /* Figure out if we want to include this variable. */
820 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
822 if (var->param_data != NULL) { /* Regex. */
823 char *my_error_msg = NULL;
824 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
825 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
826 } else { /* Simple comparison. */
827 if (strcasecmp(str->name, var->param) == 0) match = 1;
831 /* If we had a match add this argument to the collection. */
833 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
835 rvar->value = str->value;
836 rvar->value_len = str->value_len;
837 rvar->name = apr_psprintf(mptmp, "IP:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
838 apr_table_addn(vartab, rvar->name, (void *)rvar);
849 static int var_matched_var_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
850 apr_table_t *vartab, apr_pool_t *mptmp)
852 return var_simple_generate_ex(var, vartab, mptmp,
854 msr->matched_var->value,
855 msr->matched_var->value_len),
856 msr->matched_var->value_len);
859 /* MATCHED_VAR_NAME */
861 static int var_matched_var_name_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
862 apr_table_t *vartab, apr_pool_t *mptmp)
864 return var_simple_generate_ex(var, vartab, mptmp,
866 msr->matched_var->name,
867 msr->matched_var->name_len),
868 msr->matched_var->name_len);
873 static int var_session_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
874 apr_table_t *vartab, apr_pool_t *mptmp)
876 const apr_array_header_t *arr = NULL;
877 const apr_table_entry_t *te = NULL;
879 apr_table_t *target_col = NULL;
881 target_col = (apr_table_t *)apr_table_get(msr->collections, "session");
882 if (target_col == NULL) return 0;
884 arr = apr_table_elts(target_col);
885 te = (apr_table_entry_t *)arr->elts;
886 for (i = 0; i < arr->nelts; i++) {
887 msc_string *str = (msc_string *)te[i].val;
890 /* Figure out if we want to include this variable. */
892 if (var->param == NULL) match = 1; /* Unconditional inclusion. */
894 if (var->param_data != NULL) { /* Regex. */
895 char *my_error_msg = NULL;
896 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
897 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
898 } else { /* Simple comparison. */
899 if (strcasecmp(str->name, var->param) == 0) match = 1;
903 /* If we had a match add this argument to the collection. */
905 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
907 rvar->value = str->value;
908 rvar->value_len = str->value_len;
909 rvar->name = apr_psprintf(mptmp, "SESSION:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
910 apr_table_addn(vartab, rvar->name, (void *)rvar);
921 static int var_user_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
922 apr_table_t *vartab, apr_pool_t *mptmp)
924 const apr_array_header_t *arr = NULL;
925 const apr_table_entry_t *te = NULL;
927 apr_table_t *target_col = NULL;
929 target_col = (apr_table_t *)apr_table_get(msr->collections, "user");
930 if (target_col == NULL) return 0;
932 arr = apr_table_elts(target_col);
933 te = (apr_table_entry_t *)arr->elts;
934 for (i = 0; i < arr->nelts; i++) {
935 msc_string *str = (msc_string *)te[i].val;
938 /* Figure out if we want to include this variable. */
940 if (var->param == NULL) match = 1; /* Unconditional match. */
942 if (var->param_data != NULL) { /* Regex. */
943 char *my_error_msg = NULL;
944 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
945 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
946 } else { /* Simple comparison. */
947 if (strcasecmp(str->name, var->param) == 0) match = 1;
951 /* If we had a match add this argument to the collection. */
953 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
955 rvar->value = str->value;
956 rvar->value_len = str->value_len;
957 rvar->name = apr_psprintf(mptmp, "USER:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
958 apr_table_addn(vartab, rvar->name, (void *)rvar);
969 static int var_global_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
970 apr_table_t *vartab, apr_pool_t *mptmp)
972 const apr_array_header_t *arr = NULL;
973 const apr_table_entry_t *te = NULL;
975 apr_table_t *target_col = NULL;
977 target_col = (apr_table_t *)apr_table_get(msr->collections, "global");
978 if (target_col == NULL) return 0;
980 arr = apr_table_elts(target_col);
981 te = (apr_table_entry_t *)arr->elts;
982 for (i = 0; i < arr->nelts; i++) {
983 msc_string *str = (msc_string *)te[i].val;
986 /* Figure out if we want to include this variable. */
988 if (var->param == NULL) match = 1; /* Unconditional match. */
990 if (var->param_data != NULL) { /* Regex. */
991 char *my_error_msg = NULL;
992 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
993 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
994 } else { /* Simple comparison. */
995 if (strcasecmp(str->name, var->param) == 0) match = 1;
999 /* If we had a match add this argument to the collection. */
1001 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1003 rvar->value = str->value;
1004 rvar->value_len = str->value_len;
1005 rvar->name = apr_psprintf(mptmp, "GLOBAL:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
1006 apr_table_addn(vartab, rvar->name, (void *)rvar);
1017 static int var_resource_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1018 apr_table_t *vartab, apr_pool_t *mptmp)
1020 const apr_array_header_t *arr = NULL;
1021 const apr_table_entry_t *te = NULL;
1023 apr_table_t *target_col = NULL;
1025 target_col = (apr_table_t *)apr_table_get(msr->collections, "resource");
1026 if (target_col == NULL) return 0;
1028 arr = apr_table_elts(target_col);
1029 te = (apr_table_entry_t *)arr->elts;
1030 for (i = 0; i < arr->nelts; i++) {
1031 msc_string *str = (msc_string *)te[i].val;
1034 /* Figure out if we want to include this variable. */
1036 if (var->param == NULL) match = 1; /* Unconditional match. */
1038 if (var->param_data != NULL) { /* Regex. */
1039 char *my_error_msg = NULL;
1040 if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
1041 str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1042 } else { /* Simple comparison. */
1043 if (strcasecmp(str->name, var->param) == 0) match = 1;
1047 /* If we had a match add this argument to the collection. */
1049 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1051 rvar->value = str->value;
1052 rvar->value_len = str->value_len;
1053 rvar->name = apr_psprintf(mptmp, "RESOURCE:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
1054 apr_table_addn(vartab, rvar->name, (void *)rvar);
1063 /* FILES_TMPNAMES */
1065 static int var_files_tmpnames_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1066 apr_table_t *vartab, apr_pool_t *mptmp)
1068 multipart_part **parts = NULL;
1071 if (msr->mpd == NULL) return 0;
1073 parts = (multipart_part **)msr->mpd->parts->elts;
1074 for(i = 0; i < msr->mpd->parts->nelts; i++) {
1075 if ((parts[i]->type == MULTIPART_FILE)&&(parts[i]->tmp_file_name != NULL)) {
1078 /* Figure out if we want to include this variable. */
1079 if (var->param == NULL) match = 1;
1081 if (var->param_data != NULL) { /* Regex. */
1082 char *my_error_msg = NULL;
1083 if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
1084 strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1085 } else { /* Simple comparison. */
1086 if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
1090 /* If we had a match add this argument to the collection. */
1092 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1094 rvar->value = parts[i]->tmp_file_name;
1095 rvar->value_len = strlen(rvar->value);
1096 rvar->name = apr_psprintf(mptmp, "FILES_TMPNAMES:%s",
1097 log_escape_nq(mptmp, parts[i]->name));
1098 apr_table_addn(vartab, rvar->name, (void *)rvar);
1110 static int var_files_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1111 apr_table_t *vartab, apr_pool_t *mptmp)
1113 multipart_part **parts = NULL;
1116 if (msr->mpd == NULL) return 0;
1118 parts = (multipart_part **)msr->mpd->parts->elts;
1119 for(i = 0; i < msr->mpd->parts->nelts; i++) {
1120 if (parts[i]->type == MULTIPART_FILE) {
1123 /* Figure out if we want to include this variable. */
1124 if (var->param == NULL) match = 1;
1126 if (var->param_data != NULL) { /* Regex. */
1127 char *my_error_msg = NULL;
1128 if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
1129 strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1130 } else { /* Simple comparison. */
1131 if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
1135 /* If we had a match add this argument to the collection. */
1137 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1139 rvar->value = parts[i]->filename;
1140 rvar->value_len = strlen(rvar->value);
1141 rvar->name = apr_psprintf(mptmp, "FILES:%s",
1142 log_escape_nq(mptmp, parts[i]->name));
1143 apr_table_addn(vartab, rvar->name, (void *)rvar);
1155 static int var_files_sizes_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1156 apr_table_t *vartab, apr_pool_t *mptmp)
1158 multipart_part **parts = NULL;
1161 if (msr->mpd == NULL) return 0;
1163 parts = (multipart_part **)msr->mpd->parts->elts;
1164 for(i = 0; i < msr->mpd->parts->nelts; i++) {
1165 if (parts[i]->type == MULTIPART_FILE) {
1168 /* Figure out if we want to include this variable. */
1169 if (var->param == NULL) match = 1;
1171 if (var->param_data != NULL) { /* Regex. */
1172 char *my_error_msg = NULL;
1173 if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
1174 strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1175 } else { /* Simple comparison. */
1176 if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
1180 /* If we had a match add this argument to the collection. */
1182 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1184 rvar->value = apr_psprintf(mptmp, "%u", parts[i]->tmp_file_size);
1185 rvar->value_len = strlen(rvar->value);
1186 rvar->name = apr_psprintf(mptmp, "FILES_SIZES:%s",
1187 log_escape_nq(mptmp, parts[i]->name));
1188 apr_table_addn(vartab, rvar->name, (void *)rvar);
1200 static int var_files_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1201 apr_table_t *vartab, apr_pool_t *mptmp)
1203 multipart_part **parts = NULL;
1206 if (msr->mpd == NULL) return 0;
1208 parts = (multipart_part **)msr->mpd->parts->elts;
1209 for(i = 0; i < msr->mpd->parts->nelts; i++) {
1210 if (parts[i]->type == MULTIPART_FILE) {
1211 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1213 rvar->value = parts[i]->name;
1214 rvar->value_len = strlen(rvar->value);
1215 rvar->name = apr_psprintf(mptmp, "FILES_NAMES:%s",
1216 log_escape_nq_ex(mptmp, parts[i]->name, rvar->value_len));
1217 apr_table_addn(vartab, rvar->name, (void *)rvar);
1226 /* FILES_COMBINED_SIZE */
1228 static int var_files_combined_size_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1229 apr_table_t *vartab, apr_pool_t *mptmp)
1231 multipart_part **parts = NULL;
1232 msre_var *rvar = NULL;
1233 unsigned int combined_size = 0;
1236 if (msr->mpd != NULL) {
1237 parts = (multipart_part **)msr->mpd->parts->elts;
1238 for(i = 0; i < msr->mpd->parts->nelts; i++) {
1239 if (parts[i]->type == MULTIPART_FILE) {
1240 combined_size += parts[i]->tmp_file_size;
1245 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1246 rvar->value = apr_psprintf(mptmp, "%u", combined_size);
1247 rvar->value_len = strlen(rvar->value);
1248 apr_table_addn(vartab, rvar->name, (void *)rvar);
1255 static int var_modsec_build_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1256 apr_table_t *vartab, apr_pool_t *mptmp)
1258 return var_simple_generate(var, vartab, mptmp, modsec_build(mptmp));
1261 /* MULTIPART_BOUNDARY_QUOTED */
1263 static int var_multipart_boundary_quoted_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1264 apr_table_t *vartab, apr_pool_t *mptmp)
1266 if ((msr->mpd != NULL)&&(msr->mpd->flag_boundary_quoted != 0)) {
1267 return var_simple_generate(var, vartab, mptmp, "1");
1269 return var_simple_generate(var, vartab, mptmp, "0");
1273 /* MULTIPART_BOUNDARY_WHITESPACE */
1275 static int var_multipart_boundary_whitespace_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1276 apr_table_t *vartab, apr_pool_t *mptmp)
1278 if ((msr->mpd != NULL)&&(msr->mpd->flag_boundary_whitespace != 0)) {
1279 return var_simple_generate(var, vartab, mptmp, "1");
1281 return var_simple_generate(var, vartab, mptmp, "0");
1285 /* MULTIPART_DATA_AFTER */
1287 static int var_multipart_data_after_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1288 apr_table_t *vartab, apr_pool_t *mptmp)
1290 if ((msr->mpd != NULL)&&(msr->mpd->flag_data_after != 0)) {
1291 return var_simple_generate(var, vartab, mptmp, "1");
1293 return var_simple_generate(var, vartab, mptmp, "0");
1297 /* MULTIPART_DATA_BEFORE */
1299 static int var_multipart_data_before_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1300 apr_table_t *vartab, apr_pool_t *mptmp)
1302 if ((msr->mpd != NULL)&&(msr->mpd->flag_data_before != 0)) {
1303 return var_simple_generate(var, vartab, mptmp, "1");
1305 return var_simple_generate(var, vartab, mptmp, "0");
1309 /* MULTIPART_HEADER_FOLDING */
1311 static int var_multipart_header_folding_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1312 apr_table_t *vartab, apr_pool_t *mptmp)
1314 if ((msr->mpd != NULL)&&(msr->mpd->flag_header_folding != 0)) {
1315 return var_simple_generate(var, vartab, mptmp, "1");
1317 return var_simple_generate(var, vartab, mptmp, "0");
1321 /* MULTIPART_CRLF_LINE */
1323 static int var_multipart_crlf_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1324 apr_table_t *vartab, apr_pool_t *mptmp)
1326 if ((msr->mpd != NULL)&&(msr->mpd->flag_crlf_line != 0)) {
1327 return var_simple_generate(var, vartab, mptmp, "1");
1329 return var_simple_generate(var, vartab, mptmp, "0");
1333 /* MULTIPART_CRLF_LF_LINES */
1335 static int var_multipart_crlf_lf_lines_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1336 apr_table_t *vartab, apr_pool_t *mptmp)
1338 if ((msr->mpd != NULL)&&(msr->mpd->flag_lf_line != 0)&&(msr->mpd->flag_crlf_line != 0)) {
1339 return var_simple_generate(var, vartab, mptmp, "1");
1341 return var_simple_generate(var, vartab, mptmp, "0");
1345 /* MULTIPART_LF_LINE */
1347 static int var_multipart_lf_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1348 apr_table_t *vartab, apr_pool_t *mptmp)
1350 if ((msr->mpd != NULL)&&(msr->mpd->flag_lf_line != 0)) {
1351 return var_simple_generate(var, vartab, mptmp, "1");
1353 return var_simple_generate(var, vartab, mptmp, "0");
1357 /* MULTIPART_MISSING_SEMICOLON */
1359 static int var_multipart_missing_semicolon_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1360 apr_table_t *vartab, apr_pool_t *mptmp)
1362 if ((msr->mpd != NULL)&&(msr->mpd->flag_missing_semicolon != 0)) {
1363 return var_simple_generate(var, vartab, mptmp, "1");
1365 return var_simple_generate(var, vartab, mptmp, "0");
1369 /* MULTIPART_INVALID_QUOTING */
1371 static int var_multipart_invalid_quoting_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1372 apr_table_t *vartab, apr_pool_t *mptmp)
1374 if ((msr->mpd != NULL)&&(msr->mpd->flag_invalid_quoting != 0)) {
1375 return var_simple_generate(var, vartab, mptmp, "1");
1377 return var_simple_generate(var, vartab, mptmp, "0");
1381 /* MULTIPART_STRICT_ERROR */
1383 static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1384 apr_table_t *vartab, apr_pool_t *mptmp)
1386 if (msr->mpd != NULL) {
1387 /* Respond positive if at least one of the multipart flags is raised. */
1388 if ( (msr->mpd->flag_error)
1389 ||(msr->mpd->flag_boundary_quoted != 0)
1390 ||(msr->mpd->flag_boundary_whitespace != 0)
1391 ||(msr->mpd->flag_data_before != 0)
1392 ||(msr->mpd->flag_data_after != 0)
1393 ||(msr->mpd->flag_header_folding != 0)
1394 ||(msr->mpd->flag_lf_line != 0)
1395 ||(msr->mpd->flag_missing_semicolon != 0)
1396 ||(msr->mpd->flag_invalid_quoting != 0)
1398 return var_simple_generate(var, vartab, mptmp, "1");
1402 return var_simple_generate(var, vartab, mptmp, "0");
1405 /* MULTIPART_UNMATCHED_BOUNDARY */
1407 static int var_multipart_unmatched_boundary_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1408 apr_table_t *vartab, apr_pool_t *mptmp)
1410 if ((msr->mpd != NULL)&&(msr->mpd->flag_unmatched_boundary != 0)) {
1411 return var_simple_generate(var, vartab, mptmp, "1");
1413 return var_simple_generate(var, vartab, mptmp, "0");
1419 static int var_time_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1420 apr_table_t *vartab, apr_pool_t *mptmp)
1422 msre_var *rvar = NULL;
1427 tm = localtime(&tc);
1428 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1429 rvar->value = apr_psprintf(mptmp, "%02d%02d%02d%02d%02d%02d%02d",
1430 (tm->tm_year / 100) + 19, (tm->tm_year % 100),
1431 tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
1433 rvar->value_len = strlen(rvar->value);
1434 apr_table_addn(vartab, rvar->name, (void *)rvar);
1441 static int var_time_year_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1442 apr_table_t *vartab, apr_pool_t *mptmp)
1444 msre_var *rvar = NULL;
1449 tm = localtime(&tc);
1450 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1451 rvar->value = apr_psprintf(mptmp, "%02d%02d",
1452 (tm->tm_year / 100) + 19,
1454 rvar->value_len = strlen(rvar->value);
1455 apr_table_addn(vartab, rvar->name, (void *)rvar);
1462 static int var_time_wday_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1463 apr_table_t *vartab, apr_pool_t *mptmp)
1465 msre_var *rvar = NULL;
1470 tm = localtime(&tc);
1471 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1472 rvar->value = apr_psprintf(mptmp, "%d", tm->tm_wday);
1473 rvar->value_len = strlen(rvar->value);
1474 apr_table_addn(vartab, rvar->name, (void *)rvar);
1481 static int var_time_sec_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1482 apr_table_t *vartab, apr_pool_t *mptmp)
1484 msre_var *rvar = NULL;
1489 tm = localtime(&tc);
1490 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1491 rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_sec);
1492 rvar->value_len = strlen(rvar->value);
1493 apr_table_addn(vartab, rvar->name, (void *)rvar);
1500 static int var_time_min_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1501 apr_table_t *vartab, apr_pool_t *mptmp)
1503 msre_var *rvar = NULL;
1508 tm = localtime(&tc);
1509 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1510 rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_min);
1511 rvar->value_len = strlen(rvar->value);
1512 apr_table_addn(vartab, rvar->name, (void *)rvar);
1518 static int var_time_hour_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1519 apr_table_t *vartab, apr_pool_t *mptmp)
1521 msre_var *rvar = NULL;
1526 tm = localtime(&tc);
1527 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1528 rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_hour);
1529 rvar->value_len = strlen(rvar->value);
1530 apr_table_addn(vartab, rvar->name, (void *)rvar);
1537 static int var_time_mon_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1538 apr_table_t *vartab, apr_pool_t *mptmp)
1540 msre_var *rvar = NULL;
1545 tm = localtime(&tc);
1546 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1547 rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_mon + 1);
1548 rvar->value_len = strlen(rvar->value);
1549 apr_table_addn(vartab, rvar->name, (void *)rvar);
1556 static int var_time_day_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1557 apr_table_t *vartab, apr_pool_t *mptmp)
1559 msre_var *rvar = NULL;
1564 tm = localtime(&tc);
1565 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1566 rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_mday);
1567 rvar->value_len = strlen(rvar->value);
1568 apr_table_addn(vartab, rvar->name, (void *)rvar);
1575 static int var_time_epoch_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1576 apr_table_t *vartab, apr_pool_t *mptmp)
1578 msre_var *rvar = NULL;
1583 tm = localtime(&tc);
1584 rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1585 rvar->value = apr_psprintf(mptmp, "%ld", (long)tc);
1586 rvar->value_len = strlen(rvar->value);
1587 apr_table_addn(vartab, rvar->name, (void *)rvar);
1594 static int var_query_string_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1595 apr_table_t *vartab, apr_pool_t *mptmp)
1597 return var_simple_generate(var, vartab, mptmp, msr->query_string);
1600 /* REQUEST_BASENAME */
1602 static int var_request_basename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1603 apr_table_t *vartab, apr_pool_t *mptmp)
1605 char *value = file_basename(mptmp, msr->r->parsed_uri.path);
1606 return var_simple_generate(var, vartab, mptmp, value);
1611 static int var_request_body_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1612 apr_table_t *vartab, apr_pool_t *mptmp)
1614 if (msr->msc_reqbody_buffer != NULL) {
1615 return var_simple_generate_ex(var, vartab, mptmp,
1616 msr->msc_reqbody_buffer, msr->msc_reqbody_length);
1621 /* REQUEST_COOKIES */
1623 static int var_request_cookies_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1624 apr_table_t *vartab, apr_pool_t *mptmp)
1626 const apr_array_header_t *arr = NULL;
1627 const apr_table_entry_t *te = NULL;
1630 arr = apr_table_elts(msr->request_cookies);
1631 te = (apr_table_entry_t *)arr->elts;
1632 for (i = 0; i < arr->nelts; i++) {
1635 /* Figure out if we want to include this variable. */
1636 if (var->param == NULL) match = 1;
1638 if (var->param_data != NULL) { /* Regex. */
1639 char *my_error_msg = NULL;
1640 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
1641 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1642 } else { /* Simple comparison. */
1643 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
1647 /* If we had a match add this argument to the collection. */
1649 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1651 rvar->value = te[i].val;
1652 rvar->value_len = strlen(rvar->value);
1653 rvar->name = apr_psprintf(mptmp, "REQUEST_COOKIES:%s",
1654 log_escape_nq(mptmp, te[i].key));
1655 apr_table_addn(vartab, rvar->name, (void *)rvar);
1664 /* REQUEST_COOKIES_NAMES */
1666 static int var_request_cookies_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1667 apr_table_t *vartab, apr_pool_t *mptmp)
1669 const apr_array_header_t *arr = NULL;
1670 const apr_table_entry_t *te = NULL;
1673 arr = apr_table_elts(msr->request_cookies);
1674 te = (apr_table_entry_t *)arr->elts;
1675 for (i = 0; i < arr->nelts; i++) {
1678 /* Figure out if we want to include this variable. */
1679 if (var->param == NULL) match = 1;
1681 if (var->param_data != NULL) { /* Regex. */
1682 char *my_error_msg = NULL;
1683 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
1684 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1685 } else { /* Simple comparison. */
1686 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
1690 /* If we had a match add this argument to the collection. */
1692 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1694 rvar->value = te[i].key;
1695 rvar->value_len = strlen(rvar->value);
1696 rvar->name = apr_psprintf(mptmp, "REQUEST_COOKIES_NAMES:%s",
1697 log_escape_nq(mptmp, te[i].key));
1698 apr_table_addn(vartab, rvar->name, (void *)rvar);
1707 /* REQUEST_HEADERS */
1709 static int var_request_headers_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1710 apr_table_t *vartab, apr_pool_t *mptmp)
1712 const apr_array_header_t *arr = NULL;
1713 const apr_table_entry_t *te = NULL;
1716 arr = apr_table_elts(msr->request_headers);
1717 te = (apr_table_entry_t *)arr->elts;
1718 for (i = 0; i < arr->nelts; i++) {
1721 /* Figure out if we want to include this variable. */
1722 if (var->param == NULL) match = 1;
1724 if (var->param_data != NULL) { /* Regex. */
1725 char *my_error_msg = NULL;
1726 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
1727 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1728 } else { /* Simple comparison. */
1729 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
1733 /* If we had a match add this argument to the collection. */
1735 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1737 rvar->value = te[i].val;
1738 rvar->value_len = strlen(rvar->value);
1739 rvar->name = apr_psprintf(mptmp, "REQUEST_HEADERS:%s",
1740 log_escape_nq(mptmp, te[i].key));
1741 apr_table_addn(vartab, rvar->name, (void *)rvar);
1750 /* REQUEST_HEADERS_NAMES */
1752 static int var_request_headers_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1753 apr_table_t *vartab, apr_pool_t *mptmp)
1755 const apr_array_header_t *arr = NULL;
1756 const apr_table_entry_t *te = NULL;
1759 arr = apr_table_elts(msr->request_headers);
1760 te = (apr_table_entry_t *)arr->elts;
1761 for (i = 0; i < arr->nelts; i++) {
1764 /* Figure out if we want to include this variable. */
1765 if (var->param == NULL) match = 1;
1767 if (var->param_data != NULL) { /* Regex. */
1768 char *my_error_msg = NULL;
1769 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
1770 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1771 } else { /* Simple comparison. */
1772 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
1776 /* If we had a match add this argument to the collection. */
1778 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1780 rvar->value = te[i].key;
1781 rvar->value_len = strlen(rvar->value);
1782 rvar->name = apr_psprintf(mptmp, "REQUEST_HEADERS_NAMES:%s",
1783 log_escape_nq(mptmp, te[i].key));
1784 apr_table_addn(vartab, rvar->name, (void *)rvar);
1793 /* REQUEST_FILENAME */
1795 static int var_request_filename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1796 apr_table_t *vartab, apr_pool_t *mptmp)
1798 return var_simple_generate(var, vartab, mptmp, msr->r->parsed_uri.path);
1803 static int var_request_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1804 apr_table_t *vartab, apr_pool_t *mptmp)
1806 return var_simple_generate(var, vartab, mptmp, msr->request_line);
1809 /* REQUEST_METHOD */
1811 static int var_request_method_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1812 apr_table_t *vartab, apr_pool_t *mptmp)
1814 return var_simple_generate(var, vartab, mptmp, msr->request_method);
1817 /* REQUEST_PROTOCOL */
1819 static int var_request_protocol_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1820 apr_table_t *vartab, apr_pool_t *mptmp)
1822 return var_simple_generate(var, vartab, mptmp, msr->request_protocol);
1827 static int var_server_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1828 apr_table_t *vartab, apr_pool_t *mptmp)
1830 return var_simple_generate(var, vartab, mptmp, msr->local_addr);
1835 static int var_server_name_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1836 apr_table_t *vartab, apr_pool_t *mptmp)
1838 return var_simple_generate(var, vartab, mptmp, msr->hostname);
1843 static int var_server_port_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1844 apr_table_t *vartab, apr_pool_t *mptmp)
1846 char *value = apr_psprintf(mptmp, "%u", msr->local_port);
1847 return var_simple_generate(var, vartab, mptmp, value);
1850 /* SCRIPT_BASENAME */
1852 static int var_script_basename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1853 apr_table_t *vartab, apr_pool_t *mptmp)
1855 char *value = file_basename(mptmp, msr->r->filename);
1856 return var_simple_generate(var, vartab, mptmp, value);
1859 /* SCRIPT_FILENAME */
1861 static int var_script_filename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1862 apr_table_t *vartab, apr_pool_t *mptmp)
1864 char *value = msr->r->filename;
1865 return var_simple_generate(var, vartab, mptmp, value);
1870 static int var_script_gid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1871 apr_table_t *vartab, apr_pool_t *mptmp)
1873 char *value = apr_psprintf(mptmp, "%ld", (long)msr->r->finfo.group);
1874 return var_simple_generate(var, vartab, mptmp, value);
1877 /* SCRIPT_GROUPNAME */
1879 static int var_script_groupname_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1880 apr_table_t *vartab, apr_pool_t *mptmp)
1883 if (apr_gid_name_get(&value, msr->r->finfo.group, mptmp) == APR_SUCCESS) {
1884 return var_simple_generate(var, vartab, mptmp, value);
1891 static int var_script_mode_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1892 apr_table_t *vartab, apr_pool_t *mptmp)
1894 char *value = apr_psprintf(mptmp, "%04x", msr->r->finfo.protection);
1895 return var_simple_generate(var, vartab, mptmp, value);
1900 static int var_script_uid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1901 apr_table_t *vartab, apr_pool_t *mptmp)
1903 char *value = apr_psprintf(mptmp, "%ld", (long)msr->r->finfo.user);
1904 return var_simple_generate(var, vartab, mptmp, value);
1907 /* SCRIPT_USERNAME */
1909 static int var_script_username_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1910 apr_table_t *vartab, apr_pool_t *mptmp)
1913 if (apr_uid_name_get(&value, msr->r->finfo.user, mptmp) == APR_SUCCESS) {
1914 return var_simple_generate(var, vartab, mptmp, value);
1921 static int var_auth_type_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1922 apr_table_t *vartab, apr_pool_t *mptmp)
1924 char *value = msr->r->ap_auth_type;
1925 return var_simple_generate(var, vartab, mptmp, value);
1930 static int var_path_info_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1931 apr_table_t *vartab, apr_pool_t *mptmp)
1933 const char *value = msr->r->path_info;
1934 return var_simple_generate(var, vartab, mptmp, value);
1939 static int var_response_body_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1940 apr_table_t *vartab, apr_pool_t *mptmp)
1942 if (msr->resbody_data != NULL) {
1943 return var_simple_generate_ex(var, vartab, mptmp,
1944 msr->resbody_data, msr->resbody_length);
1950 /* RESPONSE_HEADERS */
1952 static int var_response_headers_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1953 apr_table_t *vartab, apr_pool_t *mptmp)
1955 const apr_array_header_t *arr = NULL;
1956 const apr_table_entry_t *te = NULL;
1959 if (msr->response_headers == NULL) return 0;
1961 arr = apr_table_elts(msr->response_headers);
1962 te = (apr_table_entry_t *)arr->elts;
1963 for (i = 0; i < arr->nelts; i++) {
1966 /* Figure out if we want to include this variable. */
1967 if (var->param == NULL) match = 1;
1969 if (var->param_data != NULL) { /* Regex. */
1970 char *my_error_msg = NULL;
1971 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
1972 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
1973 } else { /* Simple comparison. */
1974 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
1978 /* If we had a match add this argument to the collection. */
1980 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
1982 rvar->value = te[i].val;
1983 rvar->value_len = strlen(rvar->value);
1984 rvar->name = apr_psprintf(mptmp, "RESPONSE_HEADERS:%s",
1985 log_escape_nq(mptmp, te[i].key));
1986 apr_table_addn(vartab, rvar->name, (void *)rvar);
1995 /* RESPONSE_HEADERS_NAMES */
1997 static int var_response_headers_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
1998 apr_table_t *vartab, apr_pool_t *mptmp)
2000 const apr_array_header_t *arr = NULL;
2001 const apr_table_entry_t *te = NULL;
2004 arr = apr_table_elts(msr->response_headers);
2005 te = (apr_table_entry_t *)arr->elts;
2006 for (i = 0; i < arr->nelts; i++) {
2009 /* Figure out if we want to include this variable. */
2010 if (var->param == NULL) match = 1;
2012 if (var->param_data != NULL) { /* Regex. */
2013 char *my_error_msg = NULL;
2014 if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
2015 strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
2016 } else { /* Simple comparison. */
2017 if (strcasecmp(te[i].key, var->param) == 0) match = 1;
2021 /* If we had a match add this argument to the collection. */
2023 msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
2025 rvar->value = te[i].key;
2026 rvar->value_len = strlen(rvar->value);
2027 rvar->name = apr_psprintf(mptmp, "RESPONSE_HEADERS_NAMES:%s",
2028 log_escape_nq(mptmp, te[i].key));
2029 apr_table_addn(vartab, rvar->name, (void *)rvar);
2040 static int var_status_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2041 apr_table_t *vartab, apr_pool_t *mptmp)
2043 const char *value = msr->status_line;
2044 return var_simple_generate(var, vartab, mptmp, value);
2047 /* RESPONSE_PROTOCOL */
2049 static int var_response_protocol_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2050 apr_table_t *vartab, apr_pool_t *mptmp)
2052 const char *value = msr->response_protocol;
2053 return var_simple_generate(var, vartab, mptmp, value);
2056 /* RESPONSE_STATUS */
2058 static int var_response_status_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2059 apr_table_t *vartab, apr_pool_t *mptmp)
2061 const char *value = apr_psprintf(mptmp, "%u", msr->response_status);
2062 return var_simple_generate(var, vartab, mptmp, value);
2065 /* RESPONSE_CONTENT_TYPE */
2067 static int var_response_content_type(modsec_rec *msr, msre_var *var, msre_rule *rule,
2068 apr_table_t *vartab, apr_pool_t *mptmp)
2070 return var_simple_generate(var, vartab, mptmp, msr->r->content_type);
2073 /* RESPONSE_CONTENT_LENGTH */
2075 static int var_response_content_length(modsec_rec *msr, msre_var *var, msre_rule *rule,
2076 apr_table_t *vartab, apr_pool_t *mptmp)
2078 const char *value = apr_psprintf(mptmp, "%" APR_OFF_T_FMT, msr->r->clength);
2079 return var_simple_generate(var, vartab, mptmp, value);
2084 static int var_userid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2085 apr_table_t *vartab, apr_pool_t *mptmp)
2087 const char *value = msr->userid;
2088 return var_simple_generate(var, vartab, mptmp, value);
2093 static int var_sessionid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2094 apr_table_t *vartab, apr_pool_t *mptmp)
2096 const char *value = msr->sessionid;
2097 return var_simple_generate(var, vartab, mptmp, value);
2102 static int var_webappid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
2103 apr_table_t *vartab, apr_pool_t *mptmp)
2105 const char *value = msr->txcfg->webappid;
2106 return var_simple_generate(var, vartab, mptmp, value);
2109 /* ---------------------------------------------- */
2114 void msre_engine_variable_register(msre_engine *engine, const char *name,
2115 unsigned int type, unsigned int argc_min, unsigned int argc_max,
2116 fn_var_validate_t validate, fn_var_generate_t generate,
2117 unsigned int is_cacheable, unsigned int availability)
2119 msre_var_metadata *metadata = (msre_var_metadata *)apr_pcalloc(engine->mp,
2120 sizeof(msre_var_metadata));
2121 if (metadata == NULL) return;
2123 metadata->name = name;
2124 metadata->type = type;
2125 metadata->argc_min = argc_min;
2126 metadata->argc_max = argc_max;
2127 metadata->validate = validate;
2128 metadata->generate = generate;
2129 metadata->is_cacheable = is_cacheable;
2130 metadata->availability = availability;
2132 apr_table_setn(engine->variables, name, (void *)metadata);
2138 void msre_engine_register_default_variables(msre_engine *engine) {
2141 msre_engine_variable_register(engine,
2145 var_generic_list_validate,
2148 PHASE_REQUEST_HEADERS
2151 /* ARGS_COMBINED_SIZE */
2152 msre_engine_variable_register(engine,
2153 "ARGS_COMBINED_SIZE",
2157 var_args_combined_size_generate,
2158 VAR_DONT_CACHE, /* dynamic */
2159 PHASE_REQUEST_HEADERS
2163 msre_engine_variable_register(engine,
2167 var_generic_list_validate,
2168 var_args_get_generate,
2170 PHASE_REQUEST_HEADERS
2173 /* ARGS_GET_NAMES */
2174 msre_engine_variable_register(engine,
2178 var_generic_list_validate,
2179 var_args_get_names_generate,
2181 PHASE_REQUEST_HEADERS
2185 msre_engine_variable_register(engine,
2189 var_generic_list_validate,
2190 var_args_names_generate,
2192 PHASE_REQUEST_HEADERS
2196 msre_engine_variable_register(engine,
2200 var_generic_list_validate,
2201 var_args_post_generate,
2206 /* ARGS_POST_NAMES */
2207 msre_engine_variable_register(engine,
2211 var_generic_list_validate,
2212 var_args_post_names_generate,
2218 msre_engine_variable_register(engine,
2223 var_auth_type_generate,
2229 msre_engine_variable_register(engine,
2236 PHASE_REQUEST_HEADERS
2240 msre_engine_variable_register(engine,
2244 var_generic_list_validate,
2250 /* FILES_COMBINED_SIZE */
2251 msre_engine_variable_register(engine,
2252 "FILES_COMBINED_SIZE",
2256 var_files_combined_size_generate,
2257 VAR_DONT_CACHE, /* temp copy */
2262 msre_engine_variable_register(engine,
2267 var_files_names_generate,
2273 msre_engine_variable_register(engine,
2277 var_generic_list_validate,
2278 var_files_sizes_generate,
2279 VAR_DONT_CACHE, /* temp copy */
2283 /* FILES_TMPNAMES */
2284 msre_engine_variable_register(engine,
2288 var_generic_list_validate,
2289 var_files_tmpnames_generate,
2295 msre_engine_variable_register(engine,
2299 var_generic_list_validate,
2301 VAR_DONT_CACHE, /* dynamic */
2302 PHASE_REQUEST_HEADERS
2306 msre_engine_variable_register(engine,
2310 var_generic_list_validate,
2311 var_global_generate,
2312 VAR_DONT_CACHE, /* dynamic */
2313 PHASE_REQUEST_HEADERS
2316 /* HIGHEST_SEVERITY */
2317 msre_engine_variable_register(engine,
2322 var_highest_severity_generate,
2323 VAR_DONT_CACHE, /* dynamic */
2324 PHASE_REQUEST_HEADERS
2328 msre_engine_variable_register(engine,
2332 var_generic_list_validate,
2334 VAR_DONT_CACHE, /* dynamic */
2335 PHASE_REQUEST_HEADERS
2339 msre_engine_variable_register(engine,
2344 var_matched_var_generate,
2345 VAR_DONT_CACHE, /* dynamic */
2346 PHASE_REQUEST_HEADERS
2349 /* MATCHED_VAR_NAME */
2350 msre_engine_variable_register(engine,
2355 var_matched_var_name_generate,
2356 VAR_DONT_CACHE, /* dynamic */
2357 PHASE_REQUEST_HEADERS
2361 msre_engine_variable_register(engine,
2366 var_modsec_build_generate,
2368 PHASE_REQUEST_HEADERS
2371 /* MULTIPART_BOUNDARY_QUOTED */
2372 msre_engine_variable_register(engine,
2373 "MULTIPART_BOUNDARY_QUOTED",
2377 var_multipart_boundary_quoted_generate,
2378 VAR_DONT_CACHE, /* flag */
2382 /* MULTIPART_BOUNDARY_WHITESPACE */
2383 msre_engine_variable_register(engine,
2384 "MULTIPART_BOUNDARY_WHITESPACE",
2388 var_multipart_boundary_whitespace_generate,
2389 VAR_DONT_CACHE, /* flag */
2393 /* MULTIPART_DATA_AFTER */
2394 msre_engine_variable_register(engine,
2395 "MULTIPART_DATA_AFTER",
2399 var_multipart_data_after_generate,
2400 VAR_DONT_CACHE, /* flag */
2404 /* MULTIPART_DATA_BEFORE */
2405 msre_engine_variable_register(engine,
2406 "MULTIPART_DATA_BEFORE",
2410 var_multipart_data_before_generate,
2411 VAR_DONT_CACHE, /* flag */
2415 /* MULTIPART_HEADER_FOLDING */
2416 msre_engine_variable_register(engine,
2417 "MULTIPART_HEADER_FOLDING",
2421 var_multipart_header_folding_generate,
2422 VAR_DONT_CACHE, /* flag */
2426 /* MULTIPART_CRLF_LINE */
2427 msre_engine_variable_register(engine,
2428 "MULTIPART_CRLF_LINE",
2432 var_multipart_crlf_line_generate,
2433 VAR_DONT_CACHE, /* flag */
2437 /* MULTIPART_CRLF_LF_LINES */
2438 msre_engine_variable_register(engine,
2439 "MULTIPART_CRLF_LF_LINES",
2443 var_multipart_crlf_lf_lines_generate,
2444 VAR_DONT_CACHE, /* flag */
2448 /* MULTIPART_LF_LINE */
2449 msre_engine_variable_register(engine,
2450 "MULTIPART_LF_LINE",
2454 var_multipart_lf_line_generate,
2455 VAR_DONT_CACHE, /* flag */
2459 /* MULTIPART_MISSING_SEMICOLON */
2460 msre_engine_variable_register(engine,
2461 "MULTIPART_MISSING_SEMICOLON",
2465 var_multipart_missing_semicolon_generate,
2466 VAR_DONT_CACHE, /* flag */
2470 /* MULTIPART_INVALID_QUOTING */
2471 msre_engine_variable_register(engine,
2472 "MULTIPART_INVALID_QUOTING",
2476 var_multipart_invalid_quoting_generate,
2477 VAR_DONT_CACHE, /* flag */
2481 /* MULTIPART_STRICT_ERROR */
2482 msre_engine_variable_register(engine,
2483 "MULTIPART_STRICT_ERROR",
2487 var_multipart_strict_error_generate,
2488 VAR_DONT_CACHE, /* flag */
2492 /* MULTIPART_UNMATCHED_BOUNDARY */
2493 msre_engine_variable_register(engine,
2494 "MULTIPART_UNMATCHED_BOUNDARY",
2498 var_multipart_unmatched_boundary_generate,
2499 VAR_DONT_CACHE, /* flag */
2504 msre_engine_variable_register(engine,
2509 var_path_info_generate,
2515 msre_engine_variable_register(engine,
2520 var_query_string_generate,
2522 PHASE_REQUEST_HEADERS
2526 msre_engine_variable_register(engine,
2531 var_remote_addr_generate,
2533 PHASE_REQUEST_HEADERS
2537 msre_engine_variable_register(engine,
2542 var_remote_host_generate,
2548 msre_engine_variable_register(engine,
2553 var_remote_port_generate,
2554 VAR_DONT_CACHE, /* temp copy */
2559 msre_engine_variable_register(engine,
2564 var_remote_user_generate,
2570 msre_engine_variable_register(engine,
2574 var_generic_list_validate,
2575 var_resource_generate,
2576 VAR_DONT_CACHE, /* dynamic */
2577 PHASE_REQUEST_HEADERS
2580 /* REQBODY_PROCESSOR */
2581 msre_engine_variable_register(engine,
2582 "REQBODY_PROCESSOR",
2586 var_reqbody_processor_generate,
2587 VAR_DONT_CACHE, /* temp copy */
2588 PHASE_REQUEST_HEADERS
2591 /* REQBODY_PROCESSOR_ERROR */
2592 msre_engine_variable_register(engine,
2593 "REQBODY_PROCESSOR_ERROR",
2597 var_reqbody_processor_error_generate,
2598 VAR_DONT_CACHE, /* dynamic */
2602 /* REQBODY_PROCESSOR_ERROR_MSG */
2603 msre_engine_variable_register(engine,
2604 "REQBODY_PROCESSOR_ERROR_MSG",
2608 var_reqbody_processor_error_msg_generate,
2609 VAR_DONT_CACHE, /* dynamic */
2613 /* REQUEST_BASENAME */
2614 msre_engine_variable_register(engine,
2619 var_request_basename_generate,
2620 VAR_DONT_CACHE, /* temp copy */
2621 PHASE_REQUEST_HEADERS
2625 msre_engine_variable_register(engine,
2630 var_request_body_generate,
2635 /* REQUEST_COOKIES */
2636 msre_engine_variable_register(engine,
2640 var_generic_list_validate,
2641 var_request_cookies_generate,
2643 PHASE_REQUEST_HEADERS
2646 /* REQUEST_COOKIES_NAMES */
2647 msre_engine_variable_register(engine,
2648 "REQUEST_COOKIES_NAMES",
2651 var_generic_list_validate,
2652 var_request_cookies_names_generate,
2654 PHASE_REQUEST_HEADERS
2657 /* REQUEST_FILENAME */
2658 msre_engine_variable_register(engine,
2663 var_request_filename_generate,
2665 PHASE_REQUEST_HEADERS
2668 /* REQUEST_HEADERS */
2669 msre_engine_variable_register(engine,
2673 var_generic_list_validate,
2674 var_request_headers_generate,
2676 PHASE_REQUEST_HEADERS
2679 /* REQUEST_HEADERS_NAMES */
2680 msre_engine_variable_register(engine,
2681 "REQUEST_HEADERS_NAMES",
2684 var_generic_list_validate,
2685 var_request_headers_names_generate,
2687 PHASE_REQUEST_HEADERS
2691 msre_engine_variable_register(engine,
2696 var_request_line_generate,
2698 PHASE_REQUEST_HEADERS
2701 /* REQUEST_METHOD */
2702 msre_engine_variable_register(engine,
2707 var_request_method_generate,
2709 PHASE_REQUEST_HEADERS
2712 /* REQUEST_PROTOCOL */
2713 msre_engine_variable_register(engine,
2718 var_request_protocol_generate,
2720 PHASE_REQUEST_HEADERS
2724 msre_engine_variable_register(engine,
2729 var_request_uri_generate,
2730 VAR_DONT_CACHE, /* temp copy */
2731 PHASE_REQUEST_HEADERS
2734 /* REQUEST_URI_RAW */
2735 msre_engine_variable_register(engine,
2740 var_request_uri_raw_generate,
2742 PHASE_REQUEST_HEADERS
2746 msre_engine_variable_register(engine,
2751 var_response_body_generate,
2756 /* RESPONSE_CONTENT_LENGTH */
2757 msre_engine_variable_register(engine,
2758 "RESPONSE_CONTENT_LENGTH",
2762 var_response_content_length,
2763 VAR_DONT_CACHE, /* temp copy */
2764 PHASE_RESPONSE_HEADERS
2767 /* RESPONSE_CONTENT_TYPE */
2768 msre_engine_variable_register(engine,
2769 "RESPONSE_CONTENT_TYPE",
2773 var_response_content_type,
2775 PHASE_RESPONSE_HEADERS
2778 /* RESPONSE_HEADERS */
2779 msre_engine_variable_register(engine,
2783 var_generic_list_validate,
2784 var_response_headers_generate,
2786 PHASE_RESPONSE_HEADERS
2789 /* RESPONSE_HEADERS_NAMES */
2790 msre_engine_variable_register(engine,
2791 "RESPONSE_HEADERS_NAMES",
2794 var_generic_list_validate,
2795 var_response_headers_names_generate,
2797 PHASE_RESPONSE_HEADERS
2800 /* RESPONSE_PROTOCOL */
2801 msre_engine_variable_register(engine,
2802 "RESPONSE_PROTOCOL",
2806 var_response_protocol_generate,
2808 PHASE_RESPONSE_HEADERS
2811 /* RESPONSE_STATUS */
2812 msre_engine_variable_register(engine,
2817 var_response_status_generate,
2818 VAR_DONT_CACHE, /* temp copy */
2819 PHASE_RESPONSE_HEADERS
2823 msre_engine_variable_register(engine,
2829 VAR_DONT_CACHE, /* dynamic */
2830 PHASE_RESPONSE_HEADERS
2834 msre_engine_variable_register(engine,
2839 var_script_gid_generate,
2840 VAR_DONT_CACHE, /* temp copy */
2844 /* SCRIPT_BASENAME */
2845 msre_engine_variable_register(engine,
2850 var_script_basename_generate,
2851 VAR_DONT_CACHE, /* temp copy */
2855 /* SCRIPT_FILENAME */
2856 msre_engine_variable_register(engine,
2861 var_script_filename_generate,
2866 /* SCRIPT_GROUPNAME */
2867 msre_engine_variable_register(engine,
2872 var_script_groupname_generate,
2873 VAR_DONT_CACHE, /* temp copy */
2878 msre_engine_variable_register(engine,
2883 var_script_mode_generate,
2884 VAR_DONT_CACHE, /* temp copy */
2889 msre_engine_variable_register(engine,
2894 var_script_uid_generate,
2895 VAR_DONT_CACHE, /* temp copy */
2899 /* SCRIPT_USERNAME */
2900 msre_engine_variable_register(engine,
2905 var_script_username_generate,
2906 VAR_DONT_CACHE, /* temp copy */
2911 msre_engine_variable_register(engine,
2916 var_server_addr_generate,
2918 PHASE_REQUEST_HEADERS
2922 msre_engine_variable_register(engine,
2927 var_server_name_generate,
2929 PHASE_REQUEST_HEADERS
2933 msre_engine_variable_register(engine,
2938 var_server_port_generate,
2939 VAR_DONT_CACHE, /* temp copy */
2940 PHASE_REQUEST_HEADERS
2944 msre_engine_variable_register(engine,
2948 var_generic_list_validate,
2949 var_session_generate,
2950 VAR_DONT_CACHE, /* dynamic */
2951 PHASE_REQUEST_HEADERS
2955 msre_engine_variable_register(engine,
2960 var_sessionid_generate,
2961 VAR_DONT_CACHE, /* dynamic */
2962 PHASE_RESPONSE_HEADERS
2966 msre_engine_variable_register(engine,
2971 var_status_line_generate,
2973 PHASE_RESPONSE_HEADERS
2977 msre_engine_variable_register(engine,
2981 var_generic_list_validate,
2983 VAR_DONT_CACHE, /* dynamic */
2984 PHASE_REQUEST_HEADERS
2988 msre_engine_variable_register(engine,
2993 var_userid_generate,
2994 VAR_DONT_CACHE, /* dynamic */
2995 PHASE_RESPONSE_HEADERS
2999 msre_engine_variable_register(engine,
3005 VAR_DONT_CACHE, /* dynamic */
3006 PHASE_REQUEST_HEADERS
3010 msre_engine_variable_register(engine,
3015 var_time_day_generate,
3016 VAR_DONT_CACHE, /* dynamic */
3017 PHASE_REQUEST_HEADERS
3021 msre_engine_variable_register(engine,
3026 var_time_epoch_generate,
3027 VAR_DONT_CACHE, /* dynamic */
3028 PHASE_REQUEST_HEADERS
3032 msre_engine_variable_register(engine,
3037 var_time_hour_generate,
3038 VAR_DONT_CACHE, /* dynamic */
3039 PHASE_REQUEST_HEADERS
3043 msre_engine_variable_register(engine,
3048 var_time_min_generate,
3049 VAR_DONT_CACHE, /* dynamic */
3050 PHASE_REQUEST_HEADERS
3054 msre_engine_variable_register(engine,
3059 var_time_mon_generate,
3060 VAR_DONT_CACHE, /* dynamic */
3061 PHASE_REQUEST_HEADERS
3065 msre_engine_variable_register(engine,
3070 var_time_sec_generate,
3071 VAR_DONT_CACHE, /* dynamic */
3072 PHASE_REQUEST_HEADERS
3076 msre_engine_variable_register(engine,
3081 var_time_wday_generate,
3082 VAR_DONT_CACHE, /* dynamic */
3083 PHASE_REQUEST_HEADERS
3087 msre_engine_variable_register(engine,
3092 var_time_year_generate,
3093 VAR_DONT_CACHE, /* dynamic */
3094 PHASE_REQUEST_HEADERS
3098 msre_engine_variable_register(engine,
3102 var_generic_list_validate,
3104 VAR_DONT_CACHE, /* dynamic */
3105 PHASE_REQUEST_HEADERS
3109 msre_engine_variable_register(engine,
3114 var_webappid_generate,
3116 PHASE_RESPONSE_HEADERS
3119 /* WEBSERVER_ERROR_LOG */
3120 msre_engine_variable_register(engine,
3121 "WEBSERVER_ERROR_LOG",
3125 var_webserver_error_log_generate,
3126 VAR_DONT_CACHE, /* dynamic */
3127 PHASE_REQUEST_HEADERS
3131 msre_engine_variable_register(engine,
3137 VAR_DONT_CACHE, /* dynamic */