/** * \brief Inspect the file inspecting keywords against the state * * \param tv thread vars * \param det_ctx detection engine thread ctx * \param f flow * \param s signature to inspect * \param alstate state * \param flags direction flag * * \retval 0 no match * \retval 1 match * \retval 2 can't match * \retval 3 can't match filestore signature * * \note flow is not locked at this time */ int DetectFileInspectGeneric(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id) { SCEnter(); if (alstate == NULL) { SCReturnInt(DETECT_ENGINE_INSPECT_SIG_NO_MATCH); } const uint8_t direction = flags & (STREAM_TOSERVER|STREAM_TOCLIENT); FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, alstate, direction); if (ffc == NULL || ffc->head == NULL) { SCReturnInt(DETECT_ENGINE_INSPECT_SIG_NO_MATCH); } int r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH; int match = DetectFileInspect(tv, det_ctx, f, s, smd, flags, ffc); if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) { r = DETECT_ENGINE_INSPECT_SIG_MATCH; } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH) { SCLogDebug("sid %u can't match on this transaction", s->id); r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH; } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES) { SCLogDebug("sid %u can't match on this transaction (file sig)", s->id); r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES; } else if (match == DETECT_ENGINE_INSPECT_SIG_MATCH_MORE_FILES) { SCLogDebug("match with more files ahead"); r = match; } SCReturnInt(r); }
static TmEcode LogFileLogWrap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq, int ipver) { SCEnter(); LogFileLogThread *aft = (LogFileLogThread *)data; uint8_t flags = 0; /* no flow, no htp state */ if (p->flow == NULL) { SCReturnInt(TM_ECODE_OK); } if (p->flowflags & FLOW_PKT_TOCLIENT) flags |= STREAM_TOCLIENT; else flags |= STREAM_TOSERVER; int file_close = (p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0; int file_trunc = 0; FLOWLOCK_WRLOCK(p->flow); file_trunc = StreamTcpReassembleDepthReached(p); FileContainer *ffc = AppLayerParserGetFiles(IPPROTO_TCP, p->flow->alproto, p->flow->alstate, flags); SCLogDebug("ffc %p", ffc); if (ffc != NULL) { File *ff; for (ff = ffc->head; ff != NULL; ff = ff->next) { if (ff->flags & FILE_LOGGED) continue; if (FileForceMagic() && ff->magic == NULL) { FilemagicGlobalLookup(ff); } SCLogDebug("ff %p", ff); if (file_trunc && ff->state < FILE_STATE_CLOSED) ff->state = FILE_STATE_TRUNCATED; if (ff->state == FILE_STATE_CLOSED || ff->state == FILE_STATE_TRUNCATED || ff->state == FILE_STATE_ERROR || (file_close == 1 && ff->state < FILE_STATE_CLOSED)) { LogFileWriteJsonRecord(aft, p, ff, ipver); ff->flags |= FILE_LOGGED; aft->file_cnt++; } } FilePrune(ffc); } FLOWLOCK_UNLOCK(p->flow); SCReturnInt(TM_ECODE_OK); }
/** * \brief post-match function for filestore * * \param t thread local vars * \param det_ctx pattern matcher thread local data * \param p packet * * The match function for filestore records store candidates in the det_ctx. * When we are sure all parts of the signature matched, we run this function * to finalize the filestore. */ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s) { uint8_t flags = 0; SCEnter(); if (det_ctx->filestore_cnt == 0) { SCReturnInt(0); } if (s->filestore_sm == NULL || p->flow == NULL) { #ifndef DEBUG SCReturnInt(0); #else BUG_ON(1); #endif } if (p->flowflags & FLOW_PKT_TOCLIENT) flags |= STREAM_TOCLIENT; else flags |= STREAM_TOSERVER; if (det_ctx->flow_locked == 0) FLOWLOCK_WRLOCK(p->flow); FileContainer *ffc = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, p->flow->alstate, flags); /* filestore for single files only */ if (s->filestore_sm->ctx == NULL) { uint16_t u; for (u = 0; u < det_ctx->filestore_cnt; u++) { FileStoreFileById(ffc, det_ctx->filestore[u].file_id); } } else { DetectFilestoreData *filestore = (DetectFilestoreData *)s->filestore_sm->ctx; uint16_t u; for (u = 0; u < det_ctx->filestore_cnt; u++) { FilestorePostMatchWithOptions(p, p->flow, filestore, ffc, det_ctx->filestore[u].file_id, det_ctx->filestore[u].tx_id); } } if (det_ctx->flow_locked == 0) FLOWLOCK_UNLOCK(p->flow); SCReturnInt(0); }
/** * \brief post-match function for filestore * * \param t thread local vars * \param det_ctx pattern matcher thread local data * \param p packet * * The match function for filestore records store candidates in the det_ctx. * When we are sure all parts of the signature matched, we run this function * to finalize the filestore. */ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s) { uint8_t flags = 0; SCEnter(); if (det_ctx->filestore_cnt == 0) { SCReturnInt(0); } if (s->filestore_sm == NULL || p->flow == NULL) { #ifndef DEBUG SCReturnInt(0); #else BUG_ON(1); #endif } /* set filestore depth for stream reassembling */ TcpSession *ssn = (TcpSession *)p->flow->protoctx; TcpSessionSetReassemblyDepth(ssn, FileReassemblyDepth()); if (p->flowflags & FLOW_PKT_TOCLIENT) flags |= STREAM_TOCLIENT; else flags |= STREAM_TOSERVER; FileContainer *ffc = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, p->flow->alstate, flags); /* filestore for single files only */ if (s->filestore_sm->ctx == NULL) { uint16_t u; for (u = 0; u < det_ctx->filestore_cnt; u++) { FileStoreFileById(ffc, det_ctx->filestore[u].file_id); } } else { DetectFilestoreData *filestore = (DetectFilestoreData *)s->filestore_sm->ctx; uint16_t u; for (u = 0; u < det_ctx->filestore_cnt; u++) { FilestorePostMatchWithOptions(p, p->flow, filestore, ffc, det_ctx->filestore[u].file_id, det_ctx->filestore[u].tx_id); } } SCReturnInt(0); }
static TmEcode OutputFileLog(ThreadVars *tv, Packet *p, void *thread_data, PacketQueue *pq, PacketQueue *postpq) { BUG_ON(thread_data == NULL); BUG_ON(list == NULL); OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data; OutputFileLogger *logger = list; OutputLoggerThreadStore *store = op_thread_data->store; BUG_ON(logger == NULL && store != NULL); BUG_ON(logger != NULL && store == NULL); BUG_ON(logger == NULL && store == NULL); uint8_t flags = 0; Flow * const f = p->flow; /* no flow, no files */ if (f == NULL) { SCReturnInt(TM_ECODE_OK); } if (p->flowflags & FLOW_PKT_TOCLIENT) flags |= STREAM_TOCLIENT; else flags |= STREAM_TOSERVER; int file_close = (p->flags & PKT_PSEUDO_STREAM_END) ? 1 : 0; int file_trunc = 0; FLOWLOCK_WRLOCK(f); // < need write lock for FilePrune below file_trunc = StreamTcpReassembleDepthReached(p); FileContainer *ffc = AppLayerParserGetFiles(p->proto, f->alproto, f->alstate, flags); SCLogDebug("ffc %p", ffc); if (ffc != NULL) { File *ff; for (ff = ffc->head; ff != NULL; ff = ff->next) { if (ff->flags & FILE_LOGGED) continue; SCLogDebug("ff %p", ff); if (file_trunc && ff->state < FILE_STATE_CLOSED) ff->state = FILE_STATE_TRUNCATED; if (file_close && ff->state < FILE_STATE_CLOSED) ff->state = FILE_STATE_TRUNCATED; if (ff->state == FILE_STATE_CLOSED || ff->state == FILE_STATE_TRUNCATED || ff->state == FILE_STATE_ERROR) { int file_logged = 0; if (FileForceMagic() && ff->magic == NULL) { FilemagicGlobalLookup(ff); } logger = list; store = op_thread_data->store; while (logger && store) { BUG_ON(logger->LogFunc == NULL); SCLogDebug("logger %p", logger); PACKET_PROFILING_TMM_START(p, logger->module_id); logger->LogFunc(tv, store->thread_data, (const Packet *)p, (const File *)ff); PACKET_PROFILING_TMM_END(p, logger->module_id); file_logged = 1; logger = logger->next; store = store->next; BUG_ON(logger == NULL && store != NULL); BUG_ON(logger != NULL && store == NULL); } if (file_logged) { ff->flags |= FILE_LOGGED; } } } FilePrune(ffc); } FLOWLOCK_UNLOCK(f); return TM_ECODE_OK; }