* \retval -1 error
* \retval 0 ok
*/
-int FilemagicGlobalLookup(File *file)
-{
- if (file == NULL || FileDataSize(file) == 0) {
- SCReturnInt(-1);
- }
-
- const uint8_t *data = NULL;
- uint32_t data_len = 0;
- uint64_t offset = 0;
-
- StreamingBufferGetData(file->sb,
- &data, &data_len, &offset);
- if (offset == 0) {
- if (FileDataSize(file) >= FILEMAGIC_MIN_SIZE) {
- file->magic = MagicGlobalLookup(data, data_len);
- } else if (file->state >= FILE_STATE_CLOSED) {
- file->magic = MagicGlobalLookup(data, data_len);
- }
- }
-
- SCReturnInt(0);
-}
-
-/**
- * \brief run the magic check
- *
- * \param file the file
- *
- * \retval -1 error
- * \retval 0 ok
- */
-static int FilemagicThreadLookup(magic_t *ctx, File *file)
+int FilemagicThreadLookup(magic_t *ctx, File *file)
{
if (ctx == NULL || file == NULL || FileDataSize(file) == 0) {
SCReturnInt(-1);
static void *DetectFilemagicThreadInit(void *data /*@unused@*/)
{
- const char *filename = NULL;
- FILE *fd = NULL;
-
DetectFilemagicThreadData *t = SCCalloc(1, sizeof(DetectFilemagicThreadData));
if (unlikely(t == NULL)) {
SCLogError(SC_ERR_MEM_ALLOC, "couldn't alloc ctx memory");
return NULL;
}
- t->ctx = magic_open(0);
- if (t->ctx == NULL) {
- SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s", magic_error(t->ctx));
+ t->ctx = MagicInitContext();
+ if (t->ctx == NULL)
goto error;
- }
-
- (void)ConfGet("magic-file", &filename);
- if (filename != NULL) {
- if (strlen(filename) == 0) {
- /* set filename to NULL on *nix systems so magic_load uses system default path (see man libmagic) */
- SCLogInfo("using system default magic-file");
- filename = NULL;
- }
- else {
- SCLogInfo("using magic-file %s", filename);
-
- if ( (fd = fopen(filename, "r")) == NULL) {
- SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s", filename, strerror(errno));
- goto error;
- }
- fclose(fd);
- }
- }
-
- if (magic_load(t->ctx, filename) != 0) {
- SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s", magic_error(t->ctx));
- goto error;
- }
return (void *)t;
#include "conf.h"
#include "util-profiling.h"
#include "util-validate.h"
+#include "util-magic.h"
typedef struct OutputLoggerThreadStore_ {
void *thread_data;
* data for the packet loggers. */
typedef struct OutputLoggerThreadData_ {
OutputLoggerThreadStore *store;
+#ifdef HAVE_MAGIC
+ magic_t magic_ctx;
+#endif
} OutputLoggerThreadData;
/* logger instance, a module + a output ctx,
return file_logged;
}
-static void OutputFiledataLogFfc(ThreadVars *tv, OutputLoggerThreadStore *store,
+static void OutputFiledataLogFfc(ThreadVars *tv, OutputLoggerThreadData *td,
Packet *p, FileContainer *ffc, const uint8_t call_flags,
const bool file_close, const bool file_trunc, const uint8_t dir)
{
if (ffc != NULL) {
+ OutputLoggerThreadStore *store = td->store;
File *ff;
for (ff = ffc->head; ff != NULL; ff = ff->next) {
uint8_t file_flags = call_flags;
#ifdef HAVE_MAGIC
if (FileForceMagic() && ff->magic == NULL) {
- FilemagicGlobalLookup(ff);
+ FilemagicThreadLookup(&td->magic_ctx, ff);
}
#endif
SCLogDebug("ff %p", ff);
}
OutputLoggerThreadData *op_thread_data = (OutputLoggerThreadData *)thread_data;
- OutputLoggerThreadStore *store = op_thread_data->store;
/* no flow, no files */
Flow * const f = p->flow;
FileContainer *ffc_ts = AppLayerParserGetFiles(f, STREAM_TOSERVER);
FileContainer *ffc_tc = AppLayerParserGetFiles(f, STREAM_TOCLIENT);
SCLogDebug("ffc_ts %p", ffc_ts);
- OutputFiledataLogFfc(tv, store, p, ffc_ts, STREAM_TOSERVER, file_close_ts, file_trunc, STREAM_TOSERVER);
+ OutputFiledataLogFfc(tv, op_thread_data, p, ffc_ts, STREAM_TOSERVER, file_close_ts, file_trunc, STREAM_TOSERVER);
SCLogDebug("ffc_tc %p", ffc_tc);
- OutputFiledataLogFfc(tv, store, p, ffc_tc, STREAM_TOCLIENT, file_close_tc, file_trunc, STREAM_TOCLIENT);
+ OutputFiledataLogFfc(tv, op_thread_data, p, ffc_tc, STREAM_TOCLIENT, file_close_tc, file_trunc, STREAM_TOCLIENT);
return TM_ECODE_OK;
}
*data = (void *)td;
+#ifdef HAVE_MAGIC
+ td->magic_ctx = MagicInitContext();
+ if (td->magic_ctx == NULL) {
+ SCFree(td);
+ return TM_ECODE_FAILED;
+ }
+#endif
+
SCLogDebug("OutputFiledataLogThreadInit happy (*data %p)", *data);
OutputFiledataLogger *logger = list;
}
SCMutexUnlock(&g_waldo_mutex);
+#ifdef HAVE_MAGIC
+ MagicDeinitContext(op_thread_data->magic_ctx);
+#endif
+
SCFree(op_thread_data);
return TM_ECODE_OK;
}
#include "util-magic.h"
#ifdef HAVE_MAGIC
-static magic_t g_magic_ctx = NULL;
-static SCMutex g_magic_lock;
/**
- * \brief Initialize the "magic" context.
+ * \brief Initialize a "magic" context.
*/
-int MagicInit(void)
+magic_t MagicInitContext(void)
{
- BUG_ON(g_magic_ctx != NULL);
-
- SCEnter();
-
+ magic_t ctx;
const char *filename = NULL;
FILE *fd = NULL;
- SCMutexInit(&g_magic_lock, NULL);
- SCMutexLock(&g_magic_lock);
-
- g_magic_ctx = magic_open(0);
- if (g_magic_ctx == NULL) {
+ ctx = magic_open(0);
+ if (ctx == NULL) {
SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s",
- magic_error(g_magic_ctx));
+ magic_error(ctx));
goto error;
}
}
}
- if (magic_load(g_magic_ctx, filename) != 0) {
+ if (magic_load(ctx, filename) != 0) {
SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s",
- magic_error(g_magic_ctx));
+ magic_error(ctx));
goto error;
}
-
- SCMutexUnlock(&g_magic_lock);
- SCReturnInt(0);
+ return ctx;
error:
- if (g_magic_ctx != NULL) {
- magic_close(g_magic_ctx);
- g_magic_ctx = NULL;
+ if (ctx != NULL) {
+ magic_close(ctx);
+ ctx = NULL;
}
-
- SCMutexUnlock(&g_magic_lock);
- SCReturnInt(-1);
+ return NULL;
}
-/**
- * \brief Find the magic value for a buffer.
- *
- * \param buf the buffer
- * \param buflen length of the buffer
- *
- * \retval result pointer to null terminated string
- */
-char *MagicGlobalLookup(const uint8_t *buf, uint32_t buflen)
-{
- const char *result = NULL;
- char *magic = NULL;
-
- SCMutexLock(&g_magic_lock);
-
- if (buf != NULL && buflen > 0) {
- result = magic_buffer(g_magic_ctx, (void *)buf, (size_t)buflen);
- if (result != NULL) {
- magic = SCStrdup(result);
- if (unlikely(magic == NULL)) {
- SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup magic");
- }
- }
- }
- SCMutexUnlock(&g_magic_lock);
- SCReturnPtr(magic, "const char");
+void MagicDeinitContext(magic_t ctx)
+{
+ if (ctx != NULL)
+ magic_close(ctx);
}
/**
SCReturnPtr(magic, "const char");
}
-void MagicDeinit(void)
-{
- SCMutexLock(&g_magic_lock);
- if (g_magic_ctx != NULL) {
- magic_close(g_magic_ctx);
- g_magic_ctx = NULL;
- }
- SCMutexUnlock(&g_magic_lock);
- SCMutexDestroy(&g_magic_lock);
-}
-
#ifdef UNITTESTS
#if defined OS_FREEBSD || defined OS_DARWIN
return result;
}
-/** \test magic init through api */
-static int MagicInitTest02(void)
-{
- if (g_magic_ctx != NULL) {
- printf("g_magic_ctx != NULL at start of the test: ");
- return 0;
- }
-
- if (MagicInit() < 0) {
- printf("MagicInit() failure\n");
- return 0;
- }
-
- if (g_magic_ctx == NULL) {
- printf("g_magic_ctx == NULL: ");
- return 0;
- }
-
- MagicDeinit();
-
- if (g_magic_ctx != NULL) {
- printf("g_magic_ctx != NULL at end of the test: ");
- return 0;
- }
-
- return 1;
-}
-
/** \test magic lib calls -- lookup */
static int MagicDetectTest01(void)
{
return retval;
}
+
/** \test magic api calls -- lookup */
static int MagicDetectTest05(void)
{
const char *result = NULL;
+ magic_t ctx = NULL;
uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
size_t buffer_len = sizeof(buffer);
int retval = 0;
- if (MagicInit() < 0) {
- printf("MagicInit() failure\n");
- return 0;
- }
- result = MagicGlobalLookup(buffer, buffer_len);
+ ctx = MagicInitContext();
+ FAIL_IF(ctx == NULL);
+
+ result = MagicThreadLookup(&ctx, buffer, buffer_len);
if (result == NULL || strncmp(result, "PDF document", 12) != 0) {
printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)");
goto end;
retval = 1;
end:
- MagicDeinit();
+ MagicDeinitContext(ctx);
return retval;
}
+
#if 0
/** \test magic api calls -- lookup */
static int MagicDetectTest06(void)
static int MagicDetectTest07(void)
{
const char *result = NULL;
+ magic_t ctx = NULL;
uint8_t buffer[] = {
0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6,
};
size_t buffer_len = sizeof(buffer);
- FAIL_IF(MagicInit() < 0);
+ ctx = MagicInitContext();
+ FAIL_IF(ctx == NULL);
- result = MagicGlobalLookup(buffer, buffer_len);
+ result = MagicThreadLookup(&ctx, buffer, buffer_len);
FAIL_IF_NULL(result);
char *str = strstr(result, "OpenDocument Text");
FAIL_IF_NULL(str);
- MagicDeinit();
+ MagicDeinitContext(ctx);
PASS;
}
static int MagicDetectTest08(void)
{
const char *result = NULL;
+ magic_t ctx = NULL;
uint8_t buffer[] = {
0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08,
0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70,
size_t buffer_len = sizeof(buffer);
int retval = 0;
- if (MagicInit() < 0) {
- printf("MagicInit() failure\n");
- return 0;
- }
+ ctx = MagicInitContext();
+ FAIL_IF(ctx == NULL);
- result = MagicGlobalLookup(buffer, buffer_len);
+ result = MagicThreadLookup(&ctx, buffer, buffer_len);
if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) {
printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)");
goto end;
retval = 1;
end:
- MagicDeinit();
+ MagicDeinitContext(ctx);
return retval;
}
#if 0
static int MagicDetectTest10ValgrindError(void)
{
const char *result = NULL;
+ magic_t ctx = NULL;
uint8_t buffer[] = {
0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2C,
0x01,0x2C,0x00,0x00,0xFF,0xFE,0x00,0x4C,0x53,0x69,0x67,0x6E,0x61,0x74,0x75,0x72,
size_t buffer_len = sizeof(buffer);
int retval = 0;
- if (MagicInit() < 0) {
- printf("MagicInit() failure\n");
- return 0;
- }
- result = MagicGlobalLookup(buffer, buffer_len);
+ ctx = MagicInitContext();
+ FAIL_IF(ctx == NULL);
+
+ result = MagicThreadLookup(&ctx, buffer, buffer_len);
if (result == NULL || strncmp(result, "JPEG", 4) != 0) {
printf("result %p:%s, not \"JPEG\": ", result,result?result:"(null)");
goto end;
retval = 1;
end:
- MagicDeinit();
+ MagicDeinitContext(ctx);
return retval;
}
#ifdef HAVE_MAGIC
#ifdef UNITTESTS
UtRegisterTest("MagicInitTest01", MagicInitTest01);
- UtRegisterTest("MagicInitTest02", MagicInitTest02);
UtRegisterTest("MagicDetectTest01", MagicDetectTest01);
//UtRegisterTest("MagicDetectTest02", MagicDetectTest02, 1);
UtRegisterTest("MagicDetectTest03", MagicDetectTest03);