|
|
|
@ -61,9 +61,15 @@
|
|
|
|
|
#ifdef HAVE_LIBJANSSON
|
|
|
|
|
#include <jansson.h>
|
|
|
|
|
|
|
|
|
|
#define LOG_DROP_ALERTS 1
|
|
|
|
|
|
|
|
|
|
typedef struct JsonDropOutputCtx_ {
|
|
|
|
|
LogFileCtx *file_ctx;
|
|
|
|
|
uint8_t flags;
|
|
|
|
|
} JsonDropOutputCtx;
|
|
|
|
|
|
|
|
|
|
typedef struct JsonDropLogThread_ {
|
|
|
|
|
/** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
|
|
|
|
|
LogFileCtx* file_ctx;
|
|
|
|
|
JsonDropOutputCtx *drop_ctx;
|
|
|
|
|
MemBuffer *buffer;
|
|
|
|
|
} JsonDropLogThread;
|
|
|
|
|
|
|
|
|
@ -135,20 +141,22 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
|
|
|
|
|
}
|
|
|
|
|
json_object_set_new(js, "drop", djs);
|
|
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < p->alerts.cnt; i++) {
|
|
|
|
|
const PacketAlert *pa = &p->alerts.alerts[i];
|
|
|
|
|
if (unlikely(pa->s == NULL)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) ||
|
|
|
|
|
((pa->action & ACTION_DROP) && EngineModeIsIPS()))
|
|
|
|
|
{
|
|
|
|
|
AlertJsonHeader(pa, js);
|
|
|
|
|
if (aft->drop_ctx->flags & LOG_DROP_ALERTS) {
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < p->alerts.cnt; i++) {
|
|
|
|
|
const PacketAlert *pa = &p->alerts.alerts[i];
|
|
|
|
|
if (unlikely(pa->s == NULL)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if ((pa->action & (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)) ||
|
|
|
|
|
((pa->action & ACTION_DROP) && EngineModeIsIPS()))
|
|
|
|
|
{
|
|
|
|
|
AlertJsonHeader(pa, js);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OutputJSONBuffer(js, aft->file_ctx, buffer);
|
|
|
|
|
OutputJSONBuffer(js, aft->drop_ctx->file_ctx, buffer);
|
|
|
|
|
json_object_del(js, "drop");
|
|
|
|
|
json_object_clear(js);
|
|
|
|
|
json_decref(js);
|
|
|
|
@ -163,6 +171,7 @@ static TmEcode JsonDropLogThreadInit(ThreadVars *t, void *initdata, void **data)
|
|
|
|
|
if (unlikely(aft == NULL))
|
|
|
|
|
return TM_ECODE_FAILED;
|
|
|
|
|
memset(aft, 0, sizeof(*aft));
|
|
|
|
|
|
|
|
|
|
if(initdata == NULL)
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("Error getting context for AlertFastLog. \"initdata\" argument NULL");
|
|
|
|
@ -177,7 +186,7 @@ static TmEcode JsonDropLogThreadInit(ThreadVars *t, void *initdata, void **data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Use the Ouptut Context (file pointer and mutex) */
|
|
|
|
|
aft->file_ctx = ((OutputCtx *)initdata)->data;
|
|
|
|
|
aft->drop_ctx = ((OutputCtx *)initdata)->data;
|
|
|
|
|
|
|
|
|
|
*data = (void *)aft;
|
|
|
|
|
return TM_ECODE_OK;
|
|
|
|
@ -216,6 +225,15 @@ static void JsonDropLogDeInitCtxSub(OutputCtx *output_ctx)
|
|
|
|
|
SCFree(output_ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void JsonDropOutputCtxFree(JsonDropOutputCtx *drop_ctx)
|
|
|
|
|
{
|
|
|
|
|
if (drop_ctx != NULL) {
|
|
|
|
|
if (drop_ctx->file_ctx != NULL)
|
|
|
|
|
LogFileFreeCtx(drop_ctx->file_ctx);
|
|
|
|
|
SCFree(drop_ctx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define DEFAULT_LOG_FILENAME "drop.json"
|
|
|
|
|
static OutputCtx *JsonDropLogInitCtx(ConfNode *conf)
|
|
|
|
|
{
|
|
|
|
@ -225,22 +243,37 @@ static OutputCtx *JsonDropLogInitCtx(ConfNode *conf)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LogFileCtx *logfile_ctx = LogFileNewCtx();
|
|
|
|
|
if (logfile_ctx == NULL) {
|
|
|
|
|
JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx));
|
|
|
|
|
if (drop_ctx == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
drop_ctx->file_ctx = LogFileNewCtx();
|
|
|
|
|
if (drop_ctx->file_ctx == NULL) {
|
|
|
|
|
JsonDropOutputCtxFree(drop_ctx);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME) < 0) {
|
|
|
|
|
LogFileFreeCtx(logfile_ctx);
|
|
|
|
|
if (SCConfLogOpenGeneric(conf, drop_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) {
|
|
|
|
|
JsonDropOutputCtxFree(drop_ctx);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
|
|
|
|
|
if (unlikely(output_ctx == NULL)) {
|
|
|
|
|
JsonDropOutputCtxFree(drop_ctx);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output_ctx->data = logfile_ctx;
|
|
|
|
|
if (conf) {
|
|
|
|
|
const char *extended = ConfNodeLookupChildValue(conf, "alerts");
|
|
|
|
|
if (extended != NULL) {
|
|
|
|
|
if (ConfValIsTrue(extended)) {
|
|
|
|
|
drop_ctx->flags = LOG_DROP_ALERTS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output_ctx->data = drop_ctx;
|
|
|
|
|
output_ctx->DeInit = JsonDropLogDeInitCtx;
|
|
|
|
|
return output_ctx;
|
|
|
|
|
}
|
|
|
|
@ -255,12 +288,28 @@ static OutputCtx *JsonDropLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx)
|
|
|
|
|
|
|
|
|
|
AlertJsonThread *ajt = parent_ctx->data;
|
|
|
|
|
|
|
|
|
|
JsonDropOutputCtx *drop_ctx = SCCalloc(1, sizeof(*drop_ctx));
|
|
|
|
|
if (drop_ctx == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
|
|
|
|
|
if (unlikely(output_ctx == NULL)) {
|
|
|
|
|
JsonDropOutputCtxFree(drop_ctx);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
output_ctx->data = ajt->file_ctx;
|
|
|
|
|
if (conf) {
|
|
|
|
|
const char *extended = ConfNodeLookupChildValue(conf, "alerts");
|
|
|
|
|
if (extended != NULL) {
|
|
|
|
|
if (ConfValIsTrue(extended)) {
|
|
|
|
|
drop_ctx->flags = LOG_DROP_ALERTS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
drop_ctx->file_ctx = ajt->file_ctx;
|
|
|
|
|
|
|
|
|
|
output_ctx->data = drop_ctx;
|
|
|
|
|
output_ctx->DeInit = JsonDropLogDeInitCtxSub;
|
|
|
|
|
return output_ctx;
|
|
|
|
|
}
|
|
|
|
|