suricata
output-json-metadata.c
Go to the documentation of this file.
1 /* Copyright (C) 2013-2016 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Logs vars in JSON format.
24  *
25  */
26 
27 #include "suricata-common.h"
28 #include "debug.h"
29 #include "detect.h"
30 #include "flow.h"
31 #include "conf.h"
32 
33 #include "threads.h"
34 #include "tm-threads.h"
35 #include "threadvars.h"
36 #include "util-debug.h"
37 
38 #include "util-misc.h"
39 #include "util-unittest.h"
40 #include "util-unittest-helper.h"
41 
42 #include "detect-parse.h"
43 #include "detect-engine.h"
44 #include "detect-engine-mpm.h"
45 #include "detect-reference.h"
46 #include "app-layer-parser.h"
47 #include "app-layer-dnp3.h"
48 #include "app-layer-htp.h"
49 #include "app-layer-htp-xff.h"
51 #include "util-syslog.h"
52 #include "util-logopenfile.h"
53 
54 #include "output.h"
55 #include "output-json.h"
56 #include "output-json-metadata.h"
57 
58 #include "util-byte.h"
59 #include "util-privs.h"
60 #include "util-print.h"
61 #include "util-proto-name.h"
62 #include "util-optimize.h"
63 #include "util-buffer.h"
64 #include "util-crypt.h"
65 
66 #define MODULE_NAME "JsonMetadataLog"
67 
68 #ifdef HAVE_LIBJANSSON
69 
70 #define JSON_STREAM_BUFFER_SIZE 4096
71 
72 typedef struct MetadataJsonOutputCtx_ {
73  LogFileCtx* file_ctx;
74  OutputJsonCommonSettings cfg;
75 } MetadataJsonOutputCtx;
76 
77 typedef struct JsonMetadataLogThread_ {
78  /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
79  LogFileCtx* file_ctx;
80  MemBuffer *json_buffer;
81  MetadataJsonOutputCtx* json_output_ctx;
82 } JsonMetadataLogThread;
83 
84 static int MetadataJson(ThreadVars *tv, JsonMetadataLogThread *aft, const Packet *p)
85 {
86  json_t *js = CreateJSONHeader(p, LOG_DIR_PACKET, "metadata");
87  if (unlikely(js == NULL))
88  return TM_ECODE_OK;
89 
90  JsonAddCommonOptions(&aft->json_output_ctx->cfg, p, p->flow, js);
91  OutputJSONBuffer(js, aft->file_ctx, &aft->json_buffer);
92  json_object_del(js, "metadata");
93  json_object_clear(js);
94  json_decref(js);
95 
96  return TM_ECODE_OK;
97 }
98 
99 static int JsonMetadataLogger(ThreadVars *tv, void *thread_data, const Packet *p)
100 {
101  JsonMetadataLogThread *aft = thread_data;
102 
103  return MetadataJson(tv, aft, p);
104 }
105 
106 static int JsonMetadataLogCondition(ThreadVars *tv, const Packet *p)
107 {
108  if (p->pktvar) {
109  return TRUE;
110  }
111  return FALSE;
112 }
113 
114 static TmEcode JsonMetadataLogThreadInit(ThreadVars *t, const void *initdata, void **data)
115 {
116  JsonMetadataLogThread *aft = SCMalloc(sizeof(JsonMetadataLogThread));
117  if (unlikely(aft == NULL))
118  return TM_ECODE_FAILED;
119  memset(aft, 0, sizeof(JsonMetadataLogThread));
120  if(initdata == NULL)
121  {
122  SCLogDebug("Error getting context for EveLogMetadata. \"initdata\" argument NULL");
123  SCFree(aft);
124  return TM_ECODE_FAILED;
125  }
126 
127  aft->json_buffer = MemBufferCreateNew(JSON_OUTPUT_BUFFER_SIZE);
128  if (aft->json_buffer == NULL) {
129  SCFree(aft);
130  return TM_ECODE_FAILED;
131  }
132 
133  /** Use the Output Context (file pointer and mutex) */
134  MetadataJsonOutputCtx *json_output_ctx = ((OutputCtx *)initdata)->data;
135  aft->file_ctx = json_output_ctx->file_ctx;
136  aft->json_output_ctx = json_output_ctx;
137 
138  *data = (void *)aft;
139  return TM_ECODE_OK;
140 }
141 
142 static TmEcode JsonMetadataLogThreadDeinit(ThreadVars *t, void *data)
143 {
144  JsonMetadataLogThread *aft = (JsonMetadataLogThread *)data;
145  if (aft == NULL) {
146  return TM_ECODE_OK;
147  }
148 
149  MemBufferFree(aft->json_buffer);
150 
151  /* clear memory */
152  memset(aft, 0, sizeof(JsonMetadataLogThread));
153 
154  SCFree(aft);
155  return TM_ECODE_OK;
156 }
157 
158 static void JsonMetadataLogDeInitCtx(OutputCtx *output_ctx)
159 {
160  MetadataJsonOutputCtx *json_output_ctx = (MetadataJsonOutputCtx *) output_ctx->data;
161  if (json_output_ctx != NULL) {
162  LogFileFreeCtx(json_output_ctx->file_ctx);
163  SCFree(json_output_ctx);
164  }
165  SCFree(output_ctx);
166 }
167 
168 static void JsonMetadataLogDeInitCtxSub(OutputCtx *output_ctx)
169 {
170  SCLogDebug("cleaning up sub output_ctx %p", output_ctx);
171 
172  MetadataJsonOutputCtx *json_output_ctx = (MetadataJsonOutputCtx *) output_ctx->data;
173 
174  if (json_output_ctx != NULL) {
175  SCFree(json_output_ctx);
176  }
177  SCFree(output_ctx);
178 }
179 
180 #define DEFAULT_LOG_FILENAME "metadata.json"
181 
182 /**
183  * \brief Create a new LogFileCtx for "fast" output style.
184  * \param conf The configuration node for this output.
185  * \return A LogFileCtx pointer on success, NULL on failure.
186  */
187 static OutputInitResult JsonMetadataLogInitCtx(ConfNode *conf)
188 {
189  OutputInitResult result = { NULL, false };
190  MetadataJsonOutputCtx *json_output_ctx = NULL;
191  LogFileCtx *logfile_ctx = LogFileNewCtx();
192  if (logfile_ctx == NULL) {
193  SCLogDebug("MetadataFastLogInitCtx2: Could not create new LogFileCtx");
194  return result;
195  }
196 
197  if (SCConfLogOpenGeneric(conf, logfile_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
198  LogFileFreeCtx(logfile_ctx);
199  return result;
200  }
201 
202  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
203  if (unlikely(output_ctx == NULL)) {
204  LogFileFreeCtx(logfile_ctx);
205  return result;
206  }
207 
208  json_output_ctx = SCMalloc(sizeof(MetadataJsonOutputCtx));
209  if (unlikely(json_output_ctx == NULL)) {
210  LogFileFreeCtx(logfile_ctx);
211  SCFree(output_ctx);
212  return result;
213  }
214  memset(json_output_ctx, 0, sizeof(MetadataJsonOutputCtx));
215 
216  json_output_ctx->file_ctx = logfile_ctx;
217  json_output_ctx->cfg.include_metadata = true;
218 
219  output_ctx->data = json_output_ctx;
220  output_ctx->DeInit = JsonMetadataLogDeInitCtx;
221 
222  result.ctx = output_ctx;
223  result.ok = true;
224  return result;
225 }
226 
227 /**
228  * \brief Create a new LogFileCtx for "fast" output style.
229  * \param conf The configuration node for this output.
230  * \return A LogFileCtx pointer on success, NULL on failure.
231  */
232 static OutputInitResult JsonMetadataLogInitCtxSub(ConfNode *conf, OutputCtx *parent_ctx)
233 {
234  OutputInitResult result = { NULL, false };
235  OutputJsonCtx *ajt = parent_ctx->data;
236  MetadataJsonOutputCtx *json_output_ctx = NULL;
237 
238  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
239  if (unlikely(output_ctx == NULL))
240  return result;
241 
242  json_output_ctx = SCMalloc(sizeof(MetadataJsonOutputCtx));
243  if (unlikely(json_output_ctx == NULL)) {
244  goto error;
245  }
246  memset(json_output_ctx, 0, sizeof(MetadataJsonOutputCtx));
247 
248  json_output_ctx->file_ctx = ajt->file_ctx;
249  json_output_ctx->cfg = ajt->cfg;
250  /* override config setting as this logger is about metadata */
251  json_output_ctx->cfg.include_metadata = true;
252 
253  output_ctx->data = json_output_ctx;
254  output_ctx->DeInit = JsonMetadataLogDeInitCtxSub;
255 
256  result.ctx = output_ctx;
257  result.ok = true;
258  return result;
259 
260 error:
261  if (json_output_ctx != NULL) {
262  SCFree(json_output_ctx);
263  }
264  if (output_ctx != NULL) {
265  SCFree(output_ctx);
266  }
267 
268  return result;
269 }
270 
271 void JsonMetadataLogRegister (void)
272 {
274  "metadata-json-log", JsonMetadataLogInitCtx, JsonMetadataLogger,
275  JsonMetadataLogCondition, JsonMetadataLogThreadInit,
276  JsonMetadataLogThreadDeinit, NULL);
278  "eve-log.metadata", JsonMetadataLogInitCtxSub, JsonMetadataLogger,
279  JsonMetadataLogCondition, JsonMetadataLogThreadInit,
280  JsonMetadataLogThreadDeinit, NULL);
281 
282  /* Kept for compatibility. */
284  "vars-json-log", JsonMetadataLogInitCtx, JsonMetadataLogger,
285  JsonMetadataLogCondition, JsonMetadataLogThreadInit,
286  JsonMetadataLogThreadDeinit, NULL);
288  "eve-log.vars", JsonMetadataLogInitCtxSub, JsonMetadataLogger,
289  JsonMetadataLogCondition, JsonMetadataLogThreadInit,
290  JsonMetadataLogThreadDeinit, NULL);
291 }
292 
293 #else
294 
296 {
297 }
298 
299 #endif
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32
#define SCLogDebug(...)
Definition: util-debug.h:335
struct Flow_ * flow
Definition: decode.h:445
#define FALSE
#define unlikely(expr)
Definition: util-optimize.h:35
#define MODULE_NAME
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:84
#define TRUE
PktVar * pktvar
Definition: decode.h:490
#define SCCalloc(nm, a)
Definition: util-mem.h:253
void OutputRegisterPacketModule(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a packet output module.
Definition: output.c:161
void OutputRegisterPacketSubModule(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, PacketLogger PacketLogFunc, PacketLogCondition PacketConditionFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a packet output sub-module.
Definition: output.c:202
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
int SCConfLogOpenGeneric(ConfNode *conf, LogFileCtx *log_ctx, const char *default_filename, int rotate)
open a generic output "log file", which may be a regular file or a socket
Definition: conf.h:32
OutputCtx * ctx
Definition: output.h:42
#define DEFAULT_LOG_FILENAME
#define SCMalloc(a)
Definition: util-mem.h:222
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
#define SCFree(a)
Definition: util-mem.h:322
void * data
Definition: tm-modules.h:81
void JsonMetadataLogRegister(void)
Per thread variable structure.
Definition: threadvars.h:57
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:82