lua: Fix SCRule functions for match scripts

Save Signature structure to lua register so SCRule functions can work
in match scripts, where no PacketAlert is present

Resolves Feature #2450
pull/6629/head
Benjamin Wilkins 4 years ago committed by Victor Julien
parent 9b71f56728
commit e21a50fee6

@ -481,8 +481,8 @@ static int LuaDecrFlowint(lua_State *luastate)
}
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngineThreadCtx *det_ctx,
Flow *f, Packet *p, uint8_t flags)
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld,
DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p, const Signature *s, uint8_t flags)
{
SCLogDebug("det_ctx %p, f %p", det_ctx, f);
@ -491,6 +491,8 @@ void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *ld, DetectEngi
lua_pushlightuserdata(lua_state, (void *)ld);
lua_settable(lua_state, LUA_REGISTRYINDEX);
LuaStateSetSignature(lua_state, s);
LuaStateSetFlow(lua_state, f);
if (det_ctx->tx_id_set) {

@ -27,9 +27,8 @@
#ifdef HAVE_LUA
int LuaRegisterExtensions(lua_State *);
void LuaExtensionsMatchSetup(lua_State *lua_state,
DetectLuaData *, DetectEngineThreadCtx *det_ctx,
Flow *f, Packet *p, uint8_t flags);
void LuaExtensionsMatchSetup(lua_State *lua_state, DetectLuaData *, DetectEngineThreadCtx *det_ctx,
Flow *f, Packet *p, const Signature *s, uint8_t flags);
#endif /* HAVE_LUA */
#endif

@ -231,8 +231,7 @@ int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx,
if (tlua == NULL)
SCReturnInt(0);
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
f, /* no packet in the ctx */NULL, 0);
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, /* no packet in the ctx */ NULL, s, 0);
/* prepare data to pass to script */
lua_getglobal(tlua->luastate, "match");
@ -347,8 +346,7 @@ static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
LuaStateSetThreadVars(tlua->luastate, det_ctx->tv);
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
p->flow, p, flags);
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, p->flow, p, s, flags);
if ((tlua->flags & DATATYPE_PAYLOAD) && p->payload_len == 0)
SCReturnInt(0);
@ -480,8 +478,7 @@ static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
SCReturnInt(0);
/* setup extension data for use in lua c functions */
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx,
f, NULL, flags);
LuaExtensionsMatchSetup(tlua->luastate, lua, det_ctx, f, NULL, s, flags);
if (tlua->alproto != ALPROTO_UNKNOWN) {
int alproto = f->alproto;

@ -548,54 +548,61 @@ static int LuaCallbackFlowId(lua_State *luastate)
}
/** \internal
* \brief fill lua stack with alert info
* \brief fill lua stack with signature info
* \param luastate the lua state
* \param pa pointer to packet alert struct
* \param s pointer to signature struct
* \retval cnt number of data items placed on the stack
*
* Places: sid (number), rev (number), gid (number)
*/
static int LuaCallbackRuleIdsPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
static int LuaCallbackRuleIdsPushToStackFromSignature(lua_State *luastate, const Signature *s)
{
lua_pushinteger(luastate, pa->s->id);
lua_pushinteger(luastate, pa->s->rev);
lua_pushinteger(luastate, pa->s->gid);
lua_pushinteger(luastate, s->id);
lua_pushinteger(luastate, s->rev);
lua_pushinteger(luastate, s->gid);
return 3;
}
/** \internal
* \brief Wrapper for getting tuple info into a lua script
* \retval cnt number of items placed on the stack
*
* Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
* otherwise pulled from Signature in lua registry (for match scripts)
*/
static int LuaCallbackRuleIds(lua_State *luastate)
{
const Signature *s = NULL;
const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
if (pa == NULL)
return LuaCallbackError(luastate, "internal error: no packet");
return LuaCallbackRuleIdsPushToStackFromPacketAlert(luastate, pa);
if (pa != NULL) {
s = pa->s;
} else {
s = LuaStateGetSignature(luastate);
if (s == NULL)
return LuaCallbackError(luastate, "internal error: no packet alert or signature");
}
return LuaCallbackRuleIdsPushToStackFromSignature(luastate, s);
}
/** \internal
* \brief fill lua stack with alert info
* \brief fill lua stack with signature info
* \param luastate the lua state
* \param pa pointer to packet alert struct
* \param s pointer to signature struct
* \retval cnt number of data items placed on the stack
*
* Places: action (string)
*/
static int LuaCallbackRuleActionPushToStackFromPacketAlert(
lua_State *luastate, const PacketAlert *pa)
static int LuaCallbackRuleActionPushToStackFromSignature(lua_State *luastate, const Signature *s)
{
const char *action = "";
if (pa->s->action & ACTION_PASS) {
if (s->action & ACTION_PASS) {
action = "pass";
} else if ((pa->s->action & ACTION_REJECT) || (pa->s->action & ACTION_REJECT_BOTH) ||
(pa->s->action & ACTION_REJECT_DST)) {
} else if ((s->action & ACTION_REJECT) || (s->action & ACTION_REJECT_BOTH) ||
(s->action & ACTION_REJECT_DST)) {
action = "reject";
} else if (pa->s->action & ACTION_DROP) {
} else if (s->action & ACTION_DROP) {
action = "drop";
} else if (pa->s->action & ACTION_ALERT) {
} else if (s->action & ACTION_ALERT) {
action = "alert";
}
lua_pushstring(luastate, action);
@ -605,69 +612,93 @@ static int LuaCallbackRuleActionPushToStackFromPacketAlert(
/** \internal
* \brief Wrapper for getting tuple info into a lua script
* \retval cnt number of items placed on the stack
*
* Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
* otherwise pulled from Signature in lua registry (for match scripts)
*/
static int LuaCallbackRuleAction(lua_State *luastate)
{
const Signature *s = NULL;
const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
if (pa == NULL)
return LuaCallbackError(luastate, "internal error: no packet");
return LuaCallbackRuleActionPushToStackFromPacketAlert(luastate, pa);
if (pa != NULL) {
s = pa->s;
} else {
s = LuaStateGetSignature(luastate);
if (s == NULL)
return LuaCallbackError(luastate, "internal error: no packet alert or signature");
}
return LuaCallbackRuleActionPushToStackFromSignature(luastate, s);
}
/** \internal
* \brief fill lua stack with alert info
* \brief fill lua stack with signature info
* \param luastate the lua state
* \param pa pointer to packet alert struct
* \param s pointer to signature struct
* \retval cnt number of data items placed on the stack
*
* Places: msg (string)
*/
static int LuaCallbackRuleMsgPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
static int LuaCallbackRuleMsgPushToStackFromSignature(lua_State *luastate, const Signature *s)
{
lua_pushstring (luastate, pa->s->msg);
lua_pushstring(luastate, s->msg);
return 1;
}
/** \internal
* \brief Wrapper for getting tuple info into a lua script
* \retval cnt number of items placed on the stack
*
* Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
* otherwise pulled from Signature in lua registry (for match scripts)
*/
static int LuaCallbackRuleMsg(lua_State *luastate)
{
const Signature *s = NULL;
const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
if (pa == NULL)
return LuaCallbackError(luastate, "internal error: no packet");
return LuaCallbackRuleMsgPushToStackFromPacketAlert(luastate, pa);
if (pa != NULL) {
s = pa->s;
} else {
s = LuaStateGetSignature(luastate);
if (s == NULL)
return LuaCallbackError(luastate, "internal error: no packet alert or signature");
}
return LuaCallbackRuleMsgPushToStackFromSignature(luastate, s);
}
/** \internal
* \brief fill lua stack with alert info
* \brief fill lua stack with signature info
* \param luastate the lua state
* \param pa pointer to packet alert struct
* \param s pointer to signature struct
* \retval cnt number of data items placed on the stack
*
* Places: class (string), prio (number)
*/
static int LuaCallbackRuleClassPushToStackFromPacketAlert(lua_State *luastate, const PacketAlert *pa)
static int LuaCallbackRuleClassPushToStackFromSignature(lua_State *luastate, const Signature *s)
{
lua_pushstring (luastate, pa->s->class_msg);
lua_pushnumber (luastate, pa->s->prio);
lua_pushstring(luastate, s->class_msg);
lua_pushinteger(luastate, s->prio);
return 2;
}
/** \internal
* \brief Wrapper for getting tuple info into a lua script
* \retval cnt number of items placed on the stack
*
* Info is pulled from PacketAlert if it exists in lua registry (true for logging scripts)
* otherwise pulled from Signature in lua registry (for match scripts)
*/
static int LuaCallbackRuleClass(lua_State *luastate)
{
const Signature *s = NULL;
const PacketAlert *pa = LuaStateGetPacketAlert(luastate);
if (pa == NULL)
return LuaCallbackError(luastate, "internal error: no packet");
return LuaCallbackRuleClassPushToStackFromPacketAlert(luastate, pa);
if (pa != NULL) {
s = pa->s;
} else {
s = LuaStateGetSignature(luastate);
if (s == NULL)
return LuaCallbackError(luastate, "internal error: no packet alert or signature");
}
return LuaCallbackRuleClassPushToStackFromSignature(luastate, s);
}
static int LuaCallbackLogPath(lua_State *luastate)

@ -97,6 +97,8 @@ const char lua_ext_key_direction[] = "suricata:lua:direction";
/* key for pa (packet alert) pointer */
const char lua_ext_key_pa[] = "suricata:lua:pkt:alert:ptr";
/* key for s (signature) pointer */
const char lua_ext_key_s[] = "suricata:lua:signature:ptr";
/* key for file pointer */
const char lua_ext_key_file[] = "suricata:lua:file:ptr";
/* key for streaming buffer pointer */
@ -195,6 +197,22 @@ void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa)
lua_settable(luastate, LUA_REGISTRYINDEX);
}
/** \brief get signature pointer from the lua state */
Signature *LuaStateGetSignature(lua_State *luastate)
{
lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s);
lua_gettable(luastate, LUA_REGISTRYINDEX);
void *s = lua_touserdata(luastate, -1);
return (Signature *)s;
}
void LuaStateSetSignature(lua_State *luastate, const Signature *s)
{
lua_pushlightuserdata(luastate, (void *)&lua_ext_key_s);
lua_pushlightuserdata(luastate, (void *)s);
lua_settable(luastate, LUA_REGISTRYINDEX);
}
/** \brief get file pointer from the lua state */
File *LuaStateGetFile(lua_State *luastate)
{

@ -63,6 +63,8 @@ Flow *LuaStateGetFlow(lua_State *luastate);
PacketAlert *LuaStateGetPacketAlert(lua_State *luastate);
Signature *LuaStateGetSignature(lua_State *luastate);
/** \brief get file pointer from the lua state */
File *LuaStateGetFile(lua_State *luastate);
@ -83,6 +85,8 @@ void LuaStateSetFlow(lua_State *luastate, Flow *f);
void LuaStateSetPacketAlert(lua_State *luastate, PacketAlert *pa);
void LuaStateSetSignature(lua_State *luastate, const Signature *s);
void LuaStateSetFile(lua_State *luastate, File *file);
void LuaStateSetThreadVars(lua_State *luastate, ThreadVars *tv);

Loading…
Cancel
Save