suricata
detect-engine-state.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  * \defgroup sigstate State support
20  *
21  * State is stored in the ::DetectEngineState structure. This is
22  * basically a container for storage item of type ::DeStateStore.
23  * They contains an array of ::DeStateStoreItem which store the
24  * state of match for an individual signature identified by
25  * DeStateStoreItem::sid.
26  *
27  * @{
28  */
29 
30 /**
31  * \file
32  *
33  * \author Victor Julien <victor@inliniac.net>
34  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
35  *
36  * \brief State based signature handling.
37  */
38 
39 #include "suricata-common.h"
40 
41 #include "decode.h"
42 
43 #include "detect.h"
44 #include "detect-engine.h"
45 #include "detect-parse.h"
46 #include "detect-engine-state.h"
48 #include "detect-engine-build.h"
49 
50 #include "detect-flowvar.h"
51 
52 #include "stream-tcp.h"
53 #include "stream-tcp-private.h"
54 #include "stream-tcp-reassemble.h"
55 
56 #include "app-layer.h"
57 #include "app-layer-parser.h"
58 #include "app-layer-protos.h"
59 #include "app-layer-htp.h"
60 
61 #include "util-unittest.h"
62 #include "util-unittest-helper.h"
63 #include "util-profiling.h"
64 
65 #include "flow-util.h"
66 
67 static inline int StateIsValid(uint16_t alproto, void *alstate)
68 {
69  if (alstate != NULL) {
70  if (alproto == ALPROTO_HTTP1) {
71  HtpState *htp_state = (HtpState *)alstate;
72  if (htp_state->conn != NULL) {
73  return 1;
74  }
75  } else {
76  return 1;
77  }
78  }
79  return 0;
80 }
81 
82 static DeStateStore *DeStateStoreAlloc(void)
83 {
84  DeStateStore *d = SCCalloc(1, sizeof(DeStateStore));
85  if (unlikely(d == NULL))
86  return NULL;
87 
88  return d;
89 }
90 
91 #ifdef DEBUG_VALIDATION
92 static int DeStateSearchState(DetectEngineState *state, uint8_t direction, SigIntId num)
93 {
94  DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1];
95  DeStateStore *tx_store = dir_state->head;
96  SigIntId store_cnt;
97  SigIntId state_cnt = 0;
98 
99  for (; tx_store != NULL; tx_store = tx_store->next) {
100  SCLogDebug("tx_store %p", tx_store);
101  for (store_cnt = 0;
102  store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
103  store_cnt++, state_cnt++)
104  {
105  DeStateStoreItem *item = &tx_store->store[store_cnt];
106  if (item->sid == num) {
107  SCLogDebug("sid %u already in state: %p %p %p %u %u, direction %s",
108  num, state, dir_state, tx_store, state_cnt,
109  store_cnt, direction & STREAM_TOSERVER ? "toserver" : "toclient");
110  return 1;
111  }
112  }
113  }
114  return 0;
115 }
116 #endif
117 
118 static void DeStateSignatureAppend(DetectEngineState *state,
119  const Signature *s, uint32_t inspect_flags, uint8_t direction)
120 {
121  SCEnter();
122 
123  DetectEngineStateDirection *dir_state =
124  &state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1];
125 
126 #ifdef DEBUG_VALIDATION
127  BUG_ON(DeStateSearchState(state, direction, s->num));
128 #endif
129  DeStateStore *store = dir_state->tail;
130  if (store == NULL) {
131  store = DeStateStoreAlloc();
132  dir_state->head = store;
133  dir_state->cur = store;
134  dir_state->tail = store;
135  } else if (dir_state->cur) {
136  store = dir_state->cur;
137  } else {
138  store = DeStateStoreAlloc();
139  if (store != NULL) {
140  dir_state->tail->next = store;
141  dir_state->tail = store;
142  dir_state->cur = store;
143  }
144  }
145  if (store == NULL)
146  SCReturn;
147 
148  SigIntId idx = dir_state->cnt % DE_STATE_CHUNK_SIZE;
149  store->store[idx].sid = s->num;
150  store->store[idx].flags = inspect_flags;
151  dir_state->cnt++;
152  /* if current chunk is full, progress cur */
153  if (dir_state->cnt % DE_STATE_CHUNK_SIZE == 0) {
154  dir_state->cur = dir_state->cur->next;
155  }
156 
157  SCReturn;
158 }
159 
161 {
163  if (unlikely(d == NULL))
164  return NULL;
165 
166  return d;
167 }
168 
170 {
171  DeStateStore *store;
172  DeStateStore *store_next;
173  int i = 0;
174 
175  for (i = 0; i < 2; i++) {
176  store = state->dir_state[i].head;
177  while (store != NULL) {
178  store_next = store->next;
179  SCFree(store);
180  store = store_next;
181  }
182  }
183  SCFree(state);
184 }
185 
186 static void StoreFileNoMatchCnt(DetectEngineState *de_state, uint16_t file_no_match, uint8_t direction)
187 {
188  de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt += file_no_match;
189 }
190 
191 static bool StoreFilestoreSigsCantMatch(const SigGroupHead *sgh, const DetectEngineState *de_state, uint8_t direction)
192 {
193  if (de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt ==
194  sgh->filestore_cnt)
195  return true;
196  else
197  return false;
198 }
199 
200 static void StoreStateTxHandleFiles(const SigGroupHead *sgh, Flow *f, DetectEngineState *destate,
201  const uint8_t flow_flags, void *tx, const uint64_t tx_id, const uint16_t file_no_match)
202 {
203  SCLogDebug("tx %"PRIu64", file_no_match %u", tx_id, file_no_match);
204  StoreFileNoMatchCnt(destate, file_no_match, flow_flags);
205  if (StoreFilestoreSigsCantMatch(sgh, destate, flow_flags)) {
206  SCLogDebug("filestore sigs can't match");
208  f, flow_flags & (STREAM_TOCLIENT | STREAM_TOSERVER), tx, tx_id);
209  } else {
210  SCLogDebug("filestore sigs can still match");
211  }
212 }
213 
215  const SigGroupHead *sgh,
216  Flow *f, void *tx, uint64_t tx_id,
217  const Signature *s,
218  uint32_t inspect_flags, uint8_t flow_flags,
219  const uint16_t file_no_match)
220 {
221  AppLayerTxData *tx_data = AppLayerParserGetTxData(f->proto, f->alproto, tx);
222  BUG_ON(tx_data == NULL);
223  if (tx_data == NULL) {
224  SCLogDebug("No TX data for %" PRIu64, tx_id);
225  return;
226  }
227  if (tx_data->de_state == NULL) {
228  tx_data->de_state = DetectEngineStateAlloc();
229  if (tx_data->de_state == NULL)
230  return;
231  SCLogDebug("destate created for %"PRIu64, tx_id);
232  }
233  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags, flow_flags);
234  if (s->flags & SIG_FLAG_TXBOTHDIR) {
235  // add also in the other DetectEngineStateDirection
236  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags,
237  flow_flags ^ (STREAM_TOSERVER | STREAM_TOCLIENT));
238  }
239  StoreStateTxHandleFiles(sgh, f, tx_data->de_state, flow_flags, tx, tx_id, file_no_match);
240 
241  SCLogDebug("Stored for TX %"PRIu64, tx_id);
242 }
243 
244 static inline void ResetTxState(DetectEngineState *s)
245 {
246  if (s) {
247  s->dir_state[0].cnt = 0;
248  s->dir_state[0].filestore_cnt = 0;
249  s->dir_state[0].flags = 0;
250  /* reset 'cur' back to the list head */
251  s->dir_state[0].cur = s->dir_state[0].head;
252 
253  s->dir_state[1].cnt = 0;
254  s->dir_state[1].filestore_cnt = 0;
255  s->dir_state[1].flags = 0;
256  /* reset 'cur' back to the list head */
257  s->dir_state[1].cur = s->dir_state[1].head;
258  }
259 }
260 
261 /** \brief Reset de state for active tx'
262  * To be used on detect engine reload.
263  * \param f write LOCKED flow
264  */
266 {
267  void *alstate = FlowGetAppState(f);
268  if (!StateIsValid(f->alproto, alstate)) {
269  return;
270  }
271 
272  uint64_t inspect_ts = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOCLIENT);
273  uint64_t inspect_tc = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOSERVER);
274 
275  uint64_t inspect_tx_id = MIN(inspect_ts, inspect_tc);
276 
277  uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
278 
279  for ( ; inspect_tx_id < total_txs; inspect_tx_id++) {
280  void *inspect_tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, inspect_tx_id);
281  if (inspect_tx != NULL) {
282  AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, inspect_tx);
283  BUG_ON(txd == NULL);
284  if (txd) {
285  ResetTxState(txd->de_state);
286  }
287  }
288  }
289 }
290 
291 /*********Unittests*********/
292 
293 #ifdef UNITTESTS
294 #include "detect-engine-alert.h"
295 
296 static int DeStateTest01(void)
297 {
298  SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX,
299  (uintmax_t)sizeof(DetectEngineState));
300  SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX,
301  (uintmax_t)sizeof(DeStateStore));
302  SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"",
303  (uintmax_t)sizeof(DeStateStoreItem));
304 
305  return 1;
306 }
307 
308 static int DeStateTest02(void)
309 {
310  uint8_t direction = STREAM_TOSERVER;
312  FAIL_IF_NULL(state);
313  FAIL_IF_NOT_NULL(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head);
314 
315  Signature s;
316  memset(&s, 0x00, sizeof(s));
317 
318  s.num = 0;
319  DeStateSignatureAppend(state, &s, 0, direction);
320  s.num = 11;
321  DeStateSignatureAppend(state, &s, 0, direction);
322  s.num = 22;
323  DeStateSignatureAppend(state, &s, 0, direction);
324  s.num = 33;
325  DeStateSignatureAppend(state, &s, 0, direction);
326  s.num = 44;
327  DeStateSignatureAppend(state, &s, 0, direction);
328  s.num = 55;
329  DeStateSignatureAppend(state, &s, 0, direction);
330  s.num = 66;
331  DeStateSignatureAppend(state, &s, 0, direction);
332  s.num = 77;
333  DeStateSignatureAppend(state, &s, 0, direction);
334  s.num = 88;
335  DeStateSignatureAppend(state, &s, 0, direction);
336  s.num = 99;
337  DeStateSignatureAppend(state, &s, 0, direction);
338  s.num = 100;
339  DeStateSignatureAppend(state, &s, 0, direction);
340  s.num = 111;
341  DeStateSignatureAppend(state, &s, 0, direction);
342  s.num = 122;
343  DeStateSignatureAppend(state, &s, 0, direction);
344  s.num = 133;
345  DeStateSignatureAppend(state, &s, 0, direction);
346  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
347  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
348 
349  s.num = 144;
350  DeStateSignatureAppend(state, &s, 0, direction);
351 
352  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
353  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
354  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
355  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur == NULL);
356 
357  s.num = 155;
358  DeStateSignatureAppend(state, &s, 0, direction);
359 
360  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
361  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
362 
363  s.num = 166;
364  DeStateSignatureAppend(state, &s, 0, direction);
365 
366  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
367  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
368  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
369  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
370  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
371  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
372 
373  ResetTxState(state);
374 
375  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
376  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
377  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
378 
379  s.num = 0;
380  DeStateSignatureAppend(state, &s, 0, direction);
381  s.num = 11;
382  DeStateSignatureAppend(state, &s, 0, direction);
383  s.num = 22;
384  DeStateSignatureAppend(state, &s, 0, direction);
385  s.num = 33;
386  DeStateSignatureAppend(state, &s, 0, direction);
387  s.num = 44;
388  DeStateSignatureAppend(state, &s, 0, direction);
389  s.num = 55;
390  DeStateSignatureAppend(state, &s, 0, direction);
391  s.num = 66;
392  DeStateSignatureAppend(state, &s, 0, direction);
393  s.num = 77;
394  DeStateSignatureAppend(state, &s, 0, direction);
395  s.num = 88;
396  DeStateSignatureAppend(state, &s, 0, direction);
397  s.num = 99;
398  DeStateSignatureAppend(state, &s, 0, direction);
399  s.num = 100;
400  DeStateSignatureAppend(state, &s, 0, direction);
401  s.num = 111;
402  DeStateSignatureAppend(state, &s, 0, direction);
403  s.num = 122;
404  DeStateSignatureAppend(state, &s, 0, direction);
405  s.num = 133;
406  DeStateSignatureAppend(state, &s, 0, direction);
407  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
408  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
409  s.num = 144;
410  DeStateSignatureAppend(state, &s, 0, direction);
411  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
412  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
413  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
414  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
415  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
416  s.num = 155;
417  DeStateSignatureAppend(state, &s, 0, direction);
418  s.num = 166;
419  DeStateSignatureAppend(state, &s, 0, direction);
420 
421  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
422  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
423  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
424  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
425  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
426  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
427 
428  DetectEngineStateFree(state);
429 
430  PASS;
431 }
432 
433 static int DeStateTest03(void)
434 {
436  FAIL_IF_NULL(state);
437 
438  Signature s;
439  memset(&s, 0x00, sizeof(s));
440 
441  uint8_t direction = STREAM_TOSERVER;
442 
443  s.num = 11;
444  DeStateSignatureAppend(state, &s, 0, direction);
445  s.num = 22;
446  DeStateSignatureAppend(state, &s, BIT_U32(DE_STATE_FLAG_BASE), direction);
447 
448  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
449  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11);
450  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & BIT_U32(DE_STATE_FLAG_BASE));
451  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22);
452  FAIL_IF(!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & BIT_U32(DE_STATE_FLAG_BASE)));
453 
454  DetectEngineStateFree(state);
455  PASS;
456 }
457 
458 static int DeStateSigTest01(void)
459 {
460  DetectEngineThreadCtx *det_ctx = NULL;
461  ThreadVars th_v;
462  Flow f;
463  TcpSession ssn;
464  Packet *p = NULL;
465  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\n";
466  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\n";
467  uint8_t httpbuf3[] = "Cookie: dummy\r\nContent-Length: 10\r\n\r\n";
468  uint8_t httpbuf4[] = "Http Body!";
469  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
470  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
471  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
472  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
473 
476 
477  memset(&th_v, 0, sizeof(th_v));
478  memset(&f, 0, sizeof(f));
479  memset(&ssn, 0, sizeof(ssn));
480 
481  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
482  FAIL_IF_NULL(p);
483 
484  FLOW_INITIALIZE(&f);
485  f.protoctx = (void *)&ssn;
486  f.proto = IPPROTO_TCP;
487  f.flags |= FLOW_IPV4;
489 
490  p->flow = &f;
494 
495  StreamTcpInitConfig(true);
496 
499  de_ctx->flags |= DE_QUIET;
500 
501  Signature *s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy\"; http_cookie; sid:1; rev:1;)");
502  FAIL_IF_NULL(s);
503 
505  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
506  FAIL_IF_NULL(det_ctx);
507 
508  int r = AppLayerParserParse(
509  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
510  FAIL_IF_NOT(r == 0);
511  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
512  FAIL_IF(PacketAlertCheck(p, 1));
513 
514  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
515  FAIL_IF_NOT(r == 0);
516  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
517  FAIL_IF(PacketAlertCheck(p, 1));
518 
519  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
520  FAIL_IF_NOT(r == 0);
521  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
523 
524  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
525  FAIL_IF_NOT(r == 0);
526  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
527  FAIL_IF(PacketAlertCheck(p, 1));
528 
530  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
532  StreamTcpFreeConfig(true);
533  FLOW_DESTROY(&f);
534  UTHFreePacket(p);
535  PASS;
536 }
537 
538 /** \test multiple pipelined http transactions */
539 static int DeStateSigTest02(void)
540 {
541  DetectEngineThreadCtx *det_ctx = NULL;
542  ThreadVars th_v;
543  Flow f;
544  TcpSession ssn;
545  Packet *p = NULL;
546  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
547  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
548  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
549  uint8_t httpbuf4[] = "Http Body!";
550  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
551  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
552  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
553  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
554  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
555  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
556  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nHttp Body!";
557  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
558  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
559  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
562 
563  memset(&th_v, 0, sizeof(th_v));
564  memset(&f, 0, sizeof(f));
565  memset(&ssn, 0, sizeof(ssn));
566 
567  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
568 
569  FLOW_INITIALIZE(&f);
570  f.protoctx = (void *)&ssn;
571  f.proto = IPPROTO_TCP;
572  f.flags |= FLOW_IPV4;
573 
574  p->flow = &f;
579 
580  StreamTcpInitConfig(true);
581 
584 
585  de_ctx->flags |= DE_QUIET;
586 
587  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:to_server; content:\"POST\"; http_method; content:\"/\"; http_uri; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"body\"; nocase; http_client_body; sid:1; rev:1;)");
588  FAIL_IF_NULL(s);
589  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:to_server; content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; sid:2; rev:1;)");
590  FAIL_IF_NULL(s);
591 
593  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
594  FAIL_IF_NULL(det_ctx);
595 
596  int r = AppLayerParserParse(
597  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
598  FAIL_IF(r != 0);
599  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
600  FAIL_IF(PacketAlertCheck(p, 1));
601 
602  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
603  FAIL_IF(r != 0);
604  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
605  FAIL_IF(PacketAlertCheck(p, 1));
606 
607  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
608  FAIL_IF(r != 0);
609  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
610  FAIL_IF(PacketAlertCheck(p, 1));
611 
612  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f.alstate, 0);
613  FAIL_IF_NULL(tx);
614 
615  AppLayerTxData *tx_data = AppLayerParserGetTxData(IPPROTO_TCP, ALPROTO_HTTP1, tx);
616  FAIL_IF_NULL(tx_data);
617  DetectEngineState *tx_de_state = tx_data->de_state;
618  FAIL_IF_NULL(tx_de_state);
619  FAIL_IF(tx_de_state->dir_state[0].cnt != 1);
620  /* http_header(mpm): 5, uri: 3, method: 6, cookie: 7 */
621  uint32_t expected_flags = (BIT_U32(5) | BIT_U32(3) | BIT_U32(6) | BIT_U32(4));
622  FAIL_IF(tx_de_state->dir_state[0].head->store[0].flags != expected_flags);
623 
624  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
625  FAIL_IF(r != 0);
626  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
627  FAIL_IF(!(PacketAlertCheck(p, 1)));
628 
629  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
630  FAIL_IF(r != 0);
631  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
632  FAIL_IF(PacketAlertCheck(p, 1));
633 
634  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
635  FAIL_IF(r != 0);
636  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
637  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
638 
639  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
640  FAIL_IF(r != 0);
641  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
642  FAIL_IF(!(PacketAlertCheck(p, 2)));
643 
645  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
647  StreamTcpFreeConfig(true);
648  FLOW_DESTROY(&f);
649  UTHFreePacket(p);
650  PASS;
651 }
652 
653 static int DeStateSigTest03(void)
654 {
655  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
656  "Host: www.server.lan\r\n"
657  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
658  "Content-Length: 215\r\n"
659  "\r\n"
660  "-----------------------------277531038314945\r\n"
661  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
662  "Content-Type: image/jpeg\r\n"
663  "\r\n"
664  "filecontent\r\n"
665  "-----------------------------277531038314945--";
666  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
667  ThreadVars th_v;
668  TcpSession ssn;
669  Flow *f = NULL;
670  Packet *p = NULL;
673 
674  memset(&th_v, 0, sizeof(th_v));
675  memset(&ssn, 0, sizeof(ssn));
676 
677  DetectEngineThreadCtx *det_ctx = NULL;
680 
681  de_ctx->flags |= DE_QUIET;
682 
683  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (flow:to_server; content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
684  FAIL_IF_NULL(s);
685 
687  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
688 
689  f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
690  FAIL_IF_NULL(f);
691  f->protoctx = &ssn;
692  f->proto = IPPROTO_TCP;
693  f->alproto = ALPROTO_HTTP1;
694 
695  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
696  FAIL_IF_NULL(p);
697 
698  p->flow = f;
702 
703  StreamTcpInitConfig(true);
704 
705  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
706  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
707  FAIL_IF(r != 0);
708 
709  HtpState *http_state = f->alstate;
710  FAIL_IF_NULL(http_state);
711  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
712  FAIL_IF_NULL(tx);
713  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
714  FAIL_IF_NULL(tx_ud);
715 
716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
717  FAIL_IF(!(PacketAlertCheck(p, 1)));
718 
719  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
720  FileContainer *fc = files.fc;
721  FAIL_IF_NULL(fc);
722 
723  File *file = fc->head;
724  FAIL_IF_NULL(file);
725 
726  FAIL_IF(!(file->flags & FILE_STORE));
727 
729  UTHFreeFlow(f);
730 
731  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
733  StreamTcpFreeConfig(true);
734  PASS;
735 }
736 
737 static int DeStateSigTest04(void)
738 {
739  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
740  "Host: www.server.lan\r\n"
741  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
742  "Content-Length: 215\r\n"
743  "\r\n"
744  "-----------------------------277531038314945\r\n"
745  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
746  "Content-Type: image/jpeg\r\n"
747  "\r\n"
748  "filecontent\r\n"
749  "-----------------------------277531038314945--";
750  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
751  ThreadVars th_v;
752  TcpSession ssn;
755 
756  memset(&th_v, 0, sizeof(th_v));
757  memset(&ssn, 0, sizeof(ssn));
758 
759  DetectEngineThreadCtx *det_ctx = NULL;
762  de_ctx->flags |= DE_QUIET;
763 
764  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
765  FAIL_IF_NULL(s);
766 
768  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
769  FAIL_IF_NULL(det_ctx);
770 
771  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
772  FAIL_IF_NULL(f);
773  f->protoctx = &ssn;
774  f->proto = IPPROTO_TCP;
775  f->alproto = ALPROTO_HTTP1;
776 
777  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
778  FAIL_IF_NULL(p);
779  p->flow = f;
783 
784  StreamTcpInitConfig(true);
785 
786  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
787  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
788  FAIL_IF(r != 0);
789  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
790  FAIL_IF(PacketAlertCheck(p, 1));
791 
792  HtpState *http_state = f->alstate;
793  FAIL_IF_NULL(http_state);
794  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
795  FAIL_IF_NULL(tx);
796  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
797  FAIL_IF_NULL(tx_ud);
798 
799  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
800  FileContainer *fc = files.fc;
801  FAIL_IF_NULL(fc);
802  File *file = fc->head;
803  FAIL_IF_NULL(file);
804 
805  FAIL_IF(file->flags & FILE_STORE);
806 
808  UTHFreeFlow(f);
809  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
811  StreamTcpFreeConfig(true);
812  PASS;
813 }
814 
815 static int DeStateSigTest05(void)
816 {
817  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
818  "Host: www.server.lan\r\n"
819  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
820  "Content-Length: 215\r\n"
821  "\r\n"
822  "-----------------------------277531038314945\r\n"
823  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
824  "Content-Type: image/jpeg\r\n"
825  "\r\n"
826  "filecontent\r\n"
827  "-----------------------------277531038314945--";
828  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
829  ThreadVars th_v;
830  TcpSession ssn;
831 
834 
835  memset(&th_v, 0, sizeof(th_v));
836  memset(&ssn, 0, sizeof(ssn));
837 
838  DetectEngineThreadCtx *det_ctx = NULL;
841  de_ctx->flags |= DE_QUIET;
842 
843  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; sid:1; rev:1;)");
844  FAIL_IF_NULL(s);
845 
847  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
848 
849  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
850  FAIL_IF_NULL(f);
851  f->protoctx = &ssn;
852  f->proto = IPPROTO_TCP;
853  f->alproto = ALPROTO_HTTP1;
854 
855  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
856  FAIL_IF_NULL(p);
857  p->flow = f;
861 
862  StreamTcpInitConfig(true);
863 
864  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
865  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
866  FAIL_IF_NOT(r == 0);
867  HtpState *http_state = f->alstate;
868  FAIL_IF_NULL(http_state);
869  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
870  FAIL_IF_NULL(tx);
871  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
872  FAIL_IF_NULL(tx_ud);
873 
874  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
875  FileContainer *fc = files.fc;
876  FAIL_IF_NULL(fc);
877  File *file = fc->head;
878  FAIL_IF_NULL(file);
879  FAIL_IF(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
880 
881  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
882  FAIL_IF(PacketAlertCheck(p, 1));
883 
884  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
885  * an opportunity to be applied to the file itself yet */
886  FAIL_IF_NOT(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
887  FAIL_IF(file->flags & FILE_NOSTORE);
888 
890  UTHFreeFlow(f);
891  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
893  StreamTcpFreeConfig(true);
894  PASS;
895 }
896 
897 static int DeStateSigTest06(void)
898 {
899  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
900  "Host: www.server.lan\r\n"
901  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
902  "Content-Length: 215\r\n"
903  "\r\n"
904  "-----------------------------277531038314945\r\n"
905  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
906  "Content-Type: image/jpeg\r\n"
907  "\r\n"
908  "filecontent\r\n"
909  "-----------------------------277531038314945--";
910  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
911  ThreadVars th_v;
912  TcpSession ssn;
913 
916 
917  memset(&th_v, 0, sizeof(th_v));
918  memset(&ssn, 0, sizeof(ssn));
919 
920  DetectEngineThreadCtx *det_ctx = NULL;
923  de_ctx->flags |= DE_QUIET;
924 
925  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; filestore; sid:1; rev:1;)");
926  FAIL_IF_NULL(s);
927 
929  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
930  FAIL_IF_NULL(det_ctx);
931 
932  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
933  FAIL_IF_NULL(f);
934  f->protoctx = &ssn;
935  f->proto = IPPROTO_TCP;
936  f->alproto = ALPROTO_HTTP1;
937 
938  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
939  FAIL_IF_NULL(p);
940  p->flow = f;
944 
945  StreamTcpInitConfig(true);
946 
947  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
948  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
949  FAIL_IF(r != 0);
950  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
951  FAIL_IF(PacketAlertCheck(p, 1));
952 
953  HtpState *http_state = f->alstate;
954  FAIL_IF_NULL(http_state);
955  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
956  FAIL_IF_NULL(tx);
957  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
958  FAIL_IF_NULL(tx_ud);
959 
960  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
961  FileContainer *fc = files.fc;
962  FAIL_IF_NULL(fc);
963  File *file = fc->head;
964  FAIL_IF_NULL(file);
965  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
966  * an opportunity to be applied to the file itself yet */
967  FAIL_IF_NOT(tx_ud->tx_data.file_flags & FLOWFILE_NO_STORE_TS);
968  FAIL_IF(file->flags & FILE_NOSTORE);
969 
971  UTHFreeFlow(f);
972  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
974  StreamTcpFreeConfig(true);
975  PASS;
976 }
977 
978 static int DeStateSigTest07(void)
979 {
980  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
981  "Host: www.server.lan\r\n"
982  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
983  "Content-Length: 215\r\n"
984  "\r\n"
985  "-----------------------------277531038314945\r\n"
986  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
987  "Content-Type: image/jpeg\r\n"
988  "\r\n";
989 
990  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
991  uint8_t httpbuf2[] = "filecontent\r\n"
992  "-----------------------------277531038314945--";
993  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
994  ThreadVars th_v;
995  TcpSession ssn;
996 
999 
1000  memset(&th_v, 0, sizeof(th_v));
1001  memset(&ssn, 0, sizeof(ssn));
1002 
1003  DetectEngineThreadCtx *det_ctx = NULL;
1006  de_ctx->flags |= DE_QUIET;
1007 
1008  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
1009  FAIL_IF_NULL(s);
1010 
1012  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1013 
1014  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1015  FAIL_IF_NULL(f);
1016  f->protoctx = &ssn;
1017  f->proto = IPPROTO_TCP;
1018  f->alproto = ALPROTO_HTTP1;
1019 
1020  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1021  FAIL_IF_NULL(p);
1022  p->flow = f;
1026 
1027  StreamTcpInitConfig(true);
1028 
1029  int r = AppLayerParserParse(
1030  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1031  FAIL_IF(r != 0);
1032  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1033  FAIL_IF(PacketAlertCheck(p, 1));
1034 
1035  r = AppLayerParserParse(
1036  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf2, httplen2);
1037  FAIL_IF(r != 0);
1038  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1039  FAIL_IF(PacketAlertCheck(p, 1));
1040 
1041  HtpState *http_state = f->alstate;
1042  FAIL_IF_NULL(http_state);
1043  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1044  FAIL_IF_NULL(tx);
1045  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1046  FAIL_IF_NULL(tx_ud);
1047 
1048  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1049  FileContainer *fc = files.fc;
1050  FAIL_IF_NULL(fc);
1051  File *file = fc->head;
1052  FAIL_IF_NULL(file);
1053  FAIL_IF(file->flags & FILE_STORE);
1054 
1056  UTHFreeFlow(f);
1057  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1059  StreamTcpFreeConfig(true);
1060  PASS;
1061 }
1062 
1063 /**
1064  * \test multiple files in a tx
1065  */
1066 static int DeStateSigTest08(void)
1067 {
1068  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1069  "Host: www.server.lan\r\n"
1070  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1071  "Content-Length: 440\r\n"
1072  "\r\n"
1073  "-----------------------------277531038314945\r\n"
1074  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"AAAApicture1.jpg\"\r\n"
1075  "Content-Type: image/jpeg\r\n"
1076  "\r\n";
1077 
1078  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1079  uint8_t httpbuf2[] = "file";
1080  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1081  uint8_t httpbuf3[] = "content\r\n"
1082  "-----------------------------277531038314945\r\n";
1083  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1084 
1085  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"BBBBpicture2.jpg\"\r\n"
1086  "Content-Type: image/jpeg\r\n"
1087  "\r\n"
1088  "filecontent2\r\n"
1089  "-----------------------------277531038314945--";
1090  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1091 
1092  ThreadVars th_v;
1093  TcpSession ssn;
1094 
1097 
1098  memset(&th_v, 0, sizeof(th_v));
1099  memset(&ssn, 0, sizeof(ssn));
1100 
1101  DetectEngineThreadCtx *det_ctx = NULL;
1104  de_ctx->flags |= DE_QUIET;
1105 
1106  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"BBBBpicture\"; filestore; sid:1; rev:1;)");
1107  FAIL_IF_NULL(s);
1108 
1110  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1111 
1112  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1113  FAIL_IF_NULL(f);
1114  f->protoctx = &ssn;
1115  f->proto = IPPROTO_TCP;
1116  f->alproto = ALPROTO_HTTP1;
1117 
1118  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1119  FAIL_IF_NULL(p);
1120  p->flow = f;
1124 
1125  StreamTcpInitConfig(true);
1126 
1127  /* HTTP request with 1st part of the multipart body */
1128 
1129  int r = AppLayerParserParse(
1130  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1131  FAIL_IF(r != 0);
1132  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1133  FAIL_IF(PacketAlertCheck(p, 1));
1134 
1135  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1136  FAIL_IF(r != 0);
1137  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1138  FAIL_IF(PacketAlertCheck(p, 1));
1139 
1140  HtpState *http_state = f->alstate;
1141  FAIL_IF_NULL(http_state);
1142  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1143  FAIL_IF_NULL(tx);
1144  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1145  FAIL_IF_NULL(tx_ud);
1146 
1147  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1148  FileContainer *fc = files.fc;
1149  FAIL_IF_NULL(fc);
1150  File *file = fc->head;
1151  FAIL_IF_NULL(file);
1152  FAIL_IF(file->flags & FILE_STORE);
1153 
1154  /* 2nd multipart body file */
1155 
1156  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1157  FAIL_IF(r != 0);
1158  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1159  FAIL_IF(PacketAlertCheck(p, 1));
1160 
1161  r = AppLayerParserParse(
1162  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1163  FAIL_IF(r != 0);
1164  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1166 
1167  http_state = f->alstate;
1168  FAIL_IF_NULL(http_state);
1169  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1170  FAIL_IF_NULL(tx);
1171  tx_ud = htp_tx_get_user_data(tx);
1172  FAIL_IF_NULL(tx_ud);
1173 
1174  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1175  fc = files.fc;
1176  FAIL_IF_NULL(fc);
1177  file = fc->head;
1178  FAIL_IF_NULL(file);
1179  file = file->next;
1180  FAIL_IF_NULL(file);
1181  FAIL_IF_NOT(file->flags & FILE_STORE);
1182 
1184  UTHFreeFlow(f);
1185  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1187  StreamTcpFreeConfig(true);
1188  PASS;
1189 }
1190 
1191 /**
1192  * \test multiple files in a tx. Both files should match
1193  */
1194 static int DeStateSigTest09(void)
1195 {
1196  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1197  "Host: www.server.lan\r\n"
1198  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1199  "Content-Length: 440\r\n"
1200  "\r\n"
1201  "-----------------------------277531038314945\r\n"
1202  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1203  "Content-Type: image/jpeg\r\n"
1204  "\r\n";
1205 
1206  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1207  uint8_t httpbuf2[] = "file";
1208  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1209  uint8_t httpbuf3[] = "content\r\n"
1210  "-----------------------------277531038314945\r\n";
1211  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1212 
1213  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1214  "Content-Type: image/jpeg\r\n"
1215  "\r\n"
1216  "filecontent2\r\n"
1217  "-----------------------------277531038314945--";
1218  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1219 
1220  ThreadVars th_v;
1221  TcpSession ssn;
1222 
1225 
1226  memset(&th_v, 0, sizeof(th_v));
1227  memset(&ssn, 0, sizeof(ssn));
1228 
1229  DetectEngineThreadCtx *det_ctx = NULL;
1232  de_ctx->flags |= DE_QUIET;
1233 
1234  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1235  FAIL_IF_NULL(s);
1236 
1238  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1239 
1240  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1241  FAIL_IF_NULL(f);
1242  f->protoctx = &ssn;
1243  f->proto = IPPROTO_TCP;
1244  f->alproto = ALPROTO_HTTP1;
1245 
1246  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1247  FAIL_IF_NULL(p);
1248  p->flow = f;
1252 
1253  StreamTcpInitConfig(true);
1254 
1255  /* HTTP request with 1st part of the multipart body */
1256 
1257  int r = AppLayerParserParse(
1258  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1259  FAIL_IF(r != 0);
1260  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1262 
1263  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1264  FAIL_IF(r != 0);
1265  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1266  FAIL_IF(PacketAlertCheck(p, 1));
1267 
1268  HtpState *http_state = f->alstate;
1269  FAIL_IF_NULL(http_state);
1270  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1271  FAIL_IF_NULL(tx);
1272  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1273  FAIL_IF_NULL(tx_ud);
1274 
1275  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1276  FileContainer *fc = files.fc;
1277  FAIL_IF_NULL(fc);
1278  File *file = fc->head;
1279  FAIL_IF_NULL(file);
1280  FAIL_IF_NOT(file->flags & FILE_STORE);
1281 
1282  /* 2nd multipart body file */
1283 
1284  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1285  FAIL_IF(r != 0);
1286  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1287  FAIL_IF(PacketAlertCheck(p, 1));
1288 
1289  r = AppLayerParserParse(
1290  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1291  FAIL_IF(r != 0);
1292  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1294 
1295  http_state = f->alstate;
1296  FAIL_IF_NULL(http_state);
1297  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1298  FAIL_IF_NULL(tx);
1299  tx_ud = htp_tx_get_user_data(tx);
1300  FAIL_IF_NULL(tx_ud);
1301 
1302  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1303  fc = files.fc;
1304  FAIL_IF_NULL(fc);
1305  file = fc->head;
1306  FAIL_IF_NULL(file);
1307  FAIL_IF_NOT(file->flags & FILE_STORE);
1308 
1310  UTHFreeFlow(f);
1311  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1313  StreamTcpFreeConfig(true);
1314  PASS;
1315 }
1316 
1317 /**
1318  * \test multiple files in a tx. Both files should match. No other matches.
1319  */
1320 static int DeStateSigTest10(void)
1321 {
1322  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1323  "Host: www.server.lan\r\n"
1324  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1325  "Content-Length: 440\r\n"
1326  "\r\n"
1327  "-----------------------------277531038314945\r\n"
1328  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1329  "Content-Type: image/jpeg\r\n"
1330  "\r\n";
1331 
1332  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1333  uint8_t httpbuf2[] = "file";
1334  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1335  uint8_t httpbuf3[] = "content\r\n"
1336  "-----------------------------277531038314945\r\n";
1337  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1338 
1339  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1340  "Content-Type: image/jpeg\r\n"
1341  "\r\n"
1342  "filecontent2\r\n"
1343  "-----------------------------277531038314945--";
1344  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1345 
1346  ThreadVars th_v;
1347  TcpSession ssn;
1348 
1351 
1352  memset(&th_v, 0, sizeof(th_v));
1353  memset(&ssn, 0, sizeof(ssn));
1354 
1355  DetectEngineThreadCtx *det_ctx = NULL;
1358  de_ctx->flags |= DE_QUIET;
1359 
1360  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1361  FAIL_IF_NULL(s);
1362 
1364  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1365 
1366  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1367  FAIL_IF_NULL(f);
1368  f->protoctx = &ssn;
1369  f->proto = IPPROTO_TCP;
1370  f->alproto = ALPROTO_HTTP1;
1371 
1372  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1373  FAIL_IF_NULL(p);
1374  p->flow = f;
1378 
1379  StreamTcpInitConfig(true);
1380 
1381  /* HTTP request with 1st part of the multipart body */
1382 
1383  int r = AppLayerParserParse(
1384  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1385  FAIL_IF(r != 0);
1386  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1388 
1389  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1390  FAIL_IF(r != 0);
1391  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1392  FAIL_IF(PacketAlertCheck(p, 1));
1393 
1394  HtpState *http_state = f->alstate;
1395  FAIL_IF_NULL(http_state);
1396  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1397  FAIL_IF_NULL(tx);
1398  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1399  FAIL_IF_NULL(tx_ud);
1400 
1401  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1402  FileContainer *fc = files.fc;
1403  FAIL_IF_NULL(fc);
1404  File *file = fc->head;
1405  FAIL_IF_NULL(file);
1406  FAIL_IF_NOT(file->flags & FILE_STORE);
1407 
1408  /* 2nd multipart body file */
1409 
1410  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1411  FAIL_IF(r != 0);
1412  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1413  FAIL_IF(PacketAlertCheck(p, 1));
1414 
1415  r = AppLayerParserParse(
1416  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1417  FAIL_IF(r != 0);
1418  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1420 
1421  http_state = f->alstate;
1422  FAIL_IF_NULL(http_state);
1423  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1424  FAIL_IF_NULL(tx);
1425  tx_ud = htp_tx_get_user_data(tx);
1426  FAIL_IF_NULL(tx_ud);
1427 
1428  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1429  fc = files.fc;
1430  FAIL_IF_NULL(fc);
1431  file = fc->head;
1432  FAIL_IF_NULL(file);
1433  FAIL_IF_NOT(file->flags & FILE_STORE);
1434 
1436  UTHFreeFlow(f);
1437  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1439  StreamTcpFreeConfig(true);
1440  PASS;
1441 }
1442 
1443 #endif
1444 
1446 {
1447 #ifdef UNITTESTS
1448  UtRegisterTest("DeStateTest01", DeStateTest01);
1449  UtRegisterTest("DeStateTest02", DeStateTest02);
1450  UtRegisterTest("DeStateTest03", DeStateTest03);
1451  UtRegisterTest("DeStateSigTest01", DeStateSigTest01);
1452  UtRegisterTest("DeStateSigTest02", DeStateSigTest02);
1453  UtRegisterTest("DeStateSigTest03", DeStateSigTest03);
1454  UtRegisterTest("DeStateSigTest04", DeStateSigTest04);
1455  UtRegisterTest("DeStateSigTest05", DeStateSigTest05);
1456  UtRegisterTest("DeStateSigTest06", DeStateSigTest06);
1457  UtRegisterTest("DeStateSigTest07", DeStateSigTest07);
1458  UtRegisterTest("DeStateSigTest08", DeStateSigTest08);
1459  UtRegisterTest("DeStateSigTest09", DeStateSigTest09);
1460  UtRegisterTest("DeStateSigTest10", DeStateSigTest10);
1461 #endif
1462 }
1463 
1464 /**
1465  * @}
1466  */
FileContainer_
Definition: util-file.h:113
DE_STATE_CHUNK_SIZE
#define DE_STATE_CHUNK_SIZE
Definition: detect-engine-state.h:52
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectEngineStateDirection_::flags
uint8_t flags
Definition: detect-engine-state.h:88
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1242
flow-util.h
DetectEngineState_
Definition: detect-engine-state.h:92
Signature_::num
SigIntId num
Definition: detect.h:681
stream-tcp.h
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1570
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DetectEngineStateDirection_::cnt
SigIntId cnt
Definition: detect-engine-state.h:86
Flow_::proto
uint8_t proto
Definition: flow.h:378
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
Packet_::flags
uint32_t flags
Definition: decode.h:527
Flow_
Flow data structure.
Definition: flow.h:356
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:920
FILE_STORE
#define FILE_STORE
Definition: util-file.h:55
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2799
DetectEngineState_::dir_state
DetectEngineStateDirection dir_state[2]
Definition: detect-engine-state.h:93
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:322
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:233
SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_TXBOTHDIR
Definition: detect.h:249
MIN
#define MIN(x, y)
Definition: suricata-common.h:400
DE_QUIET
#define DE_QUIET
Definition: detect.h:329
stream-tcp-reassemble.h
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:359
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2319
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3344
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:515
Flow_::protoctx
void * protoctx
Definition: flow.h:441
DeStateStoreItem_::sid
SigIntId sid
Definition: detect-engine-state.h:74
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:731
util-unittest.h
DetectEngineStateDirection_::cur
DeStateStore * cur
Definition: detect-engine-state.h:84
HtpState_
Definition: app-layer-htp.h:181
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
AppLayerParserGetTxFiles
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *tx, const uint8_t direction)
Definition: app-layer-parser.c:878
detect-flowvar.h
DetectRunStoreStateTx
void DetectRunStoreStateTx(const SigGroupHead *sgh, Flow *f, void *tx, uint64_t tx_id, const Signature *s, uint32_t inspect_flags, uint8_t flow_flags, const uint16_t file_no_match)
Definition: detect-engine-state.c:214
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:478
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:488
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:482
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
app-layer-htp.h
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1197
DeStateStoreItem_::flags
uint32_t flags
Definition: detect-engine-state.h:73
FLOWFILE_NO_STORE_TS
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:134
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:409
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
FileContainer_::head
File * head
Definition: util-file.h:114
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DeStateStore_::next
struct DeStateStore_ * next
Definition: detect-engine-state.h:79
HtpState_::conn
htp_conn_t * conn
Definition: app-layer-htp.h:185
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3525
HtpTxUserData_::tx_data
AppLayerTxData tx_data
Definition: app-layer-htp.h:176
HtpState_::state_data
AppLayerStateData state_data
Definition: app-layer-htp.h:198
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:3002
app-layer-parser.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:309
util-profiling.h
DetectEngineStateAlloc
DetectEngineState * DetectEngineStateAlloc(void)
Alloc a DetectEngineState object.
Definition: detect-engine-state.c:160
SCReturn
#define SCReturn
Definition: util-debug.h:273
Signature_::flags
uint32_t flags
Definition: detect.h:670
Packet_
Definition: decode.h:484
DE_STATE_FLAG_BASE
#define DE_STATE_FLAG_BASE
Definition: detect-engine-state.h:63
detect-engine-build.h
stream-tcp-private.h
detect-engine-alert.h
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1118
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:169
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2129
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:487
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:295
FileDisableStoringForTransaction
void FileDisableStoringForTransaction(Flow *f, const uint8_t direction, void *tx, uint64_t tx_id)
disable file storing for files in a transaction
Definition: util-file.c:1156
File_::flags
uint16_t flags
Definition: util-file.h:80
DetectEngineStateDirection_::head
DeStateStore * head
Definition: detect-engine-state.h:83
File_
Definition: util-file.h:79
AppLayerTxData
struct AppLayerTxData AppLayerTxData
Definition: detect.h:1466
Packet_::flow
struct Flow_ * flow
Definition: decode.h:529
DetectEngineStateResetTxs
void DetectEngineStateResetTxs(Flow *f)
Reset de state for active tx' To be used on detect engine reload.
Definition: detect-engine-state.c:265
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:859
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1300
suricata-common.h
DeStateStore_
Definition: detect-engine-state.h:77
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
File_::next
struct File_ * next
Definition: util-file.h:92
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3751
DetectEngineStateDirection_
Definition: detect-engine-state.h:82
AppLayerParserGetTxData
AppLayerTxData * AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1192
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:929
HtpTxUserData_
Definition: app-layer-htp.h:151
DetectEngineStateDirection_::filestore_cnt
uint16_t filestore_cnt
Definition: detect-engine-state.h:87
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467
Flow_::alstate
void * alstate
Definition: flow.h:479
DeStateStore_::store
DeStateStoreItem store[DE_STATE_CHUNK_SIZE]
Definition: detect-engine-state.h:78
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
Signature_
Signature container.
Definition: detect.h:669
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:235
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2760
app-layer-protos.h
FILE_NOSTORE
#define FILE_NOSTORE
Definition: util-file.h:54
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:922
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
TcpSession_
Definition: stream-tcp-private.h:283
SigIntId
#define SigIntId
Definition: suricata-common.h:324
DeStateStoreItem_
Definition: detect-engine-state.h:72
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
DeStateRegisterTests
void DeStateRegisterTests(void)
Definition: detect-engine-state.c:1445
detect-engine-dcepayload.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SigGroupHead_::filestore_cnt
uint16_t filestore_cnt
Definition: detect.h:1576
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1111
DetectEngineStateDirection_::tail
DeStateStore * tail
Definition: detect-engine-state.h:85
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1239
app-layer.h