/** * \brief match the specified filemagic * * \param t thread local vars * \param det_ctx pattern matcher thread local data * \param f *LOCKED* flow * \param flags direction flags * \param file file being inspected * \param s signature being inspected * \param m sigmatch that we will cast into DetectFilemagicData * * \retval 0 no match * \retval 1 match */ static int DetectFilemagicMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t flags, File *file, Signature *s, SigMatch *m) { SCEnter(); int ret = 0; DetectFilemagicData *filemagic = (DetectFilemagicData *)m->ctx; if (file->txid < det_ctx->tx_id) SCReturnInt(0); if (file->txid > det_ctx->tx_id) SCReturnInt(0); DetectFilemagicThreadData *tfilemagic = (DetectFilemagicThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, filemagic->thread_ctx_id); if (tfilemagic == NULL) { SCReturnInt(0); } if (file->magic == NULL) { FilemagicThreadLookup(&tfilemagic->ctx, file); } if (file->magic != NULL) { SCLogDebug("magic %s", file->magic); /* we include the \0 in the inspection, so patterns can match on the * end of the string. */ if (BoyerMooreNocase(filemagic->name, filemagic->len, (uint8_t *)file->magic, strlen(file->magic) + 1, filemagic->bm_ctx) != NULL) { #ifdef DEBUG if (SCLogDebugEnabled()) { char *name = SCMalloc(filemagic->len + 1); if (name != NULL) { memcpy(name, filemagic->name, filemagic->len); name[filemagic->len] = '\0'; SCLogDebug("will look for filemagic %s", name); } } #endif if (!(filemagic->flags & DETECT_CONTENT_NEGATED)) { ret = 1; } } else if (filemagic->flags & DETECT_CONTENT_NEGATED) { SCLogDebug("negated match"); ret = 1; } } SCReturnInt(ret); }
/** * \brief match the specified luajit * * \param t thread local vars * \param det_ctx pattern matcher thread local data * \param p packet * \param s signature being inspected * \param m sigmatch that we will cast into DetectLuajitData * * \retval 0 no match * \retval 1 match */ static int DetectLuajitMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *m) { SCEnter(); int ret = 0; DetectLuajitData *luajit = (DetectLuajitData *)m->ctx; if (luajit == NULL) SCReturnInt(0); DetectLuajitThreadData *tluajit = (DetectLuajitThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id); if (tluajit == NULL) SCReturnInt(0); if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len == 0) SCReturnInt(0); if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p) == 0) SCReturnInt(0); if (tluajit->alproto != ALPROTO_UNKNOWN) { if (p->flow == NULL) SCReturnInt(0); FLOWLOCK_RDLOCK(p->flow); int alproto = p->flow->alproto; FLOWLOCK_UNLOCK(p->flow); if (tluajit->alproto != alproto) SCReturnInt(0); } lua_getglobal(tluajit->luastate, "match"); lua_newtable(tluajit->luastate); /* stack at -1 */ if ((tluajit->flags & DATATYPE_PAYLOAD) && p->payload_len) { lua_pushliteral(tluajit->luastate, "payload"); /* stack at -2 */ lua_pushlstring (tluajit->luastate, (const char *)p->payload, (size_t)p->payload_len); /* stack at -3 */ lua_settable(tluajit->luastate, -3); } if ((tluajit->flags & DATATYPE_PACKET) && GET_PKT_LEN(p)) { lua_pushliteral(tluajit->luastate, "packet"); /* stack at -2 */ lua_pushlstring (tluajit->luastate, (const char *)GET_PKT_DATA(p), (size_t)GET_PKT_LEN(p)); /* stack at -3 */ lua_settable(tluajit->luastate, -3); } if (tluajit->alproto == ALPROTO_HTTP) { FLOWLOCK_RDLOCK(p->flow); HtpState *htp_state = p->flow->alstate; if (htp_state != NULL && htp_state->connp != NULL && htp_state->connp->conn != NULL) { int idx = AppLayerTransactionGetInspectId(p->flow); if (idx != -1) { htp_tx_t *tx = NULL; int size = (int)list_size(htp_state->connp->conn->transactions); for ( ; idx < size; idx++) { tx = list_get(htp_state->connp->conn->transactions, idx); if (tx == NULL) continue; 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_pushlstring (tluajit->luastate, (const char *)bstr_ptr(tx->request_line), bstr_len(tx->request_line)); lua_settable(tluajit->luastate, -3); } } } } FLOWLOCK_UNLOCK(p->flow); } 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); } } if (luajit->negated) { if (ret == 1) ret = 0; else ret = 1; } SCReturnInt(ret); }
int DetectLuajitMatchBuffer(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, uint8_t *buffer, uint32_t buffer_len, uint32_t offset) { SCEnter(); int ret = 0; if (buffer == NULL || buffer_len == 0) SCReturnInt(0); DetectLuajitData *luajit = (DetectLuajitData *)sm->ctx; if (luajit == NULL) SCReturnInt(0); DetectLuajitThreadData *tluajit = (DetectLuajitThreadData *)DetectThreadCtxGetKeywordThreadCtx(det_ctx, luajit->thread_ctx_id); if (tluajit == NULL) SCReturnInt(0); lua_getglobal(tluajit->luastate, "match"); lua_newtable(tluajit->luastate); /* stack at -1 */ lua_pushliteral (tluajit->luastate, "offset"); /* stack at -2 */ lua_pushnumber (tluajit->luastate, (int)(offset + 1)); lua_settable(tluajit->luastate, -3); lua_pushstring (tluajit->luastate, luajit->buffername); /* stack at -2 */ lua_pushlstring (tluajit->luastate, (const char *)buffer, (size_t)buffer_len); 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); } } else { SCLogDebug("no stack"); } if (luajit->negated) { if (ret == 1) ret = 0; else ret = 1; } SCReturnInt(ret); }