From a4d5d50be9bd2f8a4aa4c78545e0a11e626819c7 Mon Sep 17 00:00:00 2001 From: ivanr Date: Mon, 1 Feb 2010 11:01:17 +0000 Subject: [PATCH] Integrate with mod_log_config (MODSEC-108). --- CHANGES | 3 +++ apache2/mod_security2.c | 26 ++++++++++++++++++++++++++ apache2/msc_util.c | 29 +++++++++++++++++++++++++++++ apache2/msc_util.h | 2 ++ apache2/re_variables.c | 1 + 5 files changed, 61 insertions(+) diff --git a/CHANGES b/CHANGES index b541c3eb..359b7d20 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ 1 Feb 2010 - trunk ------------------- + * Integrate with mod_log_config using the %{VARNAME}m format string. + (MODSEC-108) [Ivan Ristic] + * Replaced the previous time-measuring mechanism with a new one, which provides the following information: request time, request duration, phase duration (for all 5 phases), time spent dealing with persistent diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 43531f63..a3af90a6 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -25,6 +25,9 @@ #include "apache2.h" #include "http_main.h" +#include "apr_optional.h" +#include "mod_log_config.h" + #include "msc_logging.h" #include "msc_util.h" @@ -423,10 +426,26 @@ static apr_status_t module_cleanup(void *data) { return APR_SUCCESS; } +/** + * Generate a single variable for use with mod_log_config. + */ +static const char *modsec_var_log_handler(request_rec *r, char *name) { + modsec_rec *msr = NULL; + + if (name == NULL) return NULL; + + msr = retrieve_tx_context(r); + if (msr == NULL) return NULL; + + return construct_single_var(msr, name); +} + /** * Pre-configuration initialisation hook. */ static int hook_pre_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_temp) { + static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register; + /* Initialise ModSecurity engine */ modsecurity = modsecurity_create(mp, MODSEC_ONLINE); if (modsecurity == NULL) { @@ -434,6 +453,11 @@ static int hook_pre_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_te "ModSecurity: Failed to initialise engine."); return HTTP_INTERNAL_SERVER_ERROR; } + + log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler); + if (log_pfn_register) { + log_pfn_register(mp, "m", modsec_var_log_handler, 0); + } return OK; } @@ -1104,6 +1128,8 @@ static void register_hooks(apr_pool_t *mp) { "mod_log_config.c", NULL }; + + /* Add the MODSEC_2.x compatibility defines */ *(char **)apr_array_push(ap_server_config_defines) = apr_pstrdup(mp, "MODSEC_2.5"); diff --git a/apache2/msc_util.c b/apache2/msc_util.c index 710a47f5..39bde986 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -1418,3 +1418,32 @@ apr_fileperms_t mode2fileperms(int mode) { return perms; } +/** + * Generate a single variable. + */ +char *construct_single_var(modsec_rec *msr, char *name) { + char *varname = NULL; + char *param = NULL; + msre_var *var = NULL; + msre_var *vx = NULL; + char *my_error_msg = NULL; + + /* Extract variable name and its parameter from the script. */ + varname = apr_pstrdup(msr->mp, name); + param = strchr(varname, '.'); + if (param != NULL) { + *param = '\0'; + param++; + } + + /* Resolve variable. */ + var = msre_create_var_ex(msr->mp, msr->modsecurity->msre, + varname, param, msr, &my_error_msg); + if (var == NULL) return NULL; + + /* Generate variable. */ + vx = generate_single_var(msr, var, NULL, NULL, msr->msc_rule_mptmp); + if (vx == NULL) return NULL; + + return (char *)vx->value; +} diff --git a/apache2/msc_util.h b/apache2/msc_util.h index b1fd1937..5ed6c925 100644 --- a/apache2/msc_util.h +++ b/apache2/msc_util.h @@ -103,4 +103,6 @@ int DSOLOCAL css_decode_inplace(unsigned char *input, long int input_len); apr_fileperms_t DSOLOCAL mode2fileperms(int mode); +char DSOLOCAL *construct_single_var(modsec_rec *msr, char *name); + #endif diff --git a/apache2/re_variables.c b/apache2/re_variables.c index 878bba5a..d5740833 100644 --- a/apache2/re_variables.c +++ b/apache2/re_variables.c @@ -400,6 +400,7 @@ static int var_rule_generate(modsec_rec *msr, msre_var *var, msre_rule *rule, msre_actionset *actionset = NULL; if (rule == NULL) return 0; + actionset = rule->actionset; if (rule->chain_starter != NULL) actionset = rule->chain_starter->actionset;