suricata
output-json-http2.c
Go to the documentation of this file.
1 /* Copyright (C) 2020 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 Philippe Antoine <p.antoine@catenacyber.fr>
22  *
23  * Implements HTTP2 JSON logging portion of the engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "detect.h"
29 #include "pkt-var.h"
30 #include "conf.h"
31 
32 #include "threads.h"
33 #include "threadvars.h"
34 #include "tm-threads.h"
35 
36 #include "util-print.h"
37 #include "util-unittest.h"
38 
39 #include "util-debug.h"
40 #include "app-layer-parser.h"
41 #include "output.h"
42 #include "app-layer-http2.h"
43 #include "app-layer.h"
44 #include "util-privs.h"
45 #include "util-buffer.h"
46 
47 #include "util-logopenfile.h"
48 #include "util-crypt.h"
49 
50 #include "output-json.h"
51 #include "output-json-http2.h"
52 #include "rust.h"
53 
54 #define MODULE_NAME "LogHttp2Log"
55 
56 typedef struct OutputHttp2Ctx_ {
60 
61 
62 typedef struct JsonHttp2LogThread_ {
66 
67 
68 bool EveHTTP2AddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *jb)
69 {
70  void *state = FlowGetAppState(f);
71  if (state) {
72  void *tx = AppLayerParserGetTx(f->proto, ALPROTO_HTTP2, state, tx_id);
73  if (tx) {
74  return rs_http2_log_json(tx, jb);
75  }
76  }
77  return false;
78 }
79 
80 static int JsonHttp2Logger(ThreadVars *tv, void *thread_data, const Packet *p,
81  Flow *f, void *state, void *txptr, uint64_t tx_id)
82 {
83  JsonHttp2LogThread *aft = (JsonHttp2LogThread *)thread_data;
84  OutputHttp2Ctx *http2_ctx = aft->http2log_ctx;
85 
86  if (unlikely(state == NULL)) {
87  return 0;
88  }
89 
90  JsonBuilder *js = CreateEveHeaderWithTxId(p, LOG_DIR_FLOW, "http", NULL, tx_id);
91  if (unlikely(js == NULL))
92  return 0;
93 
94  EveAddCommonOptions(&http2_ctx->cfg, p, f, js);
95 
96  /* reset */
97  MemBufferReset(aft->buffer);
98 
99  jb_open_object(js, "http");
100  if (!rs_http2_log_json(txptr, js)) {
101  goto end;
102  }
103  jb_close(js);
104  OutputJsonBuilderBuffer(js, http2_ctx->file_ctx, &aft->buffer);
105 end:
106  jb_free(js);
107  return 0;
108 }
109 
110 static TmEcode JsonHttp2LogThreadInit(ThreadVars *t, const void *initdata, void **data)
111 {
113  if (unlikely(aft == NULL))
114  return TM_ECODE_FAILED;
115  memset(aft, 0, sizeof(JsonHttp2LogThread));
116 
117  if(initdata == NULL)
118  {
119  SCLogDebug("Error getting context for EveLogHTTP2. \"initdata\" argument NULL");
120  SCFree(aft);
121  return TM_ECODE_FAILED;
122  }
123 
124  /* Use the Ouptut Context (file pointer and mutex) */
125  aft->http2log_ctx = ((OutputCtx *)initdata)->data;
126 
128  if (aft->buffer == NULL) {
129  SCFree(aft);
130  return TM_ECODE_FAILED;
131  }
132 
133  *data = (void *)aft;
134  return TM_ECODE_OK;
135 }
136 
137 static TmEcode JsonHttp2LogThreadDeinit(ThreadVars *t, void *data)
138 {
139  JsonHttp2LogThread *aft = (JsonHttp2LogThread *)data;
140  if (aft == NULL) {
141  return TM_ECODE_OK;
142  }
143 
144  MemBufferFree(aft->buffer);
145  /* clear memory */
146  memset(aft, 0, sizeof(JsonHttp2LogThread));
147 
148  SCFree(aft);
149  return TM_ECODE_OK;
150 }
151 
152 static void OutputHttp2LogDeinit(OutputCtx *output_ctx)
153 {
154  OutputHttp2Ctx *http2_ctx = output_ctx->data;
155  LogFileCtx *logfile_ctx = http2_ctx->file_ctx;
156  LogFileFreeCtx(logfile_ctx);
157  SCFree(http2_ctx);
158  SCFree(output_ctx);
159 }
160 
161 #define DEFAULT_LOG_FILENAME "http2.json"
162 static OutputInitResult OutputHttp2LogInit(ConfNode *conf)
163 {
164  OutputInitResult result = { NULL, false };
165  LogFileCtx *file_ctx = LogFileNewCtx();
166  if(file_ctx == NULL) {
167  SCLogError(SC_ERR_HTTP2_LOG_GENERIC, "couldn't create new file_ctx");
168  return result;
169  }
170 
171  if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) {
172  LogFileFreeCtx(file_ctx);
173  return result;
174  }
175 
176  OutputHttp2Ctx *http2_ctx = SCMalloc(sizeof(OutputHttp2Ctx));
177  if (unlikely(http2_ctx == NULL)) {
178  LogFileFreeCtx(file_ctx);
179  return result;
180  }
181 
182  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
183  if (unlikely(output_ctx == NULL)) {
184  LogFileFreeCtx(file_ctx);
185  SCFree(http2_ctx);
186  return result;
187  }
188 
189  http2_ctx->file_ctx = file_ctx;
190 
191  output_ctx->data = http2_ctx;
192  output_ctx->DeInit = OutputHttp2LogDeinit;
193 
195 
196  result.ctx = output_ctx;
197  result.ok = true;
198  return result;
199 }
200 
201 static void OutputHttp2LogDeinitSub(OutputCtx *output_ctx)
202 {
203  OutputHttp2Ctx *http2_ctx = output_ctx->data;
204  SCFree(http2_ctx);
205  SCFree(output_ctx);
206 }
207 
208 static OutputInitResult OutputHttp2LogInitSub(ConfNode *conf, OutputCtx *parent_ctx)
209 {
210  OutputInitResult result = { NULL, false };
211  OutputJsonCtx *ojc = parent_ctx->data;
212 
213  OutputHttp2Ctx *http2_ctx = SCMalloc(sizeof(OutputHttp2Ctx));
214  if (unlikely(http2_ctx == NULL))
215  return result;
216 
217  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
218  if (unlikely(output_ctx == NULL)) {
219  SCFree(http2_ctx);
220  return result;
221  }
222 
223  http2_ctx->file_ctx = ojc->file_ctx;
224  http2_ctx->cfg = ojc->cfg;
225 
226  output_ctx->data = http2_ctx;
227  output_ctx->DeInit = OutputHttp2LogDeinitSub;
228 
230 
231  result.ctx = output_ctx;
232  result.ok = true;
233  return result;
234 }
235 
237 {
238  /* register as separate module */
240  MODULE_NAME, "http2-json-log",
241  OutputHttp2LogInit, ALPROTO_HTTP2, JsonHttp2Logger,
242  HTTP2StateClosed, HTTP2StateClosed,
243  JsonHttp2LogThreadInit, JsonHttp2LogThreadDeinit, NULL);
244 
245  /* also register as child of eve-log */
247  "eve-log", MODULE_NAME, "eve-log.http2",
248  OutputHttp2LogInitSub, ALPROTO_HTTP2, JsonHttp2Logger,
249  HTTP2StateClosed, HTTP2StateClosed,
250  JsonHttp2LogThreadInit, JsonHttp2LogThreadDeinit, NULL);
251 }
tm-threads.h
LOGGER_JSON_HTTP2
@ LOGGER_JSON_HTTP2
Definition: suricata-common.h:471
OutputJsonCtx_::cfg
OutputJsonCommonSettings cfg
Definition: output-json.h:104
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
LogFileNewCtx
LogFileCtx * LogFileNewCtx(void)
LogFileNewCtx() Get a new LogFileCtx.
Definition: util-logopenfile.c:640
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Flow_::proto
uint8_t proto
Definition: flow.h:365
JSON_OUTPUT_BUFFER_SIZE
#define JSON_OUTPUT_BUFFER_SIZE
Definition: output-json.h:63
threads.h
OutputJsonCtx_
Definition: output-json.h:101
Flow_
Flow data structure.
Definition: flow.h:347
OutputJsonCommonSettings_
Definition: output-json.h:91
LogFileCtx_
Definition: util-logopenfile.h:60
OutputJsonBuilderBuffer
int OutputJsonBuilderBuffer(JsonBuilder *js, LogFileCtx *file_ctx, MemBuffer **buffer)
Definition: output-json.c:978
rust.h
util-privs.h
EveAddCommonOptions
void EveAddCommonOptions(const OutputJsonCommonSettings *cfg, const Packet *p, const Flow *f, JsonBuilder *js)
Definition: output-json.c:444
app-layer-http2.h
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
util-unittest.h
FlowGetAppState
void * FlowGetAppState(const Flow *f)
Definition: flow.c:1102
OutputCtx_::data
void * data
Definition: tm-modules.h:81
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
OutputCtx_
Definition: tm-modules.h:78
SCConfLogOpenGeneric
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: util-logopenfile.c:423
JsonHttp2LogThread
struct JsonHttp2LogThread_ JsonHttp2LogThread
util-debug.h
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:44
output-json.h
OutputRegisterTxSubModuleWithProgress
void OutputRegisterTxSubModuleWithProgress(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Definition: output.c:378
AppLayerParserRegisterLogger
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:456
util-print.h
util-crypt.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
SC_ERR_HTTP2_LOG_GENERIC
@ SC_ERR_HTTP2_LOG_GENERIC
Definition: util-error.h:366
OutputInitResult_::ok
bool ok
Definition: output.h:45
app-layer-parser.h
Packet_
Definition: decode.h:414
conf.h
EveHTTP2AddMetadata
bool EveHTTP2AddMetadata(const Flow *f, uint64_t tx_id, JsonBuilder *jb)
Definition: output-json-http2.c:68
TmEcode
TmEcode
Definition: tm-threads-common.h:79
MODULE_NAME
#define MODULE_NAME
Definition: output-json-http2.c:54
ALPROTO_HTTP2
@ ALPROTO_HTTP2
Definition: app-layer-protos.h:59
MemBuffer_
Definition: util-buffer.h:27
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1032
MemBufferReset
#define MemBufferReset(mem_buffer)
Reset the mem buffer.
Definition: util-buffer.h:42
OutputInitResult_
Definition: output.h:43
suricata-common.h
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:84
JsonHttp2LogThread_
Definition: output-json-http2.c:62
JsonHttp2LogThread_::http2log_ctx
OutputHttp2Ctx * http2log_ctx
Definition: output-json-http2.c:63
MemBufferFree
void MemBufferFree(MemBuffer *buffer)
Definition: util-buffer.c:82
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
LogFileFreeCtx
int LogFileFreeCtx(LogFileCtx *lf_ctx)
LogFileFreeCtx() Destroy a LogFileCtx (Close the file and free memory)
Definition: util-logopenfile.c:766
OutputHttp2Ctx_
Definition: output-json-http2.c:56
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
threadvars.h
LOG_DIR_FLOW
@ LOG_DIR_FLOW
Definition: output-json.h:40
output-json-http2.h
OutputHttp2Ctx_::cfg
OutputJsonCommonSettings cfg
Definition: output-json-http2.c:58
JsonHttp2LogRegister
void JsonHttp2LogRegister(void)
Definition: output-json-http2.c:236
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
DEFAULT_LOG_FILENAME
#define DEFAULT_LOG_FILENAME
Definition: output-json-http2.c:161
SCFree
#define SCFree(p)
Definition: util-mem.h:61
CreateEveHeaderWithTxId
JsonBuilder * CreateEveHeaderWithTxId(const Packet *p, enum OutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, uint64_t tx_id)
Definition: output-json.c:923
ConfNode_
Definition: conf.h:32
util-logopenfile.h
util-buffer.h
OutputRegisterTxModuleWithProgress
void OutputRegisterTxModuleWithProgress(LoggerId id, const char *name, const char *conf_name, OutputInitFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, int tc_log_progress, int ts_log_progress, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit, ThreadExitPrintStatsFunc ThreadExitPrintStats)
Register a tx output module with progress.
Definition: output.c:367
JsonHttp2LogThread_::buffer
MemBuffer * buffer
Definition: output-json-http2.c:64
OutputJsonCtx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json.h:102
OutputHttp2Ctx_::file_ctx
LogFileCtx * file_ctx
Definition: output-json-http2.c:57
OutputHttp2Ctx
struct OutputHttp2Ctx_ OutputHttp2Ctx
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
MemBufferCreateNew
MemBuffer * MemBufferCreateNew(uint32_t size)
Definition: util-buffer.c:32
debug.h
output.h
app-layer.h