diff --git a/apache2/msc_lua.c b/apache2/msc_lua.c index 59ac1f05..b59b5bd9 100644 --- a/apache2/msc_lua.c +++ b/apache2/msc_lua.c @@ -79,7 +79,7 @@ char *lua_compile(msc_script **script, const char *filename, apr_pool_t *pool) { /* Find script. */ if (luaL_loadfile(L, filename)) { - return apr_psprintf(pool, "ModSecurity: Failed to open script %s: %s", + return apr_psprintf(pool, "ModSecurity: Failed to compile script %s: %s", filename, lua_tostring(L, -1)); } @@ -244,7 +244,7 @@ static const struct luaL_Reg mylib[] = { /** * */ -int lua_execute(msre_rule *rule, modsec_rec *msr, char **error_msg) { +int lua_execute(msc_script *script, modsec_rec *msr, msre_rule *rule, char **error_msg) { apr_time_t time_before; lua_State *L = NULL; int rc; @@ -253,7 +253,7 @@ int lua_execute(msre_rule *rule, modsec_rec *msr, char **error_msg) { *error_msg = NULL; if (msr->txcfg->debuglog_level >= 8) { - msr_log(msr, 8, "Lua: Executing script: %s", rule->script->name); + msr_log(msr, 8, "Lua: Executing script: %s", script->name); } time_before = apr_time_now(); @@ -268,13 +268,15 @@ int lua_execute(msre_rule *rule, modsec_rec *msr, char **error_msg) { lua_setglobal(L, "__msr"); /* Associate rule with the state. */ - lua_pushlightuserdata(L, (void *)rule); - lua_setglobal(L, "__rule"); + if (rule != NULL) { + lua_pushlightuserdata(L, (void *)rule); + lua_setglobal(L, "__rule"); + } /* Register functions. */ luaL_register(L, "m", mylib); - rc = lua_restore(L, rule->script); + rc = lua_restore(L, script); if (rc) { *error_msg = apr_psprintf(msr->mp, "Lua: Failed to restore script with %i.", rc); return -1; @@ -291,8 +293,11 @@ int lua_execute(msre_rule *rule, modsec_rec *msr, char **error_msg) { return -1; } - // TODO Who will need to free msg? + // Get the response from the script. *error_msg = (char *)lua_tostring(L, -1); + if (*error_msg != NULL) { + *error_msg = apr_pstrdup(msr->mp, *error_msg); + } /* Destroy state. */ lua_pop(L, 1); diff --git a/apache2/msc_lua.h b/apache2/msc_lua.h index fb43f35c..2fac7674 100644 --- a/apache2/msc_lua.h +++ b/apache2/msc_lua.h @@ -36,7 +36,7 @@ struct msc_script_part { char DSOLOCAL *lua_compile(msc_script **script, const char *filename, apr_pool_t *pool); -int DSOLOCAL lua_execute(msre_rule *rule, modsec_rec *msr, char **error_msg); +int DSOLOCAL lua_execute(msc_script *script, modsec_rec *msr, msre_rule *rule, char **error_msg); #endif #endif diff --git a/apache2/re.c b/apache2/re.c index 70e33f53..9d121c39 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -1966,7 +1966,7 @@ static apr_status_t msre_rule_process_lua(msre_rule *rule, modsec_rec *msr) { acting_actionset = rule->chain_starter->actionset; } - rc = lua_execute(rule, msr, &my_error_msg); + rc = lua_execute(rule->script, msr, rule, &my_error_msg); if (rc < 0) { msr_log(msr, 1, "%s", my_error_msg); return -1; diff --git a/apache2/re_actions.c b/apache2/re_actions.c index 55ebb46a..ccba553a 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -1452,15 +1452,50 @@ static apr_status_t msre_action_setuid_execute(modsec_rec *msr, apr_pool_t *mptm } /* exec */ +static char *msre_action_exec_validate(msre_engine *engine, msre_action *action) { + char *filename = (char *)action->param; + + /* TODO Support relative filenames. */ + + #ifdef WITH_LUA + /* Process Lua scripts internally. */ + if (strlen(filename) > 4) { + char *p = filename + strlen(filename) - 4; + if ((p[0] == '.')&&(p[1] == 'l')&&(p[2] == 'u')&&(p[3] == 'a')) { + /* It's a Lua script. */ + msc_script *script = NULL; + + /* Compile script. */ + char *msg = lua_compile(&script, filename, engine->mp); + if (msg != NULL) return msg; + + action->param_data = script; + } + } + #endif + + return NULL; +} + static apr_status_t msre_action_exec_execute(modsec_rec *msr, apr_pool_t *mptmp, msre_rule *rule, msre_action *action) { - char *script_output = NULL; + if (action->param_data != NULL) { /* Lua */ + msc_script *script = (msc_script *)action->param_data; + char *my_error_msg = NULL; - int rc = apache2_exec(msr, action->param, NULL, &script_output); - if (rc != 1) { - msr_log(msr, 1, "Failed to execute: %s", action->param); - return 0; + if (lua_execute(script, msr, rule, &my_error_msg) < 0) { + msr_log(msr, 1, "%s", my_error_msg); + return 0; + } + } else { /* Execute as shell script. */ + char *script_output = NULL; + + int rc = apache2_exec(msr, action->param, NULL, &script_output); + if (rc != 1) { + msr_log(msr, 1, "Failed to execute: %s", action->param); + return 0; + } } return 1; @@ -1932,7 +1967,7 @@ void msre_engine_register_default_actions(msre_engine *engine) { 1, 1, NO_PLUS_MINUS, ACTION_CARDINALITY_MANY, - NULL, + msre_action_exec_validate, NULL, msre_action_exec_execute );