ftp/eve: Convert FTP logging to use JsonBuilder

This commit converts the FTP logging mechanisms to use JsonBuilder.
pull/5110/head
Jeff Lucovsky 5 years ago committed by Victor Julien
parent a7535099b4
commit 03de315bc2

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2017 Open Information Security Foundation
/* Copyright (C) 2007-2020 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -55,7 +55,6 @@
#include "util-debug.h"
#include "util-memcmp.h"
#include "util-memrchr.h"
#include "util-byte.h"
#include "util-mem.h"
#include "util-misc.h"
@ -1439,36 +1438,31 @@ uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len)
return c == NULL ? len : c - buffer + 1;
}
json_t *JsonFTPDataAddMetadata(const Flow *f)
void JsonFTPDataAddMetadata(const Flow *f, JsonBuilder *jb)
{
const FtpDataState *ftp_state = NULL;
if (f->alstate == NULL)
return NULL;
return;
ftp_state = (FtpDataState *)f->alstate;
json_t *ftpd = json_object();
if (ftpd == NULL)
return NULL;
if (ftp_state->file_name) {
size_t size = ftp_state->file_len * 2 + 1;
char string[size];
BytesToStringBuffer(ftp_state->file_name, ftp_state->file_len, string, size);
json_object_set_new(ftpd, "filename", SCJsonString(string));
jb_set_string_from_bytes(jb, "filename", ftp_state->file_name, ftp_state->file_len);
}
switch (ftp_state->command) {
case FTP_COMMAND_STOR:
json_object_set_new(ftpd, "command", json_string("STOR"));
JB_SET_STRING(jb, "command", "STOR");
break;
case FTP_COMMAND_RETR:
json_object_set_new(ftpd, "command", json_string("RETR"));
JB_SET_STRING(jb, "command", "RETR");
break;
default:
break;
}
return ftpd;
}
/**
* \brief Free memory allocated for global SMTP parser state.
* \brief Free memory allocated for global FTP parser state.
*/
void FTPParserCleanup(void)
{

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
/* Copyright (C) 2007-2020 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -25,6 +25,8 @@
#ifndef __APP_LAYER_FTP_H__
#define __APP_LAYER_FTP_H__
#include "rust.h"
enum {
FTP_STATE_IN_PROGRESS,
FTP_STATE_PORT_DONE,
@ -221,7 +223,7 @@ uint64_t FTPMemuseGlobalCounter(void);
uint64_t FTPMemcapGlobalCounter(void);
uint16_t JsonGetNextLineFromBuffer(const char *buffer, const uint16_t len);
json_t *JsonFTPDataAddMetadata(const Flow *f);
void JsonFTPDataAddMetadata(const Flow *f, JsonBuilder *jb);
#endif /* __APP_LAYER_FTP_H__ */

@ -413,7 +413,6 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
{
MemBuffer *payload = aft->payload_buffer;
AlertJsonOutputCtx *json_output_ctx = aft->json_output_ctx;
json_t *hjs = NULL;
int i;
@ -550,11 +549,7 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
break;
}
case ALPROTO_FTPDATA:
hjs = JsonFTPDataAddMetadata(p->flow);
if (hjs) {
jb_set_jsont(jb, "ftp-data", hjs);
json_decref(hjs);
}
JsonFTPDataAddMetadata(p->flow, jb);
break;
case ALPROTO_DNP3:
AlertJsonDnp3(p->flow, pa->tx_id, jb);

@ -38,7 +38,6 @@
#include "util-buffer.h"
#include "util-debug.h"
#include "util-mem.h"
#include "util-byte.h"
#include "output.h"
#include "output-json.h"
@ -60,41 +59,31 @@ typedef struct LogFTPLogThread_ {
MemBuffer *buffer;
} LogFTPLogThread;
static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx)
static void JsonFTPLogCommand(Flow *f, FTPTransaction *tx, JsonBuilder *jb)
{
json_t *cjs = json_object();
if (!cjs) {
return cjs;
}
/* Preallocate array objects to simplify failure case */
json_t *js_resplist = NULL;
json_t *js_respcode_list = NULL;
JsonBuilder *js_resplist = NULL;
JsonBuilder *js_respcode_list = NULL;
if (!TAILQ_EMPTY(&tx->response_list)) {
js_resplist = json_array();
js_respcode_list = json_array();
js_resplist = jb_new_array();
js_respcode_list = jb_new_array();
if (unlikely(js_resplist == NULL || js_respcode_list == NULL)) {
if (js_resplist) {
json_decref(js_resplist);
} else {
json_decref(js_respcode_list);
}
return cjs;
goto fail;
}
}
json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name));
jb_set_string(jb, "command", tx->command_descriptor->command_name);
uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */
if (tx->request_length > min_length) {
json_object_set_new(cjs, "command_data",
JsonAddStringN((const char *)tx->request + min_length,
tx->request_length - min_length));
} else {
json_object_set_new(cjs, "command_data", json_string(NULL));
jb_set_string_from_bytes(jb,
"command_data",
(const uint8_t *)tx->request + min_length,
tx->request_length - min_length - 1);
}
if (!TAILQ_EMPTY(&tx->response_list)) {
int resp_code_cnt = 0;
int resp_cnt = 0;
FTPString *response;
TAILQ_FOREACH(response, &tx->response_list, next) {
/* handle multiple lines within the response, \r\n delimited */
@ -107,15 +96,15 @@ static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx)
if (pos >= 3) {
/* Gather the completion code if present */
if (isdigit(where[0]) && isdigit(where[1]) && isdigit(where[2])) {
json_array_append_new(js_respcode_list,
JsonAddStringN((const char *)where, 3));
jb_append_string_from_bytes(js_respcode_list, (const uint8_t *)where, 3);
resp_code_cnt++;
offset = 4;
}
}
/* move past 3 character completion code */
if (pos >= offset) {
json_array_append_new(js_resplist,
JsonAddStringN((const char *)where + offset, pos - offset));
jb_append_string_from_bytes(js_resplist, (const uint8_t *)where + offset, pos - offset);
resp_cnt++;
}
where += pos;
@ -123,24 +112,46 @@ static json_t *JsonFTPLogCommand(Flow *f, FTPTransaction *tx)
}
}
json_object_set_new(cjs, "reply", js_resplist);
json_object_set_new(cjs, "completion_code", js_respcode_list);
if (resp_cnt) {
jb_close(js_resplist);
jb_set_object(jb, "reply", js_resplist);
}
jb_free(js_resplist);
if (resp_code_cnt) {
jb_close(js_respcode_list);
jb_set_object(jb, "completion_code", js_respcode_list);
}
jb_free(js_respcode_list);
}
if (tx->dyn_port) {
json_object_set_new(cjs, "dynamic_port", json_integer(tx->dyn_port));
jb_set_uint(jb, "dynamic_port", tx->dyn_port);
}
if (tx->command_descriptor->command == FTP_COMMAND_PORT ||
tx->command_descriptor->command == FTP_COMMAND_EPRT) {
json_object_set_new(cjs, "mode",
json_string((char *)(tx->active ? "active" : "passive")));
if (tx->active) {
JB_SET_STRING(jb, "mode", "active");
} else {
JB_SET_STRING(jb, "mode", "passive");
}
}
if (tx->done) {
JB_SET_STRING(jb, "reply_received", "yes");
} else {
JB_SET_STRING(jb, "reply_received", "no");
}
json_object_set_new(cjs, "reply_received",
json_string((char *)(tx->done ? "yes" : "no")));
return;
return cjs;
fail:
if (js_resplist) {
jb_free(js_resplist);
}
if (js_respcode_list) {
jb_free(js_respcode_list);
}
}
@ -159,27 +170,30 @@ static int JsonFTPLogger(ThreadVars *tv, void *thread_data,
LogFTPLogThread *thread = thread_data;
LogFTPFileCtx *ftp_ctx = thread->ftplog_ctx;
json_t *js = CreateJSONHeaderWithTxId(p, LOG_DIR_FLOW, event_type, tx_id);
if (likely(js)) {
JsonAddCommonOptions(&ftp_ctx->cfg, p, f, js);
json_t *cjs = NULL;
JsonBuilder *jb = CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, event_type, NULL, tx_id);
if (likely(jb)) {
EveAddCommonOptions(&ftp_ctx->cfg, p, f, jb);
jb_open_object(jb, event_type);
if (f->alproto == ALPROTO_FTPDATA) {
cjs = JsonFTPDataAddMetadata(f);
JsonFTPDataAddMetadata(f, jb);
} else {
cjs = JsonFTPLogCommand(f, tx);
JsonFTPLogCommand(f, tx, jb);
}
if (cjs) {
json_object_set_new(js, event_type, cjs);
if (!jb_close(jb)) {
goto fail;
}
MemBufferReset(thread->buffer);
OutputJSONBuffer(js, thread->ftplog_ctx->file_ctx, &thread->buffer);
OutputJsonBuilderBuffer(jb, thread->ftplog_ctx->file_ctx, &thread->buffer);
json_object_clear(js);
json_decref(js);
jb_free(jb);
}
return TM_ECODE_OK;
fail:
jb_free(jb);
return TM_ECODE_FAILED;
}
static void OutputFTPLogDeInitCtxSub(OutputCtx *output_ctx)

Loading…
Cancel
Save