lua: fix http.request_line inspection

As there is no inspection engine for request_line, the sigmatch was
added to the AMATCH list. However, no AppLayerMatch function for
lua scripts was defined.

This patch defines a AppLayerMatch function.

Bug #1273.
pull/1126/head
Victor Julien 11 years ago
parent 8b4615f8e7
commit c152ddf072

@ -109,6 +109,8 @@ static pthread_mutex_t luajit_states_lock = SCMUTEX_INITIALIZER;
static int DetectLuaMatch (ThreadVars *, DetectEngineThreadCtx *,
Packet *, Signature *, SigMatch *);
static int DetectLuaAppMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m);
static int DetectLuaSetup (DetectEngineCtx *, Signature *, char *);
static void DetectLuaRegisterTests(void);
static void DetectLuaFree(void *);
@ -123,6 +125,7 @@ void DetectLuaRegister(void)
sigmatch_table[DETECT_LUA].desc = "match via a luajit script";
sigmatch_table[DETECT_LUA].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Lua_scripting";
sigmatch_table[DETECT_LUA].Match = DetectLuaMatch;
sigmatch_table[DETECT_LUA].AppLayerMatch = DetectLuaAppMatch;
sigmatch_table[DETECT_LUA].Setup = DetectLuaSetup;
sigmatch_table[DETECT_LUA].Free = DetectLuaFree;
sigmatch_table[DETECT_LUA].RegisterTests = DetectLuaRegisterTests;
@ -505,6 +508,118 @@ static int DetectLuaMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
SCReturnInt(ret);
}
/**
* \brief match the specified lua script in AMATCH
*
* \param t thread local vars
* \param det_ctx pattern matcher thread local data
* \param s signature being inspected
* \param m sigmatch that we will cast into DetectLuaData
*
* \retval 0 no match
* \retval 1 match
*/
static int DetectLuaAppMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s, SigMatch *m)
{
SCEnter();
int ret = 0;
DetectLuaData *luajit = (DetectLuaData *)m->ctx;
if (luajit == NULL)
SCReturnInt(0);
DetectLuaThreadData *tluajit = (DetectLuaThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id);
if (tluajit == NULL)
SCReturnInt(0);
/* setup extension data for use in lua c functions */
LuaExtensionsMatchSetup(tluajit->luastate, luajit, det_ctx,
f, /* flow is locked */LUA_FLOW_LOCKED_BY_PARENT, NULL);
if (tluajit->alproto != ALPROTO_UNKNOWN) {
int alproto = f->alproto;
if (tluajit->alproto != alproto)
SCReturnInt(0);
}
lua_getglobal(tluajit->luastate, "match");
lua_newtable(tluajit->luastate); /* stack at -1 */
if (tluajit->alproto == ALPROTO_HTTP) {
HtpState *htp_state = state;
if (htp_state != NULL && htp_state->connp != NULL) {
htp_tx_t *tx = NULL;
tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP, htp_state, det_ctx->tx_id);
if (tx != NULL) {
if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL &&
bstr_len(tx->request_line) > 0) {
lua_pushliteral(tluajit->luastate, "http.request_line"); /* stack at -2 */
LuaPushStringBuffer(tluajit->luastate,
(const uint8_t *)bstr_ptr(tx->request_line),
bstr_len(tx->request_line));
lua_settable(tluajit->luastate, -3);
}
}
}
}
int retval = lua_pcall(tluajit->luastate, 1, 1, 0);
if (retval != 0) {
SCLogInfo("failed to run script: %s", lua_tostring(tluajit->luastate, -1));
}
/* process returns from script */
if (lua_gettop(tluajit->luastate) > 0) {
/* script returns a number (return 1 or return 0) */
if (lua_type(tluajit->luastate, 1) == LUA_TNUMBER) {
double script_ret = lua_tonumber(tluajit->luastate, 1);
SCLogDebug("script_ret %f", script_ret);
lua_pop(tluajit->luastate, 1);
if (script_ret == 1.0)
ret = 1;
/* script returns a table */
} else if (lua_type(tluajit->luastate, 1) == LUA_TTABLE) {
lua_pushnil(tluajit->luastate);
const char *k, *v;
while (lua_next(tluajit->luastate, -2)) {
v = lua_tostring(tluajit->luastate, -1);
lua_pop(tluajit->luastate, 1);
k = lua_tostring(tluajit->luastate, -1);
if (!k || !v)
continue;
SCLogDebug("k='%s', v='%s'", k, v);
if (strcmp(k, "retval") == 0) {
if (atoi(v) == 1)
ret = 1;
} else {
/* set flow var? */
}
}
/* pop the table */
lua_pop(tluajit->luastate, 1);
}
}
while (lua_gettop(tluajit->luastate) > 0) {
lua_pop(tluajit->luastate, 1);
}
if (luajit->negated) {
if (ret == 1)
ret = 0;
else
ret = 1;
}
SCReturnInt(ret);
}
#ifdef UNITTESTS
/* if this ptr is set the luajit setup functions will use this buffer as the
* lua script instead of calling luaL_loadfile on the filename supplied. */

Loading…
Cancel
Save