From 54cac6461ba69ebe95e6cc5d0f8961eef3528557 Mon Sep 17 00:00:00 2001 From: brectanus Date: Wed, 12 Dec 2007 22:52:08 +0000 Subject: [PATCH] Add IS_NEW and IS_EXPIRED collection variables. See #345. --- CHANGES | 5 +-- apache2/persist_dbm.c | 47 ++++++++++++++++++++++++--- apache2/re_actions.c | 16 +++++++++ doc/modsecurity2-apache-reference.xml | 12 ++++++- 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 047eee49..78db1bb3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,8 @@ - -29 Nov 2007 - 2.5.0-dev3 +12 Dec 2007 - 2.5.0-dev3 ------------------------ + * Added IS_NEW and IS_EXPIRED built-in collection variables. + * Added SecMarker directive to allow a fixed target for skipAfter. * The invoked rule is now logged in the debug log at level 5. diff --git a/apache2/persist_dbm.c b/apache2/persist_dbm.c index 43c31938..a92794d9 100644 --- a/apache2/persist_dbm.c +++ b/apache2/persist_dbm.c @@ -72,6 +72,7 @@ apr_table_t *collection_retrieve(modsec_rec *msr, const char *col_name, apr_table_t *col = NULL; const apr_array_header_t *arr; apr_table_entry_t *te; + int expired = 0; int i; if (msr->txcfg->data_dir == NULL) { @@ -119,11 +120,16 @@ apr_table_t *collection_retrieve(modsec_rec *msr, const char *col_name, msc_string *var = (msc_string *)te[i].val; int expiry_time = atoi(var->value); - /* Do not remove the record itself. */ - if (strcmp(te[i].key, "__expire_KEY") == 0) continue; - if (expiry_time <= apr_time_sec(msr->request_time)) { + // TODO Why dup this? char *key_to_expire = apr_pstrdup(msr->mp, te[i].key); + + /* Do not remove the record itself. */ + if (strcmp(te[i].key, "__expire_KEY") == 0) { + expired = 1; + continue; + } + msr_log(msr, 9, "Removing key \"%s\" from collection.", key_to_expire + 9); apr_table_unset(col, key_to_expire + 9); msr_log(msr, 9, "Removing key \"%s\" from collection.", key_to_expire); @@ -135,6 +141,19 @@ apr_table_t *collection_retrieve(modsec_rec *msr, const char *col_name, } } while(i != arr->nelts); + /* Set IS_EXPIRED if expired */ + if (expired) { + msc_string *var = (msc_string *)apr_table_get(col, "IS_EXPIRED"); + if (var == NULL) { + var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string)); + var->name = "IS_EXPIRED"; + var->name_len = strlen(var->name); + } + if (var != NULL) { + var->value = "1"; + var->value_len = strlen(var->value); + } + } /* Update UPDATE_RATE */ { @@ -176,8 +195,8 @@ apr_table_t *collection_retrieve(modsec_rec *msr, const char *col_name, apr_sdbm_close(dbm); - msr_log(msr, 4, "Retrieved collection (name \"%s\", key \"%s\").", - log_escape(msr->mp, col_name), log_escape(msr->mp, col_key)); + msr_log(msr, 4, "Retrieved collection (name \"%s\", key \"%s\", expired \"%d\").", + log_escape(msr->mp, col_name), log_escape(msr->mp, col_key), expired); return col; } @@ -272,6 +291,24 @@ int collection_store(modsec_rec *msr, apr_table_t *col) { return 1; } + /* Set IS_NEW to 0 on store. */ + { + msc_string *var = (msc_string *)apr_table_get(col, "IS_NEW"); + if (var != NULL) { + var->value = "0"; + var->value_len = strlen(var->value); + } + } + + /* Set IS_EXPIRED to 0 on store. */ + { + msc_string *var = (msc_string *)apr_table_get(col, "IS_EXPIRED"); + if (var != NULL) { + var->value = "0"; + var->value_len = strlen(var->value); + } + } + /* Update the timeout value. */ { msc_string *var = (msc_string *)apr_table_get(col, "TIMEOUT"); diff --git a/apache2/re_actions.c b/apache2/re_actions.c index 5691c433..b6e569fe 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -1322,6 +1322,22 @@ static apr_status_t init_collection(modsec_rec *msr, const char *real_col_name, var->value = "0"; var->value_len = strlen(var->value); apr_table_setn(table, var->name, (void *)var); + + /* This is a new collection. */ + var = apr_pcalloc(msr->mp, sizeof(msc_string)); + var->name = "IS_NEW"; + var->name_len = strlen(var->name); + var->value = "1"; + var->value_len = strlen(var->value); + apr_table_setn(table, var->name, (void *)var); + + /* It has not yet expired. */ + var = apr_pcalloc(msr->mp, sizeof(msc_string)); + var->name = "IS_EXPIRED"; + var->name_len = strlen(var->name); + var->value = "0"; + var->value_len = strlen(var->value); + apr_table_setn(table, var->name, (void *)var); } /* Add the collection to the list. */ diff --git a/doc/modsecurity2-apache-reference.xml b/doc/modsecurity2-apache-reference.xml index 465afef7..6e711fd7 100644 --- a/doc/modsecurity2-apache-reference.xml +++ b/doc/modsecurity2-apache-reference.xml @@ -3934,6 +3934,16 @@ SecRule REQUEST_URI "^/cgi-bin/script\.pl" \ the creation of the collection. + + IS_EXPIRED - set to 1 if + the collection is expired otherwise set to 0. + + + + IS_NEW - set to 1 if the + collection is new (not yet persisted) otherwise set to 0. + + KEY - the value of the initcol variable (the client's IP address in the example). @@ -5146,4 +5156,4 @@ SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" t:l - + \ No newline at end of file