Beispiel #1
0
/**
 *  \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);
}
Beispiel #2
0
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);
}
Beispiel #4
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);
}
Beispiel #5
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;
}