suricata
output-json-http.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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 Tom DeCanio <td@npulsetech.com>
22  *
23  * Implements HTTP JSON logging portion of the engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "pkt-var.h"
29 #include "conf.h"
30 
31 #include "threads.h"
32 #include "threadvars.h"
33 #include "tm-threads.h"
34 
35 #include "util-print.h"
36 
37 #include "util-debug.h"
38 
39 #include "output.h"
40 #include "app-layer-htp.h"
41 #include "app-layer-htp-file.h"
42 #include "app-layer-htp-xff.h"
43 #include "app-layer.h"
44 #include "app-layer-parser.h"
45 #include "util-privs.h"
46 #include "util-buffer.h"
47 #include "util-proto-name.h"
48 #include "util-logopenfile.h"
49 #include "output-json.h"
50 #include "output-json-alert.h"
51 #include "output-json-http.h"
52 #include "util-byte.h"
53 
54 typedef struct LogHttpFileCtx_ {
55  uint32_t flags; /** Store mode */
56  uint64_t fields;/** Store fields */
61 
62 typedef struct JsonHttpLogThread_ {
64  uint32_t uri_cnt;
67 
68 #define MAX_SIZE_HEADER_NAME 256
69 #define MAX_SIZE_HEADER_VALUE 2048
70 
71 #define LOG_HTTP_DEFAULT 0
72 #define LOG_HTTP_EXTENDED 1
73 #define LOG_HTTP_REQUEST 2 /* request field */
74 #define LOG_HTTP_ARRAY 4 /* require array handling */
75 #define LOG_HTTP_REQ_HEADERS 8
76 #define LOG_HTTP_RES_HEADERS 16
77 
78 typedef enum {
134 
135 struct {
136  const char *config_field;
137  const char *htp_field;
138  uint32_t flags;
139 } http_fields[] = {
140  { "accept", "accept", LOG_HTTP_REQUEST },
141  { "accept_charset", "accept-charset", LOG_HTTP_REQUEST },
142  { "accept_encoding", "accept-encoding", LOG_HTTP_REQUEST },
143  { "accept_language", "accept-language", LOG_HTTP_REQUEST },
144  { "accept_datetime", "accept-datetime", LOG_HTTP_REQUEST },
145  { "authorization", "authorization", LOG_HTTP_REQUEST },
146  { "cache_control", "cache-control", LOG_HTTP_REQUEST },
147  { "cookie", "cookie", LOG_HTTP_REQUEST | LOG_HTTP_ARRAY },
148  { "from", "from", LOG_HTTP_REQUEST },
149  { "max_forwards", "max-forwards", LOG_HTTP_REQUEST },
150  { "origin", "origin", LOG_HTTP_REQUEST },
151  { "pragma", "pragma", LOG_HTTP_REQUEST },
152  { "proxy_authorization", "proxy-authorization", LOG_HTTP_REQUEST },
153  { "range", "range", LOG_HTTP_REQUEST },
154  { "te", "te", LOG_HTTP_REQUEST },
155  { "via", "via", LOG_HTTP_REQUEST },
156  { "x_requested_with", "x-requested-with", LOG_HTTP_REQUEST },
157  { "dnt", "dnt", LOG_HTTP_REQUEST },
158  { "x_forwarded_proto", "x-forwarded-proto", LOG_HTTP_REQUEST },
159  { "x_authenticated_user", "x-authenticated-user", LOG_HTTP_REQUEST },
160  { "x_flash_version", "x-flash-version", LOG_HTTP_REQUEST },
161  { "accept_range", "accept-range", 0 },
162  { "age", "age", 0 },
163  { "allow", "allow", 0 },
164  { "connection", "connection", 0 },
165  { "content_encoding", "content-encoding", 0 },
166  { "content_language", "content-language", 0 },
167  { "content_length", "content-length", 0 },
168  { "content_location", "content-location", 0 },
169  { "content_md5", "content-md5", 0 },
170  { "content_range", "content-range", 0 },
171  { "content_type", "content-type", 0 },
172  { "date", "date", 0 },
173  { "etag", "etags", 0 },
174  { "expires", "expires", 0 },
175  { "last_modified", "last-modified", 0 },
176  { "link", "link", 0 },
177  { "location", "location", 0 },
178  { "proxy_authenticate", "proxy-authenticate", 0 },
179  { "referer", "referer", LOG_HTTP_EXTENDED },
180  { "refresh", "refresh", 0 },
181  { "retry_after", "retry-after", 0 },
182  { "server", "server", 0 },
183  { "set_cookie", "set-cookie", 0 },
184  { "trailer", "trailer", 0 },
185  { "transfer_encoding", "transfer-encoding", 0 },
186  { "upgrade", "upgrade", 0 },
187  { "vary", "vary", 0 },
188  { "warning", "warning", 0 },
189  { "www_authenticate", "www-authenticate", 0 },
190  { "true_client_ip", "true-client-ip", LOG_HTTP_REQUEST },
191  { "org_src_ip", "org-src-ip", LOG_HTTP_REQUEST },
192  { "x_bluecoat_via", "x-bluecoat-via", LOG_HTTP_REQUEST },
193 };
194 
195 static void EveHttpLogJSONBasic(SCJsonBuilder *js, htp_tx_t *tx)
196 {
197  /* hostname */
198  if (htp_tx_request_hostname(tx) != NULL) {
199  SCJbSetStringFromBytes(js, "hostname", bstr_ptr(htp_tx_request_hostname(tx)),
200  (uint32_t)bstr_len(htp_tx_request_hostname(tx)));
201  }
202 
203  /* port */
204  /* NOTE: this field will be set ONLY if the port is present in the
205  * hostname. It may be present in the header "Host" or in the URL.
206  * There is no connection (from the suricata point of view) between this
207  * port and the TCP destination port of the flow.
208  */
209  if (htp_tx_request_port_number(tx) >= 0) {
210  SCJbSetUint(js, "http_port", htp_tx_request_port_number(tx));
211  }
212 
213  /* uri */
214  if (htp_tx_request_uri(tx) != NULL) {
215  SCJbSetStringFromBytes(js, "url", bstr_ptr(htp_tx_request_uri(tx)),
216  (uint32_t)bstr_len(htp_tx_request_uri(tx)));
217  }
218 
219  if (htp_tx_request_headers(tx) != NULL) {
220  /* user agent */
221  const htp_header_t *h_user_agent = htp_tx_request_header(tx, "user-agent");
222  if (h_user_agent != NULL) {
223  SCJbSetStringFromBytes(js, "http_user_agent", htp_header_value_ptr(h_user_agent),
224  (uint32_t)htp_header_value_len(h_user_agent));
225  }
226 
227  /* x-forwarded-for */
228  const htp_header_t *h_x_forwarded_for = htp_tx_request_header(tx, "x-forwarded-for");
229  if (h_x_forwarded_for != NULL) {
230  SCJbSetStringFromBytes(js, "xff", htp_header_value_ptr(h_x_forwarded_for),
231  (uint32_t)htp_header_value_len(h_x_forwarded_for));
232  }
233  }
234 
235  /* content-type */
236  if (htp_tx_response_headers(tx) != NULL) {
237  const htp_header_t *h_content_type = htp_tx_response_header(tx, "content-type");
238  if (h_content_type != NULL) {
239  uint32_t len = (uint32_t)htp_header_value_len(h_content_type);
240  const uint8_t *p = memchr(htp_header_value_ptr(h_content_type), ';', len);
241  if (p != NULL)
242  len = (uint32_t)(p - htp_header_value_ptr(h_content_type));
243  SCJbSetStringFromBytes(
244  js, "http_content_type", htp_header_value_ptr(h_content_type), len);
245  }
246  const htp_header_t *h_content_range = htp_tx_response_header(tx, "content-range");
247  if (h_content_range != NULL) {
248  SCJbOpenObject(js, "content_range");
249  SCJbSetStringFromBytes(js, "raw", htp_header_value_ptr(h_content_range),
250  (uint32_t)htp_header_value_len(h_content_range));
251  HTTPContentRange crparsed;
252  if (HTPParseContentRange(htp_header_value(h_content_range), &crparsed) == 0) {
253  if (crparsed.start >= 0)
254  SCJbSetUint(js, "start", crparsed.start);
255  if (crparsed.end >= 0)
256  SCJbSetUint(js, "end", crparsed.end);
257  if (crparsed.size >= 0)
258  SCJbSetUint(js, "size", crparsed.size);
259  }
260  SCJbClose(js);
261  }
262  }
263 }
264 
265 static void EveHttpLogJSONExtended(SCJsonBuilder *js, htp_tx_t *tx)
266 {
267  /* referer */
268  const htp_header_t *h_referer = NULL;
269  if (htp_tx_request_headers(tx) != NULL) {
270  h_referer = htp_tx_request_header(tx, "referer");
271  }
272  if (h_referer != NULL) {
273  SCJbSetStringFromBytes(js, "http_refer", htp_header_value_ptr(h_referer),
274  (uint32_t)htp_header_value_len(h_referer));
275  }
276 
277  /* method */
278  if (htp_tx_request_method(tx) != NULL) {
279  SCJbSetStringFromBytes(js, "http_method", bstr_ptr(htp_tx_request_method(tx)),
280  (uint32_t)bstr_len(htp_tx_request_method(tx)));
281  }
282 
283  /* protocol */
284  if (htp_tx_request_protocol(tx) != NULL) {
285  SCJbSetStringFromBytes(js, "protocol", bstr_ptr(htp_tx_request_protocol(tx)),
286  (uint32_t)bstr_len(htp_tx_request_protocol(tx)));
287  }
288 
289  /* response status */
290  const int resp = htp_tx_response_status_number(tx);
291  if (resp > 0) {
292  SCJbSetUint(js, "status", (uint32_t)resp);
293  } else if (htp_tx_response_status(tx) != NULL) {
294  SCJbSetStringFromBytes(js, "status_string", bstr_ptr(htp_tx_response_status(tx)),
295  (uint32_t)bstr_len(htp_tx_response_status(tx)));
296  }
297 
298  const htp_header_t *h_location = htp_tx_response_header(tx, "location");
299  if (h_location != NULL) {
300  SCJbSetStringFromBytes(js, "redirect", htp_header_value_ptr(h_location),
301  (uint32_t)htp_header_value_len(h_location));
302  }
303 
304  /* length */
305  SCJbSetUint(js, "length", htp_tx_response_message_len(tx));
306 }
307 
308 static void EveHttpLogJSONHeaders(
309  SCJsonBuilder *js, uint32_t direction, htp_tx_t *tx, LogHttpFileCtx *http_ctx)
310 {
311  const htp_headers_t *headers = direction & LOG_HTTP_REQ_HEADERS ? htp_tx_request_headers(tx)
312  : htp_tx_response_headers(tx);
313  char name[MAX_SIZE_HEADER_NAME] = {0};
314  char value[MAX_SIZE_HEADER_VALUE] = {0};
315  size_t n = htp_headers_size(headers);
316  SCJsonBuilderMark mark = { 0, 0, 0 };
317  SCJbGetMark(js, &mark);
318  bool array_empty = true;
319  SCJbOpenArray(js, direction & LOG_HTTP_REQ_HEADERS ? "request_headers" : "response_headers");
320  for (size_t i = 0; i < n; i++) {
321  const htp_header_t *h = htp_headers_get_index(headers, i);
322  if ((http_ctx->flags & direction) == 0 && http_ctx->fields != 0) {
323  bool tolog = false;
325  if ((http_ctx->fields & (1ULL << f)) != 0) {
326  /* prevent logging a field twice if extended logging is
327  enabled */
328  if (((http_ctx->flags & LOG_HTTP_EXTENDED) == 0) ||
329  ((http_ctx->flags & LOG_HTTP_EXTENDED) !=
330  (http_fields[f].flags & LOG_HTTP_EXTENDED))) {
331  if (bstr_cmp_c_nocase(htp_header_name(h), http_fields[f].htp_field)) {
332  tolog = true;
333  break;
334  }
335  }
336  }
337  }
338  if (!tolog) {
339  continue;
340  }
341  }
342  array_empty = false;
343  SCJbStartObject(js);
344  size_t size_name = htp_header_name_len(h) < MAX_SIZE_HEADER_NAME - 1
345  ? htp_header_name_len(h)
346  : MAX_SIZE_HEADER_NAME - 1;
347  memcpy(name, htp_header_name_ptr(h), size_name);
348  name[size_name] = '\0';
349  SCJbSetString(js, "name", name);
350  size_t size_value = htp_header_value_len(h) < MAX_SIZE_HEADER_VALUE - 1
351  ? htp_header_value_len(h)
352  : MAX_SIZE_HEADER_VALUE - 1;
353  memcpy(value, htp_header_value_ptr(h), size_value);
354  value[size_value] = '\0';
355  SCJbSetString(js, "value", value);
356  SCJbClose(js);
357  }
358  if (array_empty) {
359  SCJbRestoreMark(js, &mark);
360  } else {
361  // Close array.
362  SCJbClose(js);
363  }
364 }
365 
366 static void BodyPrintableBuffer(SCJsonBuilder *js, HtpBody *body, const char *key)
367 {
368  if (body->sb != NULL && body->sb->region.buf != NULL) {
369  const uint8_t *body_data;
370  uint32_t body_data_len;
371  uint64_t body_offset;
372 
373  if (StreamingBufferGetData(body->sb, &body_data,
374  &body_data_len, &body_offset) == 0) {
375  return;
376  }
377 
378  SCJbSetPrintAsciiString(js, key, body_data, body_data_len);
379  }
380 }
381 
382 void EveHttpLogJSONBodyPrintable(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
383 {
384  HtpState *htp_state = (HtpState *)FlowGetAppState(f);
385  if (htp_state) {
386  htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id);
387  if (tx) {
388  HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
389  BodyPrintableBuffer(js, &htud->request_body, "http_request_body_printable");
390  BodyPrintableBuffer(js, &htud->response_body, "http_response_body_printable");
391  }
392  }
393 }
394 
395 static void BodyBase64Buffer(SCJsonBuilder *js, HtpBody *body, const char *key)
396 {
397  if (body->sb != NULL && body->sb->region.buf != NULL) {
398  const uint8_t *body_data;
399  uint32_t body_data_len;
400  uint64_t body_offset;
401 
402  if (StreamingBufferGetData(body->sb, &body_data,
403  &body_data_len, &body_offset) == 0) {
404  return;
405  }
406 
407  SCJbSetBase64(js, key, body_data, body_data_len);
408  }
409 }
410 
411 void EveHttpLogJSONBodyBase64(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
412 {
413  HtpState *htp_state = (HtpState *)FlowGetAppState(f);
414  if (htp_state) {
415  htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id);
416  if (tx) {
417  HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
418  BodyBase64Buffer(js, &htud->request_body, "http_request_body");
419  BodyBase64Buffer(js, &htud->response_body, "http_response_body");
420  }
421  }
422 }
423 
424 /* JSON format logging */
425 static void EveHttpLogJSON(JsonHttpLogThread *aft, SCJsonBuilder *js, htp_tx_t *tx, uint64_t tx_id)
426 {
427  LogHttpFileCtx *http_ctx = aft->httplog_ctx;
428  SCJbOpenObject(js, "http");
429 
430  EveHttpLogJSONBasic(js, tx);
431  if (http_ctx->flags & LOG_HTTP_EXTENDED)
432  EveHttpLogJSONExtended(js, tx);
433  if (http_ctx->flags & LOG_HTTP_REQ_HEADERS || http_ctx->fields != 0)
434  EveHttpLogJSONHeaders(js, LOG_HTTP_REQ_HEADERS, tx, http_ctx);
435  if (http_ctx->flags & LOG_HTTP_RES_HEADERS || http_ctx->fields != 0)
436  EveHttpLogJSONHeaders(js, LOG_HTTP_RES_HEADERS, tx, http_ctx);
437 
438  SCJbClose(js);
439 }
440 
441 static int JsonHttpLogger(ThreadVars *tv, void *thread_data, const Packet *p, Flow *f, void *alstate, void *txptr, uint64_t tx_id)
442 {
443  SCEnter();
444 
445  htp_tx_t *tx = txptr;
446  JsonHttpLogThread *jhl = (JsonHttpLogThread *)thread_data;
447 
449  p, LOG_DIR_FLOW, "http", NULL, tx_id, jhl->httplog_ctx->eve_ctx);
450  if (unlikely(js == NULL))
451  return TM_ECODE_OK;
452 
453  SCLogDebug("got a HTTP request and now logging !!");
454 
455  EveHttpLogJSON(jhl, js, tx, tx_id);
456  HttpXFFCfg *xff_cfg = jhl->httplog_ctx->xff_cfg != NULL ?
458 
459  /* xff header */
460  if ((xff_cfg != NULL) && !(xff_cfg->flags & XFF_DISABLED) && p->flow != NULL) {
461  int have_xff_ip = 0;
462  char buffer[XFF_MAXLEN];
463 
464  have_xff_ip = HttpXFFGetIPFromTx(p->flow, tx_id, xff_cfg, buffer, XFF_MAXLEN);
465 
466  if (have_xff_ip) {
467  if (xff_cfg->flags & XFF_EXTRADATA) {
468  SCJbSetString(js, "xff", buffer);
469  }
470  else if (xff_cfg->flags & XFF_OVERWRITE) {
471  if (p->flowflags & FLOW_PKT_TOCLIENT) {
472  SCJbSetString(js, "dest_ip", buffer);
473  } else {
474  SCJbSetString(js, "src_ip", buffer);
475  }
476  }
477  }
478  }
479 
480  OutputJsonBuilderBuffer(tv, p, p->flow, js, jhl->ctx);
481  SCJbFree(js);
482 
484 }
485 
486 bool EveHttpAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
487 {
488  HtpState *htp_state = (HtpState *)FlowGetAppState(f);
489  if (htp_state) {
490  htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id);
491 
492  if (tx) {
493  EveHttpLogJSONBasic(js, tx);
494  EveHttpLogJSONExtended(js, tx);
495  return true;
496  }
497  }
498 
499  return false;
500 }
501 
502 static void OutputHttpLogDeinitSub(OutputCtx *output_ctx)
503 {
504  LogHttpFileCtx *http_ctx = output_ctx->data;
505  if (http_ctx->xff_cfg) {
506  SCFree(http_ctx->xff_cfg);
507  }
508  SCFree(http_ctx);
509  SCFree(output_ctx);
510 }
511 
512 static OutputInitResult OutputHttpLogInitSub(SCConfNode *conf, OutputCtx *parent_ctx)
513 {
514  OutputInitResult result = { NULL, false };
515  OutputJsonCtx *ojc = parent_ctx->data;
516 
517  LogHttpFileCtx *http_ctx = SCCalloc(1, sizeof(LogHttpFileCtx));
518  if (unlikely(http_ctx == NULL))
519  return result;
520  memset(http_ctx, 0x00, sizeof(*http_ctx));
521 
522  OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx));
523  if (unlikely(output_ctx == NULL)) {
524  SCFree(http_ctx);
525  return result;
526  }
527 
528  http_ctx->flags = LOG_HTTP_DEFAULT;
529  http_ctx->eve_ctx = ojc;
530 
531  if (conf) {
532  const char *extended = SCConfNodeLookupChildValue(conf, "extended");
533 
534  if (extended != NULL) {
535  if (SCConfValIsTrue(extended)) {
536  http_ctx->flags = LOG_HTTP_EXTENDED;
537  }
538  }
539 
540  const char *all_headers = SCConfNodeLookupChildValue(conf, "dump-all-headers");
541  if (all_headers != NULL) {
542  if (strncmp(all_headers, "both", 4) == 0) {
543  http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
544  http_ctx->flags |= LOG_HTTP_RES_HEADERS;
545  } else if (strncmp(all_headers, "request", 7) == 0) {
546  http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
547  } else if (strncmp(all_headers, "response", 8) == 0) {
548  http_ctx->flags |= LOG_HTTP_RES_HEADERS;
549  }
550  }
551  SCConfNode *custom;
552  if ((custom = SCConfNodeLookupChild(conf, "custom")) != NULL) {
553  if ((http_ctx->flags & (LOG_HTTP_REQ_HEADERS | LOG_HTTP_RES_HEADERS)) ==
555  SCLogWarning("No need for custom as dump-all-headers is already present");
556  }
557  SCConfNode *field;
558  TAILQ_FOREACH (field, &custom->head, next) {
559  HttpField f;
560  for (f = HTTP_FIELD_ACCEPT; f < HTTP_FIELD_SIZE; f++) {
561  if ((strcmp(http_fields[f].config_field, field->val) == 0) ||
562  (strcasecmp(http_fields[f].htp_field, field->val) == 0)) {
563  http_ctx->fields |= (1ULL << f);
564  break;
565  }
566  }
567  }
568  }
569  }
570 
571  if (conf != NULL && SCConfNodeLookupChild(conf, "xff") != NULL) {
572  http_ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg));
573  if (http_ctx->xff_cfg != NULL) {
574  HttpXFFGetCfg(conf, http_ctx->xff_cfg);
575  }
576  } else if (ojc->xff_cfg) {
577  http_ctx->parent_xff_cfg = ojc->xff_cfg;
578  }
579 
580  output_ctx->data = http_ctx;
581  output_ctx->DeInit = OutputHttpLogDeinitSub;
582 
583  /* enable the logger for the app layer */
585 
586  result.ctx = output_ctx;
587  result.ok = true;
588  return result;
589 }
590 
591 static TmEcode JsonHttpLogThreadInit(ThreadVars *t, const void *initdata, void **data)
592 {
593  JsonHttpLogThread *aft = SCCalloc(1, sizeof(JsonHttpLogThread));
594  if (unlikely(aft == NULL))
595  return TM_ECODE_FAILED;
596 
597  if(initdata == NULL)
598  {
599  SCLogDebug("Error getting context for EveLogHTTP. \"initdata\" argument NULL");
600  goto error_exit;
601  }
602 
603  /* Use the Output Context (file pointer and mutex) */
604  aft->httplog_ctx = ((OutputCtx *)initdata)->data; //TODO
605 
606  aft->ctx = CreateEveThreadCtx(t, aft->httplog_ctx->eve_ctx);
607  if (!aft->ctx) {
608  goto error_exit;
609  }
610 
611  *data = (void *)aft;
612  return TM_ECODE_OK;
613 
614 error_exit:
615  SCFree(aft);
616  return TM_ECODE_FAILED;
617 }
618 
619 static TmEcode JsonHttpLogThreadDeinit(ThreadVars *t, void *data)
620 {
621  JsonHttpLogThread *aft = (JsonHttpLogThread *)data;
622  if (aft == NULL) {
623  return TM_ECODE_OK;
624  }
625 
626  FreeEveThreadCtx(aft->ctx);
627 
628  /* clear memory */
629  memset(aft, 0, sizeof(JsonHttpLogThread));
630 
631  SCFree(aft);
632  return TM_ECODE_OK;
633 }
634 
636 {
637  /* register as child of eve-log */
638  OutputRegisterTxSubModule(LOGGER_JSON_TX, "eve-log", "JsonHttpLog", "eve-log.http",
639  OutputHttpLogInitSub, ALPROTO_HTTP1, JsonHttpLogger, JsonHttpLogThreadInit,
640  JsonHttpLogThreadDeinit);
641 }
SCJsonBuilder
struct SCJsonBuilder SCJsonBuilder
Definition: detect-engine-helper.h:83
XFF_MAXLEN
#define XFF_MAXLEN
Definition: app-layer-htp-xff.h:39
util-byte.h
tm-threads.h
HTTP_FIELD_SIZE
@ HTTP_FIELD_SIZE
Definition: output-json-http.c:132
len
uint8_t len
Definition: app-layer-dnp3.h:2
SCConfValIsTrue
int SCConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:577
HTTP_FIELD_CONTENT_LOCATION
@ HTTP_FIELD_CONTENT_LOCATION
Definition: output-json-http.c:107
JsonHttpLogThread_
Definition: output-json-http.c:62
OutputJsonCtx_::xff_cfg
HttpXFFCfg * xff_cfg
Definition: output-json.h:81
XFF_EXTRADATA
#define XFF_EXTRADATA
Definition: app-layer-htp-xff.h:31
MAX_SIZE_HEADER_NAME
#define MAX_SIZE_HEADER_NAME
Definition: output-json-http.c:68
HtpBody_::sb
StreamingBuffer * sb
Definition: app-layer-htp.h:135
HttpXFFGetCfg
void HttpXFFGetCfg(SCConfNode *conf, HttpXFFCfg *result)
Function to return XFF configuration from a configuration node.
Definition: app-layer-htp-xff.c:116
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
EveHttpLogJSONBodyPrintable
void EveHttpLogJSONBodyPrintable(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
Definition: output-json-http.c:382
http_fields
struct @141 http_fields[]
HTTP_FIELD_ALLOW
@ HTTP_FIELD_ALLOW
Definition: output-json-http.c:102
HTTP_FIELD_ACCEPT_RANGES
@ HTTP_FIELD_ACCEPT_RANGES
Definition: output-json-http.c:100
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
HTTP_FIELD_X_FLASH_VERSION
@ HTTP_FIELD_X_FLASH_VERSION
Definition: output-json-http.c:99
name
const char * name
Definition: detect-engine-proto.c:47
FreeEveThreadCtx
void FreeEveThreadCtx(OutputJsonThreadCtx *ctx)
Definition: output-json-common.c:58
HTTP_FIELD_REFERRER
@ HTTP_FIELD_REFERRER
Definition: output-json-http.c:118
MAX_SIZE_HEADER_VALUE
#define MAX_SIZE_HEADER_VALUE
Definition: output-json-http.c:69
threads.h
OutputJsonCtx_
Definition: output-json.h:77
Flow_
Flow data structure.
Definition: flow.h:359
LogHttpFileCtx
struct LogHttpFileCtx_ LogHttpFileCtx
LOG_HTTP_ARRAY
#define LOG_HTTP_ARRAY
Definition: output-json-http.c:74
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
HTTP_FIELD_EXPIRES
@ HTTP_FIELD_EXPIRES
Definition: output-json-http.c:113
CreateEveThreadCtx
OutputJsonThreadCtx * CreateEveThreadCtx(ThreadVars *t, OutputJsonCtx *ctx)
Definition: output-json-common.c:29
HtpTxUserData_::request_body
HtpBody request_body
Definition: app-layer-htp.h:166
OutputRegisterTxSubModule
void OutputRegisterTxSubModule(LoggerId id, const char *parent_name, const char *name, const char *conf_name, OutputInitSubFunc InitFunc, AppProto alproto, TxLogger TxLogFunc, ThreadInitFunc ThreadInit, ThreadDeinitFunc ThreadDeinit)
Definition: output.c:411
HTTP_FIELD_FROM
@ HTTP_FIELD_FROM
Definition: output-json-http.c:87
HTTP_FIELD_CONTENT_ENCODING
@ HTTP_FIELD_CONTENT_ENCODING
Definition: output-json-http.c:104
HTTP_FIELD_WWW_AUTHENTICATE
@ HTTP_FIELD_WWW_AUTHENTICATE
Definition: output-json-http.c:128
StreamingBufferGetData
int StreamingBufferGetData(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t *stream_offset)
Definition: util-streaming-buffer.c:1810
HTTP_FIELD_WARNING
@ HTTP_FIELD_WARNING
Definition: output-json-http.c:127
HTTP_FIELD_COOKIE
@ HTTP_FIELD_COOKIE
Definition: output-json-http.c:86
HTTP_FIELD_CONTENT_LENGTH
@ HTTP_FIELD_CONTENT_LENGTH
Definition: output-json-http.c:106
util-privs.h
LogHttpFileCtx_::xff_cfg
HttpXFFCfg * xff_cfg
Definition: output-json-http.c:57
p
Packet * p
Definition: fuzz_dataset.c:30
OutputJsonBuilderBuffer
void OutputJsonBuilderBuffer(ThreadVars *tv, const Packet *p, Flow *f, SCJsonBuilder *js, OutputJsonThreadCtx *ctx)
Definition: output-json.c:1018
SCConfNodeLookupChildValue
const char * SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:877
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:547
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
HTTP_FIELD_ETAG
@ HTTP_FIELD_ETAG
Definition: output-json-http.c:112
HTTP_FIELD_X_BLUECOAT_VIA
@ HTTP_FIELD_X_BLUECOAT_VIA
Definition: output-json-http.c:131
HTTP_FIELD_AGE
@ HTTP_FIELD_AGE
Definition: output-json-http.c:101
EveHttpAddMetadata
bool EveHttpAddMetadata(const Flow *f, uint64_t tx_id, SCJsonBuilder *js)
Definition: output-json-http.c:486
HtpState_
Definition: app-layer-htp.h:183
JsonHttpLogThread_::httplog_ctx
LogHttpFileCtx * httplog_ctx
Definition: output-json-http.c:63
HTTP_FIELD_CACHE_CONTROL
@ HTTP_FIELD_CACHE_CONTROL
Definition: output-json-http.c:85
OutputCtx_::data
void * data
Definition: tm-modules.h:91
config_field
const char * config_field
Definition: output-json-http.c:136
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
JsonHttpLogThread_::ctx
OutputJsonThreadCtx * ctx
Definition: output-json-http.c:65
OutputCtx_
Definition: tm-modules.h:88
app-layer-htp-xff.h
JsonHttpLogThread_::uri_cnt
uint32_t uri_cnt
Definition: output-json-http.c:64
app-layer-htp-file.h
OutputJsonThreadCtx_
Definition: output-json.h:85
HTTP_FIELD_RETRY_AFTER
@ HTTP_FIELD_RETRY_AFTER
Definition: output-json-http.c:120
HTTP_FIELD_UPGRADE
@ HTTP_FIELD_UPGRADE
Definition: output-json-http.c:125
HTTP_FIELD_CONTENT_RANGE
@ HTTP_FIELD_CONTENT_RANGE
Definition: output-json-http.c:109
HTTP_FIELD_ACCEPT
@ HTTP_FIELD_ACCEPT
Definition: output-json-http.c:79
HTTP_FIELD_PRAGMA
@ HTTP_FIELD_PRAGMA
Definition: output-json-http.c:90
HTTP_FIELD_ACCEPT_LANGUAGE
@ HTTP_FIELD_ACCEPT_LANGUAGE
Definition: output-json-http.c:82
HTTP_FIELD_LOCATION
@ HTTP_FIELD_LOCATION
Definition: output-json-http.c:116
HTTP_FIELD_DATE
@ HTTP_FIELD_DATE
Definition: output-json-http.c:111
app-layer-htp.h
LOG_HTTP_DEFAULT
#define LOG_HTTP_DEFAULT
Definition: output-json-http.c:71
HTTP_FIELD_ORIGIN
@ HTTP_FIELD_ORIGIN
Definition: output-json-http.c:89
HTTPContentRange
struct HTTPContentRange HTTPContentRange
Definition: app-layer-htp-range.h:26
util-debug.h
htp_field
const char * htp_field
Definition: output-json-http.c:137
HTTP_FIELD_ORG_SRC_IP
@ HTTP_FIELD_ORG_SRC_IP
Definition: output-json-http.c:130
OutputInitResult_::ctx
OutputCtx * ctx
Definition: output.h:47
SCAppLayerParserRegisterLogger
void SCAppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:535
HTTP_FIELD_LAST_MODIFIED
@ HTTP_FIELD_LAST_MODIFIED
Definition: output-json-http.c:114
HTTP_FIELD_AUTHORIZATION
@ HTTP_FIELD_AUTHORIZATION
Definition: output-json-http.c:84
output-json.h
LOG_HTTP_REQUEST
#define LOG_HTTP_REQUEST
Definition: output-json-http.c:73
util-print.h
HTTP_FIELD_RANGE
@ HTTP_FIELD_RANGE
Definition: output-json-http.c:92
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
HttpField
HttpField
Definition: output-json-http.c:78
HTTP_FIELD_LINK
@ HTTP_FIELD_LINK
Definition: output-json-http.c:115
OutputInitResult_::ok
bool ok
Definition: output.h:48
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
HTTP_FIELD_ACCEPT_ENCODING
@ HTTP_FIELD_ACCEPT_ENCODING
Definition: output-json-http.c:81
LOG_DIR_FLOW
@ LOG_DIR_FLOW
Definition: output-eve-bindgen.h:35
app-layer-parser.h
HTTP_FIELD_SERVER
@ HTTP_FIELD_SERVER
Definition: output-json-http.c:121
HTTP_FIELD_CONNECTION
@ HTTP_FIELD_CONNECTION
Definition: output-json-http.c:103
HTTP_FIELD_TE
@ HTTP_FIELD_TE
Definition: output-json-http.c:93
HTTP_FIELD_SET_COOKIE
@ HTTP_FIELD_SET_COOKIE
Definition: output-json-http.c:122
Packet_
Definition: decode.h:516
StreamingBufferRegion_::buf
uint8_t * buf
Definition: util-streaming-buffer.h:85
conf.h
HTTP_FIELD_TRAILER
@ HTTP_FIELD_TRAILER
Definition: output-json-http.c:123
XFF_OVERWRITE
#define XFF_OVERWRITE
Definition: app-layer-htp-xff.h:33
TmEcode
TmEcode
Definition: tm-threads-common.h:80
HttpXFFCfg_
Definition: app-layer-htp-xff.h:41
util-proto-name.h
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:237
HtpTxUserData_::response_body
HtpBody response_body
Definition: app-layer-htp.h:167
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1219
HTTP_FIELD_CONTENT_MD5
@ HTTP_FIELD_CONTENT_MD5
Definition: output-json-http.c:108
SCConfNodeLookupChild
SCConfNode * SCConfNodeLookupChild(const SCConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:849
HTTP_FIELD_DNT
@ HTTP_FIELD_DNT
Definition: output-json-http.c:96
OutputInitResult_
Definition: output.h:46
Packet_::flow
struct Flow_ * flow
Definition: decode.h:564
HtpBody_
Definition: app-layer-htp.h:131
suricata-common.h
OutputCtx_::DeInit
void(* DeInit)(struct OutputCtx_ *)
Definition: tm-modules.h:94
LOG_HTTP_REQ_HEADERS
#define LOG_HTTP_REQ_HEADERS
Definition: output-json-http.c:75
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
HTTP_FIELD_PROXY_AUTHORIZATION
@ HTTP_FIELD_PROXY_AUTHORIZATION
Definition: output-json-http.c:91
JsonHttpLogThread
struct JsonHttpLogThread_ JsonHttpLogThread
CreateEveHeaderWithTxId
SCJsonBuilder * CreateEveHeaderWithTxId(const Packet *p, enum SCOutputJsonLogDirection dir, const char *event_type, JsonAddrInfo *addr, uint64_t tx_id, OutputJsonCtx *eve_ctx)
Definition: output-json.c:962
HTTP_FIELD_VARY
@ HTTP_FIELD_VARY
Definition: output-json-http.c:126
HtpTxUserData_
Definition: app-layer-htp.h:153
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
HTTP_FIELD_TRUE_CLIENT_IP
@ HTTP_FIELD_TRUE_CLIENT_IP
Definition: output-json-http.c:129
output-json-alert.h
threadvars.h
HTPParseContentRange
int HTPParseContentRange(const bstr *rawvalue, HTTPContentRange *range)
Definition: app-layer-htp-file.c:100
HTTP_FIELD_CONTENT_LANGUAGE
@ HTTP_FIELD_CONTENT_LANGUAGE
Definition: output-json-http.c:105
LOGGER_JSON_TX
@ LOGGER_JSON_TX
Definition: suricata-common.h:489
HttpXFFCfg_::flags
uint8_t flags
Definition: app-layer-htp-xff.h:42
EveHttpLogJSONBodyBase64
void EveHttpLogJSONBodyBase64(SCJsonBuilder *js, Flow *f, uint64_t tx_id)
Definition: output-json-http.c:411
SCFree
#define SCFree(p)
Definition: util-mem.h:61
util-logopenfile.h
LogHttpFileCtx_::fields
uint64_t fields
Definition: output-json-http.c:56
HTTP_FIELD_X_FORWARDED_PROTO
@ HTTP_FIELD_X_FORWARDED_PROTO
Definition: output-json-http.c:97
util-buffer.h
HTTP_FIELD_MAX_FORWARDS
@ HTTP_FIELD_MAX_FORWARDS
Definition: output-json-http.c:88
LOG_HTTP_EXTENDED
#define LOG_HTTP_EXTENDED
Definition: output-json-http.c:72
HTTP_FIELD_TRANSFER_ENCODING
@ HTTP_FIELD_TRANSFER_ENCODING
Definition: output-json-http.c:124
JsonHttpLogRegister
void JsonHttpLogRegister(void)
Definition: output-json-http.c:635
HTTP_FIELD_ACCEPT_DATETIME
@ HTTP_FIELD_ACCEPT_DATETIME
Definition: output-json-http.c:83
HTTP_FIELD_VIA
@ HTTP_FIELD_VIA
Definition: output-json-http.c:94
LogHttpFileCtx_::eve_ctx
OutputJsonCtx * eve_ctx
Definition: output-json-http.c:59
HTTP_FIELD_ACCEPT_CHARSET
@ HTTP_FIELD_ACCEPT_CHARSET
Definition: output-json-http.c:80
HttpXFFGetIPFromTx
int HttpXFFGetIPFromTx(const Flow *f, uint64_t tx_id, HttpXFFCfg *xff_cfg, char *dstbuf, int dstbuflen)
Function to return XFF IP if any in the selected transaction. The caller needs to lock the flow.
Definition: app-layer-htp-xff.c:52
HTTP_FIELD_REFRESH
@ HTTP_FIELD_REFRESH
Definition: output-json-http.c:119
HTTP_FIELD_PROXY_AUTHENTICATE
@ HTTP_FIELD_PROXY_AUTHENTICATE
Definition: output-json-http.c:117
HTTP_FIELD_CONTENT_TYPE
@ HTTP_FIELD_CONTENT_TYPE
Definition: output-json-http.c:110
output-json-http.h
LogHttpFileCtx_::flags
uint32_t flags
Definition: output-json-http.c:55
HTTP_FIELD_X_AUTHENTICATED_USER
@ HTTP_FIELD_X_AUTHENTICATED_USER
Definition: output-json-http.c:98
flags
uint32_t flags
Definition: output-json-http.c:138
StreamingBuffer_::region
StreamingBufferRegion region
Definition: util-streaming-buffer.h:109
LogHttpFileCtx_
Definition: output-json-http.c:54
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
SCConfNode_
Definition: conf.h:37
SCConfNode_::val
char * val
Definition: conf.h:39
XFF_DISABLED
#define XFF_DISABLED
Definition: app-layer-htp-xff.h:29
HTTP_FIELD_X_REQUESTED_WITH
@ HTTP_FIELD_X_REQUESTED_WITH
Definition: output-json-http.c:95
LOG_HTTP_RES_HEADERS
#define LOG_HTTP_RES_HEADERS
Definition: output-json-http.c:76
output.h
app-layer.h
f
Flow f
Definition: fuzz_dataset.c:32
LogHttpFileCtx_::parent_xff_cfg
HttpXFFCfg * parent_xff_cfg
Definition: output-json-http.c:58