static apr_status_t msre_action_ctl_execute()

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;
}