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