luajit: clean up initialization

pull/69/head
Victor Julien 13 years ago
parent c55b618bd4
commit 42646579a8

@ -167,7 +167,7 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
SCReturnInt(0); SCReturnInt(0);
if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p) == 0) if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p) == 0)
SCReturnInt(0); SCReturnInt(0);
if (tluajit->alproto != 0) { if (tluajit->alproto != ALPROTO_UNKNOWN) {
if (p->flow == NULL) if (p->flow == NULL)
SCReturnInt(0); SCReturnInt(0);
@ -204,17 +204,20 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
for ( ; idx < size; idx++) for ( ; idx < size; idx++)
{ {
tx = list_get(htp_state->connp->conn->transactions, idx); tx = list_get(htp_state->connp->conn->transactions, idx);
if (tx == NULL || tx->request_uri_normalized == NULL) if (tx == NULL)
continue; continue;
if ((tluajit->flags & DATATYPE_HTTP_URI) && bstr_len(tx->request_uri_normalized) > 0) { if ((tluajit->flags & DATATYPE_HTTP_URI) && tx->request_uri_normalized != NULL &&
bstr_len(tx->request_uri_normalized) > 0)
{
lua_pushliteral(tluajit->luastate, "http.uri"); /* stack at -2 */ lua_pushliteral(tluajit->luastate, "http.uri"); /* stack at -2 */
lua_pushlstring (tluajit->luastate, lua_pushlstring (tluajit->luastate,
(const char *)bstr_ptr(tx->request_uri_normalized), (const char *)bstr_ptr(tx->request_uri_normalized),
bstr_len(tx->request_uri_normalized)); bstr_len(tx->request_uri_normalized));
lua_settable(tluajit->luastate, -3); lua_settable(tluajit->luastate, -3);
} }
if ((tluajit->flags & DATATYPE_HTTP_REQUEST_LINE) && bstr_len(tx->request_line) > 0) { 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 */ lua_pushliteral(tluajit->luastate, "http.request_line"); /* stack at -2 */
lua_pushlstring (tluajit->luastate, lua_pushlstring (tluajit->luastate,
(const char *)bstr_ptr(tx->request_line), (const char *)bstr_ptr(tx->request_line),
@ -282,103 +285,54 @@ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
} }
static void *DetectLuajitThreadInit(void *data) { static void *DetectLuajitThreadInit(void *data) {
DetectLuajitData *luajit = (DetectLuajitData *)data;
BUG_ON(luajit == NULL);
DetectLuajitThreadData *t = SCMalloc(sizeof(DetectLuajitThreadData)); DetectLuajitThreadData *t = SCMalloc(sizeof(DetectLuajitThreadData));
if (t != NULL) { if (t == NULL) {
SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't alloc ctx memory");
return NULL;
}
memset(t, 0x00, sizeof(DetectLuajitThreadData)); memset(t, 0x00, sizeof(DetectLuajitThreadData));
t->alproto = luajit->alproto;
t->flags = luajit->flags;
t->luastate = luaL_newstate(); t->luastate = luaL_newstate();
BUG_ON(t->luastate == NULL); if (t->luastate == NULL) {
SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1));
goto error;
}
luaL_openlibs(t->luastate); luaL_openlibs(t->luastate);
int status = luaL_loadfile(t->luastate, (char *)data); int status = luaL_loadfile(t->luastate, luajit->filename);
if (status) { if (status) {
fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(t->luastate, -1)); SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(t->luastate, -1));
BUG_ON(1); goto error;
} }
/* prime the script (or something) */ /* prime the script (or something) */
if (lua_pcall(t->luastate, 0, 0, 0) != 0) { if (lua_pcall(t->luastate, 0, 0, 0) != 0) {
fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1)); SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't prime file: %s", lua_tostring(t->luastate, -1));
BUG_ON(1); goto error;
}
lua_getglobal(t->luastate, "init");
if (lua_type(t->luastate, -1) != LUA_TFUNCTION) {
SCLogInfo("no init function in script");
/** \todo proper cleanup */
return NULL;
}
lua_newtable(t->luastate); /* stack at -1 */
if (lua_gettop(t->luastate) == 0 || lua_type(t->luastate, 2) != LUA_TTABLE) {
SCLogInfo("no table setup");
/** \todo proper cleanup */
return NULL;
}
lua_pushliteral(t->luastate, "script_api_ver"); /* stack at -2 */
lua_pushnumber (t->luastate, 1); /* stack at -3 */
lua_settable(t->luastate, -3);
if (lua_pcall(t->luastate, 1, 1, 0) != 0) {
fprintf(stderr, "Couldn't prime file: %s\n", lua_tostring(t->luastate, -1));
BUG_ON(1);
}
/* process returns from script */
if (lua_gettop(t->luastate) == 0) {
SCLogInfo("init function in script should return table, nothing returned");
/** \todo proper cleanup */
return NULL;
}
if (lua_type(t->luastate, 1) != LUA_TTABLE) {
SCLogInfo("init function in script should return table, returned is not table");
/** \todo proper cleanup */
return NULL;
}
lua_pushnil(t->luastate);
const char *k, *v;
while (lua_next(t->luastate, -2)) {
v = lua_tostring(t->luastate, -1);
lua_pop(t->luastate, 1);
k = lua_tostring(t->luastate, -1);
if (!k || !v)
continue;
SCLogDebug("k='%s', v='%s'", k, v);
if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) {
t->flags |= DATATYPE_PACKET;
} else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) {
t->flags |= DATATYPE_PAYLOAD;
} else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) {
/* http types */
t->alproto = ALPROTO_HTTP;
if (strcmp(k, "http.uri") == 0)
t->flags |= DATATYPE_HTTP_URI;
else if (strcmp(k, "http.request_line") == 0)
t->flags |= DATATYPE_HTTP_REQUEST_LINE;
else {
SCLogInfo("unsupported http data type %s", k);
}
} else {
SCLogInfo("unsupported data type %s", k);
}
} }
/* pop the table */ /* pop the table */
lua_pop(t->luastate, 1); lua_pop(t->luastate, 1);
}
return (void *)t; return (void *)t;
error:
if (t->luastate)
lua_close(t->luastate);
SCFree(t);
return NULL;
} }
static void DetectLuajitThreadFree(void *ctx) { static void DetectLuajitThreadFree(void *ctx) {
DetectLuajitThreadData *t = (DetectLuajitThreadData *)ctx; DetectLuajitThreadData *t = (DetectLuajitThreadData *)ctx;
/** \todo lua state cleanup */ lua_close(t->luastate);
SCFree(t); SCFree(t);
} }
@ -421,6 +375,102 @@ error:
return NULL; return NULL;
} }
static int DetectLuaSetupPrime(DetectLuajitData *ld) {
lua_State *luastate = luaL_newstate();
if (luastate == NULL)
goto error;
luaL_openlibs(luastate);
int status = luaL_loadfile(luastate, ld->filename);
if (status) {
SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't load file: %s", lua_tostring(luastate, -1));
goto error;
}
/* prime the script (or something) */
if (lua_pcall(luastate, 0, 0, 0) != 0) {
SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't prime file: %s", lua_tostring(luastate, -1));
goto error;
}
lua_getglobal(luastate, "init");
if (lua_type(luastate, -1) != LUA_TFUNCTION) {
SCLogError(SC_ERR_LUAJIT_ERROR, "no init function in script");
goto error;
}
lua_newtable(luastate); /* stack at -1 */
if (lua_gettop(luastate) == 0 || lua_type(luastate, 2) != LUA_TTABLE) {
SCLogError(SC_ERR_LUAJIT_ERROR, "no table setup");
goto error;
}
lua_pushliteral(luastate, "script_api_ver"); /* stack at -2 */
lua_pushnumber (luastate, 1); /* stack at -3 */
lua_settable(luastate, -3);
if (lua_pcall(luastate, 1, 1, 0) != 0) {
SCLogError(SC_ERR_LUAJIT_ERROR, "couldn't run script 'init' function: %s", lua_tostring(luastate, -1));
goto error;
}
/* process returns from script */
if (lua_gettop(luastate) == 0) {
SCLogError(SC_ERR_LUAJIT_ERROR, "init function in script should return table, nothing returned");
goto error;
}
if (lua_type(luastate, 1) != LUA_TTABLE) {
SCLogError(SC_ERR_LUAJIT_ERROR, "init function in script should return table, returned is not table");
goto error;
}
lua_pushnil(luastate);
const char *k, *v;
while (lua_next(luastate, -2)) {
v = lua_tostring(luastate, -1);
lua_pop(luastate, 1);
k = lua_tostring(luastate, -1);
if (!k || !v)
continue;
SCLogDebug("k='%s', v='%s'", k, v);
if (strcmp(k, "packet") == 0 && strcmp(v, "true") == 0) {
ld->flags |= DATATYPE_PACKET;
} else if (strcmp(k, "payload") == 0 && strcmp(v, "true") == 0) {
ld->flags |= DATATYPE_PAYLOAD;
} else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) {
if (ld->alproto != ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_LUAJIT_ERROR, "can just inspect script against one alproto %s", k);
goto error;
}
/* http types */
ld->alproto = ALPROTO_HTTP;
if (strcmp(k, "http.uri") == 0)
ld->flags |= DATATYPE_HTTP_URI;
else if (strcmp(k, "http.request_line") == 0)
ld->flags |= DATATYPE_HTTP_REQUEST_LINE;
else {
SCLogError(SC_ERR_LUAJIT_ERROR, "unsupported http data type %s", k);
goto error;
}
} else {
SCLogError(SC_ERR_LUAJIT_ERROR, "unsupported data type %s", k);
goto error;
}
}
/* pop the table */
lua_pop(luastate, 1);
lua_close(luastate);
return 0;
error:
lua_close(luastate);
return -1;
}
/** /**
* \brief this function is used to parse luajit options * \brief this function is used to parse luajit options
* \brief into the current signature * \brief into the current signature
@ -442,11 +492,22 @@ static int DetectLuajitSetup (DetectEngineCtx *de_ctx, Signature *s, char *str)
goto error; goto error;
luajit->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "luajit", luajit->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "luajit",
DetectLuajitThreadInit, (void *)luajit->filename, DetectLuajitThreadInit, (void *)luajit,
DetectLuajitThreadFree); DetectLuajitThreadFree);
if (luajit->thread_ctx_id == -1) if (luajit->thread_ctx_id == -1)
goto error; goto error;
if (DetectLuaSetupPrime(luajit) == -1) {
goto error;
}
if (luajit->alproto != ALPROTO_UNKNOWN) {
if (s->alproto != ALPROTO_UNKNOWN && luajit->alproto != s->alproto) {
goto error;
}
s->alproto = luajit->alproto;
}
/* Okay so far so good, lets get this into a SigMatch /* Okay so far so good, lets get this into a SigMatch
* and put it in the Signature. */ * and put it in the Signature. */
sm = SigMatchAlloc(); sm = SigMatchAlloc();

@ -40,6 +40,8 @@ typedef struct DetectLuajitData {
int thread_ctx_id; int thread_ctx_id;
int negated; int negated;
char *filename; char *filename;
uint32_t flags;
int alproto;
} DetectLuajitData; } DetectLuajitData;
#endif #endif

@ -232,6 +232,7 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_ERR_NO_MD5_SUPPORT); CASE_CODE (SC_ERR_NO_MD5_SUPPORT);
CASE_CODE (SC_ERR_EVENT_ENGINE); CASE_CODE (SC_ERR_EVENT_ENGINE);
CASE_CODE (SC_ERR_NO_LUAJIT_SUPPORT); CASE_CODE (SC_ERR_NO_LUAJIT_SUPPORT);
CASE_CODE (SC_ERR_LUAJIT_ERROR);
default: default:
return "UNKNOWN_ERROR"; return "UNKNOWN_ERROR";
} }

@ -247,6 +247,7 @@ typedef enum {
SC_ERR_NO_MD5_SUPPORT, SC_ERR_NO_MD5_SUPPORT,
SC_ERR_EVENT_ENGINE, SC_ERR_EVENT_ENGINE,
SC_ERR_NO_LUAJIT_SUPPORT, SC_ERR_NO_LUAJIT_SUPPORT,
SC_ERR_LUAJIT_ERROR,
} SCError; } SCError;
const char *SCErrorToString(SCError); const char *SCErrorToString(SCError);

Loading…
Cancel
Save