@ -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 . */