From 30da07b59be54b7ed8b62f90e7559afbbc7bdc36 Mon Sep 17 00:00:00 2001 From: brenosilva Date: Tue, 12 Apr 2011 13:49:07 +0000 Subject: [PATCH] MODSEC-37 --- apache2/apache2_config.c | 42 ++++++++++++++++++++++++++-------------- apache2/re.c | 24 +++++++++++++++-------- apache2/re.h | 2 +- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c index 2e50acf3..b7788364 100644 --- a/apache2/apache2_config.c +++ b/apache2/apache2_config.c @@ -849,7 +849,7 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, * */ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg, - const char *p1, const char *p2) + const char *p1, const char *p2, int offset) { char *my_error_msg = NULL; msre_rule *rule = NULL; @@ -868,7 +868,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg, #endif /* Fetch the rule */ - rule = msre_ruleset_fetch_rule(ruleset, p1); + rule = msre_ruleset_fetch_rule(ruleset, p1, offset); if (rule == NULL) { #ifdef DEBUG_CONF ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, @@ -940,18 +940,14 @@ char *update_rule_target(cmd_parms *cmd, directory_config *dcfg, msre_ruleset *ruleset = NULL; const char *curr_targets = NULL; char *my_error_msg = NULL; - char *p = NULL; - char *savedptr = NULL; - char *target_list = NULL; - char *replace = NULL; - int is_negated = 0; - int is_counting = 0; - int name_len = 0; - int value_len = 0; + char *p = NULL, *savedptr = NULL; + char *target_list = NULL, *replace = NULL; + int is_negated = 0, is_counting = 0; + int name_len = 0, value_len = 0; char *name = NULL, *value = NULL; - char *opt = NULL; - char *param = NULL; + char *opt = NULL, *param = NULL; int i, rc, match = 0; + int offset = 0; if(p1 == NULL || p2 == NULL || (dcfg == NULL && rset == NULL)) { return NULL; @@ -967,7 +963,7 @@ char *update_rule_target(cmd_parms *cmd, directory_config *dcfg, return NULL; } - rule = msre_ruleset_fetch_rule(ruleset, p1); + rule = msre_ruleset_fetch_rule(ruleset, p1, offset); if (rule == NULL) { if (cmd != NULL) { ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, @@ -1927,9 +1923,25 @@ static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg, } static const char *cmd_rule_update_action_by_id(cmd_parms *cmd, void *_dcfg, - const char *p1, const char *p2) + const char *p1, const char *p2) { - return update_rule_action(cmd, (directory_config *)_dcfg, p1, p2); + int offset = 0, rule_id = atoi(p1); + char *opt = strchr(p1,':'); + char *savedptr = NULL; + char *param = apr_pstrdup(cmd->pool, p1); + + if ((rule_id == LONG_MAX)||(rule_id == LONG_MIN)||(rule_id <= 0)) { + return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for ID for update action: %s", p1); + } + + if(opt != NULL) { + opt++; + offset = atoi(opt); + opt = apr_strtok(param,":", &savedptr); + return update_rule_action(cmd, (directory_config *)_dcfg, (const char *)opt, p2, offset); + } + + return update_rule_action(cmd, (directory_config *)_dcfg, p1, p2, offset); } static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg, diff --git a/apache2/re.c b/apache2/re.c index b8800856..21e14ab1 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -1351,7 +1351,7 @@ int msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase) { } static msre_rule * msre_ruleset_fetch_phase_rule(const msre_ruleset *ruleset, const char *id, - const apr_array_header_t *phase_arr) + const apr_array_header_t *phase_arr, int offset) { msre_rule **rules = (msre_rule **)phase_arr->elts; int i; @@ -1366,7 +1366,15 @@ static msre_rule * msre_ruleset_fetch_phase_rule(const msre_ruleset *ruleset, co && (strcmp(rule->actionset->id, id) == 0)) { /* Return rule that matched unless it is a placeholder */ - return (rule->placeholder == RULE_PH_NONE) ? rule : NULL; + if(offset == 0) { + return (rule->placeholder == RULE_PH_NONE) ? rule : NULL; + } + else { + if (i+offset < phase_arr->nelts) { + msre_rule *rule_off = (msre_rule *)rules[i+offset]; + return (rule_off->placeholder == RULE_PH_NONE) ? rule_off : NULL; + } + } } } @@ -1376,24 +1384,24 @@ static msre_rule * msre_ruleset_fetch_phase_rule(const msre_ruleset *ruleset, co /** * Fetches rule from the ruleset all rules that match the given exception. */ -msre_rule * msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id) { +msre_rule * msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id, int offset) { msre_rule *rule = NULL; if (ruleset == NULL) return NULL; - rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_request_headers); + rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_request_headers, offset); if (rule != NULL) return rule; - rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_request_body); + rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_request_body, ofsset); if (rule != NULL) return rule; - rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_response_headers); + rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_response_headers, offset); if (rule != NULL) return rule; - rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_response_body); + rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_response_body, offset); if (rule != NULL) return rule; - rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_logging); + rule = msre_ruleset_fetch_phase_rule(ruleset, id, ruleset->phase_logging, offset); return rule; } diff --git a/apache2/re.h b/apache2/re.h index 1990b08a..98b3884e 100644 --- a/apache2/re.h +++ b/apache2/re.h @@ -123,7 +123,7 @@ msre_ruleset DSOLOCAL *msre_ruleset_create(msre_engine *engine, apr_pool_t *mp); int DSOLOCAL msre_ruleset_rule_add(msre_ruleset *ruleset, msre_rule *rule, int phase); -msre_rule DSOLOCAL *msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id); +msre_rule DSOLOCAL *msre_ruleset_fetch_rule(msre_ruleset *ruleset, const char *id, int offset); int DSOLOCAL msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exception *re);