in apache2/re_actions.c [968:1303]
static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
msre_rule *rule, msre_action *action)
{
char *name = NULL;
char *value = NULL;
/* Parse first. */
if (parse_name_eq_value(msr->mp, action->param, &name, &value) < 0) return -1;
if (value == NULL) return -1;
/* Validate value. */
if (strcasecmp(name, "ruleEngine") == 0) {
if (strcasecmp(value, "on") == 0) {
msr->txcfg->is_enabled = MODSEC_ENABLED;
msr->usercfg->is_enabled = MODSEC_ENABLED;
}
else
if (strcasecmp(value, "off") == 0) {
msr->txcfg->is_enabled = MODSEC_DISABLED;
msr->usercfg->is_enabled = MODSEC_DISABLED;
}
else
if (strcasecmp(value, "detectiononly") == 0) {
msr->txcfg->is_enabled = MODSEC_DETECTION_ONLY;
msr->usercfg->is_enabled = MODSEC_DETECTION_ONLY;
msr->txcfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_PARTIAL;
msr->usercfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_PARTIAL;
msr->txcfg->of_limit_action = REQUEST_BODY_LIMIT_ACTION_PARTIAL;
msr->usercfg->of_limit_action = REQUEST_BODY_LIMIT_ACTION_PARTIAL;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set ruleEngine to %s.", value);
}
return 1;
} else
if (strcasecmp(name, "HashEnforcement") == 0) {
if (strcasecmp(value, "on") == 0) {
msr->txcfg->hash_enforcement = HASH_ENABLED;
msr->usercfg->hash_enforcement = HASH_ENABLED;
}
if (strcasecmp(value, "off") == 0) {
msr->txcfg->hash_enforcement = HASH_DISABLED;
msr->usercfg->hash_enforcement = HASH_DISABLED;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set HashEnforcement to %s.", value);
}
return 1;
} else
if (strcasecmp(name, "HashEngine") == 0) {
if (strcasecmp(value, "on") == 0) {
msr->txcfg->hash_is_enabled = HASH_ENABLED;
msr->usercfg->hash_is_enabled = HASH_ENABLED;
}
if (strcasecmp(value, "off") == 0) {
msr->txcfg->hash_is_enabled = HASH_DISABLED;
msr->usercfg->hash_is_enabled = HASH_DISABLED;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set HashEngine to %s.", value);
}
return 1;
} else
if (strcasecmp(name, "ruleRemoveById") == 0) {
*(const char **)apr_array_push(msr->removed_rules) = (const char *)apr_pstrdup(msr->mp, value);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Removed rule by id : %s.", value);
}
return 1;
} else
if (strcasecmp(name, "ruleRemoveByTag") == 0) {
rule_exception *re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_TAG;
re->param = (const char *)apr_pstrdup(msr->mp, value);
re->param_data = msc_pregcomp(msr->mp, re->param, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", re->param);
return -1;
}
*(rule_exception **)apr_array_push(msr->removed_rules_tag) = re;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Removed rule by tag : %s.", value);
}
return 1;
} else
if (strcasecmp(name, "ruleRemoveByMsg") == 0) {
rule_exception *re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_MSG;
re->param = (const char *)apr_pstrdup(msr->mp, value);
re->param_data = msc_pregcomp(msr->mp, re->param, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", re->param);
return -1;
}
*(rule_exception **)apr_array_push(msr->removed_rules_msg) = re;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Removed rule by msg : %s.", value);
}
return 1;
} else
if (strcasecmp(name, "requestBodyAccess") == 0) {
int pv = parse_boolean(value);
if (pv == -1) return -1;
msr->txcfg->reqbody_access = pv;
msr->usercfg->reqbody_access = pv;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set requestBodyAccess to %d.", pv);
}
return 1;
} else
if (strcasecmp(name, "forceRequestBodyVariable") == 0) {
if (strcasecmp(value, "on") == 0) {
msr->txcfg->reqbody_buffering = REQUEST_BODY_FORCEBUF_ON;
msr->usercfg->reqbody_buffering = REQUEST_BODY_FORCEBUF_ON;
}
else
if (strcasecmp(value, "off") == 0) {
msr->txcfg->reqbody_buffering = REQUEST_BODY_FORCEBUF_OFF;
msr->usercfg->reqbody_buffering = REQUEST_BODY_FORCEBUF_OFF;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set requestBodyAccess to %d.", msr->txcfg->reqbody_buffering);
}
return 1;
} else
if (strcasecmp(name, "requestBodyProcessor") == 0) {
msr->msc_reqbody_processor = value;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set requestBodyProcessor to %s.", value);
}
return 1;
} else
if (strcasecmp(name, "responseBodyAccess") == 0) {
int pv = parse_boolean(value);
if (pv == -1) return -1;
msr->txcfg->resbody_access = pv;
msr->usercfg->resbody_access = pv;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set responseBodyAccess to %d.", pv);
}
return 1;
} else
if (strcasecmp(name, "auditEngine") == 0) {
if (strcasecmp(value, "on") == 0) {
msr->txcfg->auditlog_flag = AUDITLOG_ON;
msr->usercfg->auditlog_flag = AUDITLOG_ON;
}
else
if (strcasecmp(value, "off") == 0) {
msr->txcfg->auditlog_flag = AUDITLOG_OFF;
msr->usercfg->auditlog_flag = AUDITLOG_OFF;
}
else
if (strcasecmp(value, "relevantonly") == 0) {
msr->txcfg->auditlog_flag = AUDITLOG_RELEVANT;
msr->usercfg->auditlog_flag = AUDITLOG_RELEVANT;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set auditEngine to %d.", msr->txcfg->auditlog_flag);
}
return 1;
} else
if (strcasecmp(name, "auditLogParts") == 0) {
char *new_value = value;
if (value[0] == '+') {
/* Add the listed parts. */
new_value = apr_pstrcat(msr->mp, msr->txcfg->auditlog_parts, value + 1, NULL);
}
else
if (value[0] == '-') { /* Remove the listed parts. */
char c, *t = value + 1;
/* Start with the current value. */
new_value = apr_pstrdup(msr->mp, msr->txcfg->auditlog_parts);
while((c = *t++) != '\0') {
char *s = new_value;
char *d = new_value;
while(*s != '\0') {
if (*s != c) {
*(d++) = *(s++);
} else {
s++;
}
}
*d = '\0';
}
}
/* Set the new value. */
msr->txcfg->auditlog_parts = new_value;
msr->usercfg->auditlog_parts = new_value;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set auditLogParts to %s.", msr->txcfg->auditlog_parts);
}
return 1;
} else
if (strcasecmp(name, "debugLogLevel") == 0) {
msr->txcfg->debuglog_level = atoi(value);
msr->usercfg->debuglog_level = atoi(value);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set debugLogLevel to %d.", msr->txcfg->debuglog_level);
}
return 1;
} else
if (strcasecmp(name, "requestBodyLimit") == 0) {
long int limit = strtol(value, NULL, 10);
/* ENH Accept only in correct phase warn otherwise. */
msr->txcfg->reqbody_limit = limit;
msr->usercfg->reqbody_limit = limit;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set requestBodyLimit to %ld.", limit);
}
return 1;
} else
if (strcasecmp(name, "responseBodyLimit") == 0) {
long int limit = strtol(value, NULL, 10);
/* ENH Accept only in correct phase warn otherwise. */
msr->txcfg->of_limit = limit;
msr->usercfg->of_limit = limit;
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: Set responseBodyLimit to %ld.", limit);
}
return 1;
} else
if (strcasecmp(name, "ruleRemoveTargetById") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleRemoveTargetById id=%s targets=%s", p1, p2);
}
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_ID;
re->param = (const char *)apr_pstrdup(msr->mp, p1);
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
} else
if (strcasecmp(name, "ruleRemoveTargetByTag") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleRemoveTargetByTag tag=%s targets=%s", p1, p2);
}
if (p2 == NULL) {
msr_log(msr, 1, "ModSecurity: Missing target for tag \"%s\"", p1);
return -1;
}
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_TAG;
re->param = (const char *)apr_pstrdup(msr->mp, p1);
re->param_data = msc_pregcomp(msr->mp, p1, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", p1);
return -1;
}
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
} else
if (strcasecmp(name, "ruleRemoveTargetByMsg") == 0) {
rule_exception *re = NULL;
char *p1 = NULL, *p2 = NULL;
char *savedptr = NULL;
p1 = apr_strtok(value,";",&savedptr);
p2 = apr_strtok(NULL,";",&savedptr);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Ctl: ruleRemoveTargetByMsg msg=%s targets=%s", p1, p2);
}
re = apr_pcalloc(msr->mp, sizeof(rule_exception));
re->type = RULE_EXCEPTION_REMOVE_MSG;
re->param = apr_pstrdup(msr->mp, p1);
re->param_data = msc_pregcomp(msr->mp, p1, 0, NULL, NULL);
if (re->param_data == NULL) {
msr_log(msr, 1, "ModSecurity: Invalid regular expression \"%s\"", p1);
return -1;
}
apr_table_addn(msr->removed_targets, apr_pstrdup(msr->mp, p2), (void *)re);
return 1;
}
else {
/* Should never happen, but log if it does. */
msr_log(msr, 1, "Internal Error: Unknown ctl action \"%s\".", name);
return -1;
}
return -1;
}