mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
3113 lines
87 KiB
C
3113 lines
87 KiB
C
/*
|
|
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
* Copyright (c) 2004-2007 Breach Security, Inc. (http://www.breach.com/)
|
|
*
|
|
* You should have received a copy of the licence along with this
|
|
* program (stored in the file "LICENSE"). If the file is missing,
|
|
* or if you have any other questions related to the licence, please
|
|
* write to Breach Security, Inc. at support@breach.com.
|
|
*
|
|
*/
|
|
#include "http_core.h"
|
|
|
|
#include "modsecurity.h"
|
|
#include "apache2.h"
|
|
#include "re.h"
|
|
#include "msc_util.h"
|
|
|
|
#ifdef WITH_LIBXML2
|
|
#include "libxml/xpathInternals.h"
|
|
#endif
|
|
|
|
/**
|
|
* Generates a variable from a string and a length.
|
|
*/
|
|
static int var_simple_generate_ex(msre_var *var, apr_table_t *vartab, apr_pool_t *mptmp,
|
|
const char *value, int value_len)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
|
|
if (value == NULL) return 0;
|
|
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = value;
|
|
rvar->value_len = value_len;
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Generates a variable from a NULL-terminated string.
|
|
*/
|
|
static int var_simple_generate(msre_var *var, apr_table_t *vartab, apr_pool_t *mptmp,
|
|
const char *value)
|
|
{
|
|
if (value == NULL) return 0;
|
|
return var_simple_generate_ex(var, vartab, mptmp, value, strlen(value));
|
|
}
|
|
|
|
/**
|
|
* Validate that a target parameter is valid. We only need to take
|
|
* care of the case when the parameter is a regular expression.
|
|
*/
|
|
static char *var_generic_list_validate(msre_ruleset *ruleset, msre_var *var) {
|
|
/* It's OK if there's no parameter. */
|
|
if (var->param == NULL) return NULL;
|
|
|
|
/* Is it a regular expression? */
|
|
if ((strlen(var->param) > 2)&&(var->param[0] == '/')
|
|
&&(var->param[strlen(var->param) - 1] == '/'))
|
|
{ /* Regex. */
|
|
msc_regex_t *regex = NULL;
|
|
const char *errptr = NULL;
|
|
const char *pattern = NULL;
|
|
int erroffset;
|
|
|
|
pattern = apr_pstrmemdup(ruleset->mp, var->param + 1, strlen(var->param + 1) - 1);
|
|
if (pattern == NULL) return FATAL_ERROR;
|
|
|
|
regex = msc_pregcomp(ruleset->mp, pattern, PCRE_DOTALL | PCRE_CASELESS | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
|
|
if (regex == NULL) {
|
|
return apr_psprintf(ruleset->mp, "Error compiling pattern (pos %d): %s",
|
|
erroffset, errptr);
|
|
}
|
|
|
|
/* Store the compiled regex for later. */
|
|
var->param_data = regex;
|
|
}
|
|
|
|
/* Simple string */
|
|
return NULL;
|
|
}
|
|
|
|
/* Custom parameter validation functions */
|
|
|
|
/* ARGS */
|
|
|
|
static int var_args_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
/* Loop through the arguments. */
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this argument. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
/* Run the regex against the argument name. */
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->value;
|
|
rvar->value_len = arg->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* ARGS_COMBINED_SIZE */
|
|
|
|
static int var_args_combined_size_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
unsigned int combined_size = 0;
|
|
int i;
|
|
msre_var *rvar = NULL;
|
|
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
combined_size += arg->name_len;
|
|
combined_size += arg->value_len;
|
|
}
|
|
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%u", combined_size);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* ARGS_NAMES */
|
|
|
|
static int var_args_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->name;
|
|
rvar->value_len = arg->name_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* ARGS_GET */
|
|
|
|
static int var_args_get_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
/* Loop through the arguments. */
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Only QUERY_STRING arguments */
|
|
if (strcmp("QUERY_STRING", arg->origin) != 0) continue;
|
|
|
|
/* Figure out if we want to include this argument. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
/* Run the regex against the argument name. */
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->value;
|
|
rvar->value_len = arg->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS_GET:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* ARGS_GET_NAMES */
|
|
|
|
static int var_args_get_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Only QUERY_STRING arguments */
|
|
if (strcmp("QUERY_STRING", arg->origin) != 0) continue;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->name;
|
|
rvar->value_len = arg->name_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS_GET_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* ARGS_POST */
|
|
|
|
static int var_args_post_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
/* Loop through the arguments. */
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Only BODY arguments */
|
|
if (strcmp("BODY", arg->origin) != 0) continue;
|
|
|
|
/* Figure out if we want to include this argument. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
/* Run the regex against the argument name. */
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->value;
|
|
rvar->value_len = arg->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS_POST:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* ARGS_POST_NAMES */
|
|
|
|
static int var_args_post_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->arguments);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_arg *arg = (msc_arg *)te[i].val;
|
|
int match = 0;
|
|
|
|
/* Only BODY arguments */
|
|
if (strcmp("BODY", arg->origin) != 0) continue;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, arg->name,
|
|
arg->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(arg->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = arg->name;
|
|
rvar->value_len = arg->name_len;
|
|
rvar->name = apr_psprintf(mptmp, "ARGS_POST_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* RULE */
|
|
|
|
static int var_rule_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_actionset *actionset = NULL;
|
|
|
|
if (rule == NULL) return 0;
|
|
actionset = rule->actionset;
|
|
if (rule->chain_starter != NULL) actionset = rule->chain_starter->actionset;
|
|
|
|
if ((strcasecmp(var->param, "id") == 0)&&(actionset->id != NULL)) {
|
|
return var_simple_generate(var, vartab, mptmp, actionset->id);
|
|
} else
|
|
if ((strcasecmp(var->param, "rev") == 0)&&(actionset->rev != NULL)) {
|
|
return var_simple_generate(var, vartab, mptmp, actionset->rev);
|
|
} else
|
|
if ((strcasecmp(var->param, "severity") == 0)&&(actionset->severity != -1)) {
|
|
char *value = apr_psprintf(mptmp, "%d", actionset->severity);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
} else
|
|
if ((strcasecmp(var->param, "msg") == 0)&&(actionset->msg != NULL)) {
|
|
return var_simple_generate(var, vartab, mptmp, actionset->msg);
|
|
} else
|
|
if ((strcasecmp(var->param, "logdata") == 0)&&(actionset->logdata != NULL)) {
|
|
return var_simple_generate(var, vartab, mptmp, actionset->logdata);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ENV */
|
|
|
|
static char *var_env_validate(msre_ruleset *ruleset, msre_var *var) {
|
|
if ((strlen(var->param) > 2)&&(var->param[0] == '/')
|
|
&&(var->param[strlen(var->param) - 1] == '/'))
|
|
{
|
|
return apr_psprintf(ruleset->mp, "Regular expressions not supported in ENV.");
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static int var_env_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = get_env_var(msr->r, (char *)var->param);
|
|
if (value != NULL) {
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* REQUEST_URI_RAW */
|
|
|
|
static int var_request_uri_raw_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->r->unparsed_uri);
|
|
}
|
|
|
|
/* REQUEST_URI */
|
|
|
|
static int var_request_uri_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = NULL;
|
|
|
|
if (msr->r->parsed_uri.query == NULL) value = msr->r->parsed_uri.path;
|
|
else value = apr_pstrcat(mptmp, msr->r->parsed_uri.path, "?", msr->r->parsed_uri.query, NULL);
|
|
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* REQBODY_PROCESSOR */
|
|
|
|
static int var_reqbody_processor_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
if (msr->msc_reqbody_processor == NULL) {
|
|
rvar->value = apr_pstrdup(mptmp, "");
|
|
rvar->value_len = 0;
|
|
} else {
|
|
rvar->value = apr_pstrdup(mptmp, msr->msc_reqbody_processor);
|
|
rvar->value_len = strlen(rvar->value);
|
|
}
|
|
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* REQBODY_ERROR */
|
|
|
|
static int var_reqbody_processor_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = apr_psprintf(mptmp, "%d", msr->msc_reqbody_error);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* REQBODY_ERROR_MSG */
|
|
|
|
static int var_reqbody_processor_error_msg_generate(modsec_rec *msr, msre_var *var,
|
|
msre_rule *rule, apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
if (msr->msc_reqbody_error_msg == NULL) {
|
|
rvar->value = apr_pstrdup(mptmp, "");
|
|
rvar->value_len = 0;
|
|
} else {
|
|
rvar->value = apr_psprintf(mptmp, "%s", msr->msc_reqbody_error_msg);
|
|
rvar->value_len = strlen(rvar->value);
|
|
}
|
|
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
#ifdef WITH_LIBXML2
|
|
|
|
/* XML */
|
|
|
|
static char *var_xml_validate(msre_ruleset *ruleset, msre_var *var) {
|
|
/* It's OK if there's no parameter. */
|
|
if (var->param == NULL) return NULL;
|
|
|
|
/* ENH validate XPath expression in advance. */
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int var_xml_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *tarr;
|
|
const apr_table_entry_t *telts;
|
|
xmlXPathContextPtr xpathCtx;
|
|
xmlXPathObjectPtr xpathObj;
|
|
xmlNodeSetPtr nodes;
|
|
const xmlChar* xpathExpr = NULL;
|
|
int i, count;
|
|
|
|
/* Is there an XML document tree at all? */
|
|
if ((msr->xml == NULL)||(msr->xml->doc == NULL)) {
|
|
/* Sorry, we've got nothing to give! */
|
|
return 0;
|
|
}
|
|
|
|
if (var->param == NULL) {
|
|
/* Invocation without an XPath expression makes sense
|
|
* with functions that manipulate the document tree.
|
|
*/
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = apr_pstrdup(mptmp, "[XML document tree]");
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Process the XPath expression. */
|
|
|
|
count = 0;
|
|
xpathExpr = (const xmlChar*)var->param;
|
|
|
|
xpathCtx = xmlXPathNewContext(msr->xml->doc);
|
|
if (xpathCtx == NULL) {
|
|
msr_log(msr, 1, "XML: Unable to create new XPath context.");
|
|
return -1;
|
|
}
|
|
|
|
/* Look through the actionset of the associated rule
|
|
* for the namespace information. Register them if any are found.
|
|
*/
|
|
tarr = apr_table_elts(rule->actionset->actions);
|
|
telts = (const apr_table_entry_t*)tarr->elts;
|
|
for (i = 0; i < tarr->nelts; i++) {
|
|
msre_action *action = (msre_action *)telts[i].val;
|
|
|
|
if (strcasecmp(action->metadata->name, "xmlns") == 0) {
|
|
char *prefix, *href;
|
|
|
|
if (parse_name_eq_value(mptmp, action->param, &prefix, &href) < 0) return -1;
|
|
if ((prefix == NULL)||(href == NULL)) return -1;
|
|
|
|
if(xmlXPathRegisterNs(xpathCtx, (const xmlChar*)prefix, (const xmlChar*)href) != 0) {
|
|
msr_log(msr, 1, "Failed to register XML namespace href \"%s\" prefix \"%s\".",
|
|
log_escape(mptmp, prefix), log_escape(mptmp, href));
|
|
return -1;
|
|
}
|
|
|
|
msr_log(msr, 4, "Registered XML namespace href \"%s\" prefix \"%s\".",
|
|
log_escape(mptmp, prefix), log_escape(mptmp, href));
|
|
}
|
|
}
|
|
|
|
/* Initialise XPath expression. */
|
|
xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
|
|
if (xpathObj == NULL) {
|
|
msr_log(msr, 1, "XML: Unable to evaluate xpath expression.");
|
|
xmlXPathFreeContext(xpathCtx);
|
|
return -1;
|
|
}
|
|
|
|
/* Evaluate XPath expression. */
|
|
nodes = xpathObj->nodesetval;
|
|
if (nodes == NULL) {
|
|
xmlXPathFreeObject(xpathObj);
|
|
xmlXPathFreeContext(xpathCtx);
|
|
return 0;
|
|
}
|
|
|
|
/* Create one variable for each node in the result. */
|
|
for(i = 0; i < nodes->nodeNr; i++) {
|
|
msre_var *rvar = NULL;
|
|
char *content = NULL;
|
|
|
|
content = (char *)xmlNodeGetContent(nodes->nodeTab[i]);
|
|
if (content != NULL) {
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_pstrdup(mptmp, content);
|
|
xmlFree(content);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
xmlXPathFreeObject(xpathObj);
|
|
xmlXPathFreeContext(xpathCtx);
|
|
|
|
return count;
|
|
}
|
|
#endif
|
|
|
|
/* WEBSERVER_ERROR_LOG */
|
|
|
|
static int var_webserver_error_log_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
int i, count = 0;
|
|
|
|
for(i = 0; i < msr->error_messages->nelts; i++) {
|
|
error_message *em = (((error_message**)msr->error_messages->elts)[i]);
|
|
char *fem = NULL;
|
|
|
|
fem = format_error_log_message(mptmp, em);
|
|
if (fem != NULL) {
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_pstrdup(mptmp, fem);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* REMOTE_ADDR */
|
|
|
|
static int var_remote_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->remote_addr);
|
|
}
|
|
|
|
/* REMOTE_HOST */
|
|
|
|
static int var_remote_host_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value1 = ap_get_remote_host(msr->r->connection, msr->r->per_dir_config,
|
|
REMOTE_NAME, NULL);
|
|
return var_simple_generate(var, vartab, mptmp, value1);
|
|
}
|
|
|
|
/* REMOTE_PORT */
|
|
|
|
static int var_remote_port_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = apr_psprintf(mptmp, "%d", msr->remote_port);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* REMOTE_USER */
|
|
|
|
static int var_remote_user_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->remote_user);
|
|
}
|
|
|
|
/* TX */
|
|
|
|
static int var_tx_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->tx_vars);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "TX:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* GEO */
|
|
|
|
static int var_geo_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->geo_vars);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "GEO:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* HIGHEST_SEVERITY */
|
|
|
|
static int var_highest_severity_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp,
|
|
apr_psprintf(mptmp, "%d", msr->highest_severity));
|
|
}
|
|
|
|
/* IP */
|
|
|
|
static int var_ip_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
apr_table_t *target_col = NULL;
|
|
|
|
target_col = (apr_table_t *)apr_table_get(msr->collections, "ip");
|
|
if (target_col == NULL) return 0;
|
|
|
|
arr = apr_table_elts(target_col);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "IP:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* MATCHED_VAR */
|
|
|
|
static int var_matched_var_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate_ex(var, vartab, mptmp,
|
|
apr_pmemdup(mptmp,
|
|
msr->matched_var->value,
|
|
msr->matched_var->value_len),
|
|
msr->matched_var->value_len);
|
|
}
|
|
|
|
/* MATCHED_VAR_NAME */
|
|
|
|
static int var_matched_var_name_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate_ex(var, vartab, mptmp,
|
|
apr_pmemdup(mptmp,
|
|
msr->matched_var->name,
|
|
msr->matched_var->name_len),
|
|
msr->matched_var->name_len);
|
|
}
|
|
|
|
/* SESSION */
|
|
|
|
static int var_session_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
apr_table_t *target_col = NULL;
|
|
|
|
target_col = (apr_table_t *)apr_table_get(msr->collections, "session");
|
|
if (target_col == NULL) return 0;
|
|
|
|
arr = apr_table_elts(target_col);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional inclusion. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "SESSION:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* USER */
|
|
|
|
static int var_user_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
apr_table_t *target_col = NULL;
|
|
|
|
target_col = (apr_table_t *)apr_table_get(msr->collections, "user");
|
|
if (target_col == NULL) return 0;
|
|
|
|
arr = apr_table_elts(target_col);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional match. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "USER:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* GLOBAL */
|
|
|
|
static int var_global_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
apr_table_t *target_col = NULL;
|
|
|
|
target_col = (apr_table_t *)apr_table_get(msr->collections, "global");
|
|
if (target_col == NULL) return 0;
|
|
|
|
arr = apr_table_elts(target_col);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional match. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "GLOBAL:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* RESOURCE */
|
|
|
|
static int var_resource_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
apr_table_t *target_col = NULL;
|
|
|
|
target_col = (apr_table_t *)apr_table_get(msr->collections, "resource");
|
|
if (target_col == NULL) return 0;
|
|
|
|
arr = apr_table_elts(target_col);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
msc_string *str = (msc_string *)te[i].val;
|
|
int match;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
match = 0;
|
|
if (var->param == NULL) match = 1; /* Unconditional match. */
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, str->name,
|
|
str->name_len, &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(str->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = str->value;
|
|
rvar->value_len = str->value_len;
|
|
rvar->name = apr_psprintf(mptmp, "RESOURCE:%s", log_escape_nq(mptmp, str->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* FILES_TMPNAMES */
|
|
|
|
static int var_files_tmpnames_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
multipart_part **parts = NULL;
|
|
int i, count = 0;
|
|
|
|
if (msr->mpd == NULL) return 0;
|
|
|
|
parts = (multipart_part **)msr->mpd->parts->elts;
|
|
for(i = 0; i < msr->mpd->parts->nelts; i++) {
|
|
if ((parts[i]->type == MULTIPART_FILE)&&(parts[i]->tmp_file_name != NULL)) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
|
|
strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = parts[i]->tmp_file_name;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "FILES_TMPNAMES:%s",
|
|
log_escape_nq(mptmp, parts[i]->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* FILES */
|
|
|
|
static int var_files_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
multipart_part **parts = NULL;
|
|
int i, count = 0;
|
|
|
|
if (msr->mpd == NULL) return 0;
|
|
|
|
parts = (multipart_part **)msr->mpd->parts->elts;
|
|
for(i = 0; i < msr->mpd->parts->nelts; i++) {
|
|
if (parts[i]->type == MULTIPART_FILE) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
|
|
strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = parts[i]->filename;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "FILES:%s",
|
|
log_escape_nq(mptmp, parts[i]->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* FILES_SIZES */
|
|
|
|
static int var_files_sizes_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
multipart_part **parts = NULL;
|
|
int i, count = 0;
|
|
|
|
if (msr->mpd == NULL) return 0;
|
|
|
|
parts = (multipart_part **)msr->mpd->parts->elts;
|
|
for(i = 0; i < msr->mpd->parts->nelts; i++) {
|
|
if (parts[i]->type == MULTIPART_FILE) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
|
|
strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = apr_psprintf(mptmp, "%u", parts[i]->tmp_file_size);
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "FILES_SIZES:%s",
|
|
log_escape_nq(mptmp, parts[i]->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* FILES_NAMES */
|
|
|
|
static int var_files_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
multipart_part **parts = NULL;
|
|
int i, count = 0;
|
|
|
|
if (msr->mpd == NULL) return 0;
|
|
|
|
parts = (multipart_part **)msr->mpd->parts->elts;
|
|
for(i = 0; i < msr->mpd->parts->nelts; i++) {
|
|
if (parts[i]->type == MULTIPART_FILE) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = parts[i]->name;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "FILES_NAMES:%s",
|
|
log_escape_nq(mptmp, parts[i]->name));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* FILES_COMBINED_SIZE */
|
|
|
|
static int var_files_combined_size_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
multipart_part **parts = NULL;
|
|
msre_var *rvar = NULL;
|
|
unsigned int combined_size = 0;
|
|
int i;
|
|
|
|
if (msr->mpd != NULL) {
|
|
parts = (multipart_part **)msr->mpd->parts->elts;
|
|
for(i = 0; i < msr->mpd->parts->nelts; i++) {
|
|
if (parts[i]->type == MULTIPART_FILE) {
|
|
combined_size += parts[i]->tmp_file_size;
|
|
}
|
|
}
|
|
}
|
|
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%u", combined_size);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* MODSEC_BUILD */
|
|
|
|
static int var_modsec_build_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, modsec_build(mptmp));
|
|
}
|
|
|
|
/* MULTIPART_BOUNDARY_QUOTED */
|
|
|
|
static int var_multipart_boundary_quoted_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_boundary_quoted != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_BOUNDARY_WHITESPACE */
|
|
|
|
static int var_multipart_boundary_whitespace_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_boundary_whitespace != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_DATA_AFTER */
|
|
|
|
static int var_multipart_data_after_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_data_after != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_DATA_BEFORE */
|
|
|
|
static int var_multipart_data_before_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_data_before != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_HEADER_FOLDING */
|
|
|
|
static int var_multipart_header_folding_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_header_folding != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_CRLF_LINE */
|
|
|
|
static int var_multipart_crlf_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_crlf_line != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_CRLF_LF_LINES */
|
|
|
|
static int var_multipart_crlf_lf_lines_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_lf_line != 0)&&(msr->mpd->flag_crlf_line != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_LF_LINE */
|
|
|
|
static int var_multipart_lf_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_lf_line != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_MISSING_SEMICOLON */
|
|
|
|
static int var_multipart_missing_semicolon_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_missing_semicolon != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* MULTIPART_STRICT_ERROR */
|
|
|
|
static int var_multipart_strict_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if (msr->mpd != NULL) {
|
|
/* Respond positive if at least one of the multipart flags is raised. */
|
|
if ( (msr->mpd->flag_error)
|
|
||(msr->mpd->flag_boundary_quoted != 0)
|
|
||(msr->mpd->flag_boundary_whitespace != 0)
|
|
||(msr->mpd->flag_data_before != 0)
|
|
||(msr->mpd->flag_data_after != 0)
|
|
||(msr->mpd->flag_header_folding != 0)
|
|
||(msr->mpd->flag_lf_line != 0)
|
|
||(msr->mpd->flag_missing_semicolon != 0)
|
|
) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
}
|
|
}
|
|
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
|
|
/* MULTIPART_UNMATCHED_BOUNDARY */
|
|
|
|
static int var_multipart_unmatched_boundary_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if ((msr->mpd != NULL)&&(msr->mpd->flag_unmatched_boundary != 0)) {
|
|
return var_simple_generate(var, vartab, mptmp, "1");
|
|
} else {
|
|
return var_simple_generate(var, vartab, mptmp, "0");
|
|
}
|
|
}
|
|
|
|
/* TIME */
|
|
|
|
static int var_time_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d%02d%02d%02d%02d%02d%02d",
|
|
(tm->tm_year / 100) + 19, (tm->tm_year % 100),
|
|
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
|
|
tm->tm_sec);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_YEAR */
|
|
|
|
static int var_time_year_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d%02d",
|
|
(tm->tm_year / 100) + 19,
|
|
tm->tm_year % 100);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_WDAY */
|
|
|
|
static int var_time_wday_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%d", tm->tm_wday);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_SEC */
|
|
|
|
static int var_time_sec_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_sec);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_MIN */
|
|
|
|
static int var_time_min_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_min);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_HOUR */
|
|
static int var_time_hour_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_hour);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_MON */
|
|
|
|
static int var_time_mon_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_mon + 1);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_DAY */
|
|
|
|
static int var_time_day_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%02d", tm->tm_mday);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* TIME_EPOCH */
|
|
|
|
static int var_time_epoch_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
msre_var *rvar = NULL;
|
|
struct tm *tm;
|
|
time_t tc;
|
|
|
|
tc = time(NULL);
|
|
tm = localtime(&tc);
|
|
rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
rvar->value = apr_psprintf(mptmp, "%d", (int)tc);
|
|
rvar->value_len = strlen(rvar->value);
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* QUERY_STRING */
|
|
|
|
static int var_query_string_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->query_string);
|
|
}
|
|
|
|
/* REQUEST_BASENAME */
|
|
|
|
static int var_request_basename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = file_basename(mptmp, msr->r->parsed_uri.path);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* REQUEST_BODY */
|
|
|
|
static int var_request_body_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if (msr->msc_reqbody_buffer != NULL) {
|
|
return var_simple_generate_ex(var, vartab, mptmp,
|
|
msr->msc_reqbody_buffer, msr->msc_reqbody_length);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* REQUEST_COOKIES */
|
|
|
|
static int var_request_cookies_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->request_cookies);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].val;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "REQUEST_COOKIES:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* REQUEST_COOKIES_NAMES */
|
|
|
|
static int var_request_cookies_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->request_cookies);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].key;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "REQUEST_COOKIES_NAMES:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* REQUEST_HEADERS */
|
|
|
|
static int var_request_headers_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->request_headers);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].val;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "REQUEST_HEADERS:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* REQUEST_HEADERS_NAMES */
|
|
|
|
static int var_request_headers_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->request_headers);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].key;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "REQUEST_HEADERS_NAMES:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* REQUEST_FILENAME */
|
|
|
|
static int var_request_filename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->r->parsed_uri.path);
|
|
}
|
|
|
|
/* REQUEST_LINE */
|
|
|
|
static int var_request_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->request_line);
|
|
}
|
|
|
|
/* REQUEST_METHOD */
|
|
|
|
static int var_request_method_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->request_method);
|
|
}
|
|
|
|
/* REQUEST_PROTOCOL */
|
|
|
|
static int var_request_protocol_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->request_protocol);
|
|
}
|
|
|
|
/* SERVER_ADDR */
|
|
|
|
static int var_server_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->local_addr);
|
|
}
|
|
|
|
/* SERVER_NAME */
|
|
|
|
static int var_server_name_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->hostname);
|
|
}
|
|
|
|
/* SERVER_PORT */
|
|
|
|
static int var_server_port_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = apr_psprintf(mptmp, "%d", msr->local_port);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_BASENAME */
|
|
|
|
static int var_script_basename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = file_basename(mptmp, msr->r->filename);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_FILENAME */
|
|
|
|
static int var_script_filename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = msr->r->filename;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_GID */
|
|
|
|
static int var_script_gid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = apr_psprintf(mptmp, "%d", msr->r->finfo.group);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_GROUPNAME */
|
|
|
|
static int var_script_groupname_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = NULL;
|
|
if (apr_gid_name_get(&value, msr->r->finfo.group, mptmp) == APR_SUCCESS) {
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* SCRIPT_MODE */
|
|
|
|
static int var_script_mode_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = apr_psprintf(mptmp, "%04x", msr->r->finfo.protection);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_UID */
|
|
|
|
static int var_script_uid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = apr_psprintf(mptmp, "%d", msr->r->finfo.user);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SCRIPT_USERNAME */
|
|
|
|
static int var_script_username_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = NULL;
|
|
if (apr_uid_name_get(&value, msr->r->finfo.user, mptmp) == APR_SUCCESS) {
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* AUTH_TYPE */
|
|
|
|
static int var_auth_type_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
char *value = msr->r->ap_auth_type;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* PATH_INFO */
|
|
|
|
static int var_path_info_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->r->path_info;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* RESPONSE_BODY */
|
|
|
|
static int var_response_body_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
if (msr->resbody_data != NULL) {
|
|
return var_simple_generate_ex(var, vartab, mptmp,
|
|
msr->resbody_data, msr->resbody_length);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* RESPONSE_HEADERS */
|
|
|
|
static int var_response_headers_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
if (msr->response_headers == NULL) return 0;
|
|
|
|
arr = apr_table_elts(msr->response_headers);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].val;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "RESPONSE_HEADERS:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* RESPONSE_HEADERS_NAMES */
|
|
|
|
static int var_response_headers_names_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const apr_array_header_t *arr = NULL;
|
|
const apr_table_entry_t *te = NULL;
|
|
int i, count = 0;
|
|
|
|
arr = apr_table_elts(msr->response_headers);
|
|
te = (apr_table_entry_t *)arr->elts;
|
|
for (i = 0; i < arr->nelts; i++) {
|
|
int match = 0;
|
|
|
|
/* Figure out if we want to include this variable. */
|
|
if (var->param == NULL) match = 1;
|
|
else {
|
|
if (var->param_data != NULL) { /* Regex. */
|
|
char *my_error_msg = NULL;
|
|
if (!(msc_regexec((msc_regex_t *)var->param_data, te[i].key,
|
|
strlen(te[i].key), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
|
|
} else { /* Simple comparison. */
|
|
if (strcasecmp(te[i].key, var->param) == 0) match = 1;
|
|
}
|
|
}
|
|
|
|
/* If we had a match add this argument to the collection. */
|
|
if (match) {
|
|
msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
|
|
|
|
rvar->value = te[i].key;
|
|
rvar->value_len = strlen(rvar->value);
|
|
rvar->name = apr_psprintf(mptmp, "RESPONSE_HEADERS_NAMES:%s",
|
|
log_escape_nq(mptmp, te[i].key));
|
|
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
|
|
|
count++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
/* STATUS_LINE */
|
|
|
|
static int var_status_line_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->status_line;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* RESPONSE_PROTOCOL */
|
|
|
|
static int var_response_protocol_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->response_protocol;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* RESPONSE_STATUS */
|
|
|
|
static int var_response_status_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = apr_psprintf(mptmp, "%d", msr->response_status);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* RESPONSE_CONTENT_TYPE */
|
|
|
|
static int var_response_content_type(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
return var_simple_generate(var, vartab, mptmp, msr->r->content_type);
|
|
}
|
|
|
|
/* RESPONSE_CONTENT_LENGTH */
|
|
|
|
static int var_response_content_length(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = apr_psprintf(mptmp, "%" APR_OFF_T_FMT, msr->r->clength);
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* USERID */
|
|
|
|
static int var_userid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->userid;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* SESSIONID */
|
|
|
|
static int var_sessionid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->sessionid;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* WEBAPPID */
|
|
|
|
static int var_webappid_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
|
apr_table_t *vartab, apr_pool_t *mptmp)
|
|
{
|
|
const char *value = msr->txcfg->webappid;
|
|
return var_simple_generate(var, vartab, mptmp, value);
|
|
}
|
|
|
|
/* ---------------------------------------------- */
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void msre_engine_variable_register(msre_engine *engine, const char *name,
|
|
unsigned int type, unsigned int argc_min, unsigned int argc_max,
|
|
fn_var_validate_t validate, fn_var_generate_t generate,
|
|
unsigned int is_cacheable, unsigned int availability)
|
|
{
|
|
msre_var_metadata *metadata = (msre_var_metadata *)apr_pcalloc(engine->mp,
|
|
sizeof(msre_var_metadata));
|
|
if (metadata == NULL) return;
|
|
|
|
metadata->name = name;
|
|
metadata->type = type;
|
|
metadata->argc_min = argc_min;
|
|
metadata->argc_max = argc_max;
|
|
metadata->validate = validate;
|
|
metadata->generate = generate;
|
|
metadata->is_cacheable = is_cacheable;
|
|
metadata->availability = availability;
|
|
|
|
apr_table_setn(engine->variables, name, (void *)metadata);
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
void msre_engine_register_default_variables(msre_engine *engine) {
|
|
|
|
/* ARGS */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* ARGS_COMBINED_SIZE */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_COMBINED_SIZE",
|
|
VAR_LIST,
|
|
0, 0,
|
|
NULL,
|
|
var_args_combined_size_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* ARGS_GET */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_GET",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_get_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* ARGS_GET_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_GET_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_get_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* ARGS_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* ARGS_POST */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_POST",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_post_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* ARGS_POST_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"ARGS_POST_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_args_post_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* AUTH_TYPE */
|
|
msre_engine_variable_register(engine,
|
|
"AUTH_TYPE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_auth_type_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* ENV */
|
|
msre_engine_variable_register(engine,
|
|
"ENV",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_env_validate,
|
|
var_env_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* FILES */
|
|
msre_engine_variable_register(engine,
|
|
"FILES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_files_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* FILES_COMBINED_SIZE */
|
|
msre_engine_variable_register(engine,
|
|
"FILES_COMBINED_SIZE",
|
|
VAR_LIST,
|
|
0, 0,
|
|
NULL,
|
|
var_files_combined_size_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* FILES_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"FILES_NAMES",
|
|
VAR_LIST,
|
|
0, 0,
|
|
NULL,
|
|
var_files_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* FILES_SIZES */
|
|
msre_engine_variable_register(engine,
|
|
"FILES_SIZES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_files_sizes_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* FILES_TMPNAMES */
|
|
msre_engine_variable_register(engine,
|
|
"FILES_TMPNAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_files_tmpnames_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* GEO */
|
|
msre_engine_variable_register(engine,
|
|
"GEO",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_geo_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* GLOBAL */
|
|
msre_engine_variable_register(engine,
|
|
"GLOBAL",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_global_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* HIGHEST_SEVERITY */
|
|
msre_engine_variable_register(engine,
|
|
"HIGHEST_SEVERITY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_highest_severity_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* IP */
|
|
msre_engine_variable_register(engine,
|
|
"IP",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_ip_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* MATCHED_VAR */
|
|
msre_engine_variable_register(engine,
|
|
"MATCHED_VAR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_matched_var_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* MATCHED_VAR_NAME */
|
|
msre_engine_variable_register(engine,
|
|
"MATCHED_VAR_NAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_matched_var_name_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* MODSEC_BUILD */
|
|
msre_engine_variable_register(engine,
|
|
"MODSEC_BUILD",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_modsec_build_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* MULTIPART_BOUNDARY_QUOTED */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_BOUNDARY_QUOTED",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_boundary_quoted_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_BOUNDARY_WHITESPACE */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_BOUNDARY_WHITESPACE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_boundary_whitespace_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_DATA_AFTER */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_DATA_AFTER",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_data_after_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_DATA_BEFORE */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_DATA_BEFORE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_data_before_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_HEADER_FOLDING */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_HEADER_FOLDING",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_header_folding_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_CRLF_LINE */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_CRLF_LINE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_crlf_line_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_CRLF_LF_LINES */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_CRLF_LF_LINES",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_crlf_lf_lines_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_LF_LINE */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_LF_LINE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_lf_line_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_MISSING_SEMICOLON */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_MISSING_SEMICOLON",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_missing_semicolon_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_STRICT_ERROR */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_STRICT_ERROR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_strict_error_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* MULTIPART_UNMATCHED_BOUNDARY */
|
|
msre_engine_variable_register(engine,
|
|
"MULTIPART_UNMATCHED_BOUNDARY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_multipart_unmatched_boundary_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* PATH_INFO */
|
|
msre_engine_variable_register(engine,
|
|
"PATH_INFO",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_path_info_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* QUERY_STRING */
|
|
msre_engine_variable_register(engine,
|
|
"QUERY_STRING",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_query_string_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REMOTE_ADDR */
|
|
msre_engine_variable_register(engine,
|
|
"REMOTE_ADDR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_remote_addr_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REMOTE_HOST */
|
|
msre_engine_variable_register(engine,
|
|
"REMOTE_HOST",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_remote_host_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* REMOTE_PORT */
|
|
msre_engine_variable_register(engine,
|
|
"REMOTE_PORT",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_remote_port_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* REMOTE_USER */
|
|
msre_engine_variable_register(engine,
|
|
"REMOTE_USER",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_remote_user_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* RESOURCE */
|
|
msre_engine_variable_register(engine,
|
|
"RESOURCE",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_resource_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQBODY_PROCESSOR */
|
|
msre_engine_variable_register(engine,
|
|
"REQBODY_PROCESSOR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_reqbody_processor_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQBODY_PROCESSOR_ERROR */
|
|
msre_engine_variable_register(engine,
|
|
"REQBODY_PROCESSOR_ERROR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_reqbody_processor_error_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* REQBODY_PROCESSOR_ERROR_MSG */
|
|
msre_engine_variable_register(engine,
|
|
"REQBODY_PROCESSOR_ERROR_MSG",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_reqbody_processor_error_msg_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* REQUEST_BASENAME */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_BASENAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_basename_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_BODY */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_BODY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_body_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* REQUEST_COOKIES */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_COOKIES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_request_cookies_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_COOKIES_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_COOKIES_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_request_cookies_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_FILENAME */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_FILENAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_filename_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_HEADERS */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_HEADERS",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_request_headers_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_HEADERS_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_HEADERS_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_request_headers_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_LINE */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_LINE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_line_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_METHOD */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_METHOD",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_method_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_PROTOCOL */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_PROTOCOL",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_protocol_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_URI */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_URI",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_uri_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* REQUEST_URI_RAW */
|
|
msre_engine_variable_register(engine,
|
|
"REQUEST_URI_RAW",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_request_uri_raw_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_BODY */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_BODY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_response_body_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_BODY
|
|
);
|
|
|
|
/* RESPONSE_CONTENT_LENGTH */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_CONTENT_LENGTH",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_response_content_length,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_CONTENT_TYPE */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_CONTENT_TYPE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_response_content_type,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_HEADERS */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_HEADERS",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_response_headers_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_HEADERS_NAMES */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_HEADERS_NAMES",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_generic_list_validate,
|
|
var_response_headers_names_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_PROTOCOL */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_PROTOCOL",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_response_protocol_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RESPONSE_STATUS */
|
|
msre_engine_variable_register(engine,
|
|
"RESPONSE_STATUS",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_response_status_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* RULE */
|
|
msre_engine_variable_register(engine,
|
|
"RULE",
|
|
VAR_LIST,
|
|
1, 1,
|
|
NULL,
|
|
var_rule_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* SCRIPT_GID */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_GID",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_gid_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_BASENAME */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_BASENAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_basename_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_FILENAME */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_FILENAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_filename_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_GROUPNAME */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_GROUPNAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_groupname_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_MODE */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_MODE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_mode_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_UID */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_UID",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_uid_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SCRIPT_USERNAME */
|
|
msre_engine_variable_register(engine,
|
|
"SCRIPT_USERNAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_script_username_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
|
|
/* SERVER_ADDR */
|
|
msre_engine_variable_register(engine,
|
|
"SERVER_ADDR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_server_addr_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* SERVER_NAME */
|
|
msre_engine_variable_register(engine,
|
|
"SERVER_NAME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_server_name_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* SERVER_PORT */
|
|
msre_engine_variable_register(engine,
|
|
"SERVER_PORT",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_server_port_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* SESSION */
|
|
msre_engine_variable_register(engine,
|
|
"SESSION",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_session_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* SESSIONID */
|
|
msre_engine_variable_register(engine,
|
|
"SESSIONID",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_sessionid_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* STATUS_LINE */
|
|
msre_engine_variable_register(engine,
|
|
"STATUS_LINE",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_status_line_generate,
|
|
VAR_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* USER */
|
|
msre_engine_variable_register(engine,
|
|
"USER",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_user_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* USERID */
|
|
msre_engine_variable_register(engine,
|
|
"USERID",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_userid_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* TIME */
|
|
msre_engine_variable_register(engine,
|
|
"TIME",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_DAY */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_DAY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_day_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_EPOCH */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_EPOCH",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_epoch_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_HOUR */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_HOUR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_hour_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_MIN */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_MIN",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_min_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_MON */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_MON",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_mon_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_SEC */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_SEC",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_sec_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_WDAY */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_WDAY",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_wday_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TIME_YEAR */
|
|
msre_engine_variable_register(engine,
|
|
"TIME_YEAR",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_time_year_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* TX */
|
|
msre_engine_variable_register(engine,
|
|
"TX",
|
|
VAR_LIST,
|
|
1, 1,
|
|
var_generic_list_validate,
|
|
var_tx_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
/* WEBAPPID */
|
|
msre_engine_variable_register(engine,
|
|
"WEBAPPID",
|
|
VAR_SIMPLE,
|
|
0, 0,
|
|
NULL,
|
|
var_webappid_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_RESPONSE_HEADERS
|
|
);
|
|
|
|
/* WEBSERVER_ERROR_LOG */
|
|
msre_engine_variable_register(engine,
|
|
"WEBSERVER_ERROR_LOG",
|
|
VAR_LIST,
|
|
0, 0,
|
|
NULL,
|
|
var_webserver_error_log_generate,
|
|
VAR_DONT_CACHE,
|
|
PHASE_REQUEST_HEADERS
|
|
);
|
|
|
|
#ifdef WITH_LIBXML2
|
|
/* XML */
|
|
msre_engine_variable_register(engine,
|
|
"XML",
|
|
VAR_LIST,
|
|
0, 1,
|
|
var_xml_validate,
|
|
var_xml_generate,
|
|
VAR_CACHE,
|
|
PHASE_REQUEST_BODY
|
|
);
|
|
#endif
|
|
}
|