Implement "block" pseudo-action. See #441.

This commit is contained in:
brectanus
2008-01-24 05:16:35 +00:00
parent 9dbc7807d9
commit a3584993f5
6 changed files with 136 additions and 27 deletions

View File

@@ -609,6 +609,10 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
rule->actionset = msre_actionset_merge(modsecurity->msre, dcfg->tmp_default_actionset,
rule->actionset, 1);
/* Keep track of the parent action for "block" */
rule->actionset->parent_intercept_action_rec = dcfg->tmp_default_actionset->intercept_action_rec;
rule->actionset->parent_intercept_action = dcfg->tmp_default_actionset->intercept_action;
/* Must NOT specify a disruptive action in logging phase. */
if ((rule->actionset != NULL)
&& (rule->actionset->phase == PHASE_LOGGING)
@@ -761,7 +765,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
#ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Looking to update rule id=\"%s\" with \"%s\".", p1, p2);
"Update rule id=\"%s\" with action \"%s\".", p1, p2);
#endif
/* Fetch the rule */
@@ -769,7 +773,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
if (rule == NULL) {
#ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Failed to update rule id=\"%s\" with \"%s\": Rule not found.", p1, p2);
"Update rule id=\"%s\" with action \"%s\" failed: Rule not found.", p1, p2);
#endif
return NULL;
}
@@ -799,7 +803,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
{
char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Updating rule %pp id=\"%s\" action: \"%s\"",
"Update rule %pp id=\"%s\" old action: \"%s\"",
rule,
(rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
actions);
@@ -819,7 +823,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
{
char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Updated rule %pp id=\"%s\" action: \"%s\"",
"Update rule %pp id=\"%s\" new action: \"%s\"",
rule,
(rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
actions);

View File

@@ -87,6 +87,35 @@ char *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actions
return actions;
}
/**
* Add an action to an actionset.
*/
static void msre_actionset_action_add(msre_actionset *actionset, msre_action *action)
{
msre_action *add_action = action;
/**
* The "block" action is just a placeholder for the parent action.
*/
if ((actionset->parent_intercept_action_rec != NULL) && (actionset->parent_intercept_action_rec != NOT_SET_P) && (strcmp("block", action->metadata->name) == 0) && (strcmp("block", action->metadata->name) == 0)) {
/* revert back to parent */
actionset->intercept_action = actionset->parent_intercept_action;
add_action = actionset->parent_intercept_action_rec;
}
if (add_action->metadata->cardinality_group != ACTION_CGROUP_NONE) {
msre_actionset_cardinality_fixup(actionset, add_action);
}
if (add_action->metadata->cardinality == ACTION_CARDINALITY_ONE) {
/* One action per actionlist. */
apr_table_setn(actionset->actions, add_action->metadata->name, (void *)add_action);
} else {
/* Multiple actions per actionlist. */
apr_table_addn(actionset->actions, add_action->metadata->name, (void *)add_action);
}
}
/**
* Creates msre_var instances (rule variables) out of the
* given text string and places them into the supplied table.
@@ -159,17 +188,7 @@ apr_status_t msre_parse_actions(msre_engine *engine, msre_actionset *actionset,
action->metadata->init(engine, actionset, action);
}
if (action->metadata->cardinality_group != ACTION_CGROUP_NONE) {
msre_actionset_cardinality_fixup(actionset, action);
}
if (action->metadata->cardinality == ACTION_CARDINALITY_ONE) {
/* One action per actionlist. */
apr_table_setn(actionset->actions, action->metadata->name, (void *)action);
} else {
/* Multiple actions per actionlist. */
apr_table_addn(actionset->actions, action->metadata->name, (void *)action);
}
msre_actionset_action_add(actionset, action);
count++;
}
@@ -503,6 +522,9 @@ msre_actionset *msre_actionset_create(msre_engine *engine, const char *text,
actionset->skip_after = NOT_SET_P;
/* Disruptive */
actionset->parent_intercept_action_rec = NOT_SET_P;
actionset->intercept_action_rec = NOT_SET_P;
actionset->parent_intercept_action = NOT_SET;
actionset->intercept_action = NOT_SET;
actionset->intercept_uri = NOT_SET_P;
actionset->intercept_status = NOT_SET;
@@ -581,6 +603,7 @@ msre_actionset *msre_actionset_merge(msre_engine *engine, msre_actionset *parent
/* Disruptive */
if (child->intercept_action != NOT_SET) {
merged->intercept_action_rec = child->intercept_action_rec;
merged->intercept_action = child->intercept_action;
merged->intercept_uri = child->intercept_uri;
}
@@ -598,17 +621,7 @@ msre_actionset *msre_actionset_merge(msre_engine *engine, msre_actionset *parent
tarr = apr_table_elts(child->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 (action->metadata->cardinality_group != ACTION_CGROUP_NONE) {
msre_actionset_cardinality_fixup(merged, action);
}
if (action->metadata->cardinality == ACTION_CARDINALITY_ONE) {
apr_table_setn(merged->actions, action->metadata->name, (void *)action);
} else {
apr_table_addn(merged->actions, action->metadata->name, (void *)action);
}
msre_actionset_action_add(merged, (msre_action *)telts[i].val);
}
return merged;
@@ -643,6 +656,9 @@ void msre_actionset_set_defaults(msre_actionset *actionset) {
if (actionset->skip_after == NOT_SET_P) actionset->skip_after = NULL;
/* Disruptive */
if (actionset->parent_intercept_action_rec == NOT_SET_P) actionset->parent_intercept_action_rec = NULL;
if (actionset->intercept_action_rec == NOT_SET_P) actionset->intercept_action_rec = NULL;
if (actionset->parent_intercept_action == NOT_SET) actionset->parent_intercept_action = ACTION_NONE;
if (actionset->intercept_action == NOT_SET) actionset->intercept_action = ACTION_NONE;
if (actionset->intercept_uri == NOT_SET_P) actionset->intercept_uri = NULL;
if (actionset->intercept_status == NOT_SET) actionset->intercept_status = 403;

View File

@@ -272,9 +272,15 @@ struct msre_actionset {
int intercept_status;
int intercept_pause;
/* "block" needs parent action to reset it */
msre_action *parent_intercept_action_rec;
msre_action *intercept_action_rec;
int parent_intercept_action;
/* Other */
int log;
int auditlog;
int block;
};
char DSOLOCAL *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actionset *actionset);

View File

@@ -378,11 +378,21 @@ static apr_status_t msre_action_noauditlog_init(msre_engine *engine, msre_action
return 1;
}
/* block */
static apr_status_t msre_action_block_init(msre_engine *engine, msre_actionset *actionset,
msre_action *action)
{
/* Right now we just set a flag and inherit the real disruptive action */
actionset->block = 1;
return 1;
}
/* deny */
static apr_status_t msre_action_deny_init(msre_engine *engine, msre_actionset *actionset,
msre_action *action)
{
actionset->intercept_action = ACTION_DENY;
actionset->intercept_action_rec = action;
return 1;
}
@@ -404,6 +414,7 @@ static apr_status_t msre_action_drop_init(msre_engine *engine, msre_actionset *a
msre_action *action)
{
actionset->intercept_action = ACTION_DROP;
actionset->intercept_action_rec = action;
return 1;
}
@@ -432,6 +443,7 @@ static apr_status_t msre_action_redirect_init(msre_engine *engine, msre_actionse
{
actionset->intercept_action = ACTION_REDIRECT;
actionset->intercept_uri = action->param;
actionset->intercept_action_rec = action;
return 1;
}
@@ -463,6 +475,7 @@ static apr_status_t msre_action_proxy_init(msre_engine *engine, msre_actionset *
{
actionset->intercept_action = ACTION_PROXY;
actionset->intercept_uri = action->param;
actionset->intercept_action_rec = action;
return 1;
}
@@ -488,6 +501,7 @@ static apr_status_t msre_action_pass_init(msre_engine *engine, msre_actionset *a
msre_action *action)
{
actionset->intercept_action = ACTION_NONE;
actionset->intercept_action_rec = action;
return 1;
}
@@ -526,6 +540,7 @@ static apr_status_t msre_action_allow_init(msre_engine *engine, msre_actionset *
msre_action *action)
{
actionset->intercept_action = ACTION_ALLOW;
actionset->intercept_action_rec = action;
if (action->param != NULL) {
if (strcasecmp(action->param, "phase") == 0) {
@@ -1744,6 +1759,19 @@ void msre_engine_register_default_actions(msre_engine *engine) {
NULL
);
/* deny */
msre_engine_action_register(engine,
"block",
ACTION_DISRUPTIVE,
0, 0,
NO_PLUS_MINUS,
ACTION_CARDINALITY_ONE,
ACTION_CGROUP_DISRUPTIVE,
NULL,
msre_action_block_init,
NULL
);
/* deny */
msre_engine_action_register(engine,
"deny",