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->iid));
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->iid;
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  if (tx_data->de_state == NULL) {
223  tx_data->de_state = DetectEngineStateAlloc();
224  if (tx_data->de_state == NULL)
225  return;
226  SCLogDebug("destate created for %"PRIu64, tx_id);
227  }
228  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags, flow_flags);
229  if (s->flags & SIG_FLAG_TXBOTHDIR) {
230  // add also in the other DetectEngineStateDirection
231  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags,
232  flow_flags ^ (STREAM_TOSERVER | STREAM_TOCLIENT));
233  }
234  StoreStateTxHandleFiles(sgh, f, tx_data->de_state, flow_flags, tx, tx_id, file_no_match);
235 
236  SCLogDebug("Stored for TX %"PRIu64, tx_id);
237 }
238 
239 static inline void ResetTxState(DetectEngineState *s)
240 {
241  if (s) {
242  s->dir_state[0].cnt = 0;
243  s->dir_state[0].filestore_cnt = 0;
244  s->dir_state[0].flags = 0;
245  /* reset 'cur' back to the list head */
246  s->dir_state[0].cur = s->dir_state[0].head;
247 
248  s->dir_state[1].cnt = 0;
249  s->dir_state[1].filestore_cnt = 0;
250  s->dir_state[1].flags = 0;
251  /* reset 'cur' back to the list head */
252  s->dir_state[1].cur = s->dir_state[1].head;
253  }
254 }
255 
256 /** \brief Reset de state for active tx'
257  * To be used on detect engine reload.
258  * \param f write LOCKED flow
259  */
261 {
262  void *alstate = FlowGetAppState(f);
263  if (!StateIsValid(f->alproto, alstate)) {
264  return;
265  }
266 
267  uint64_t inspect_ts = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOCLIENT);
268  uint64_t inspect_tc = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOSERVER);
269 
270  uint64_t inspect_tx_id = MIN(inspect_ts, inspect_tc);
271 
272  uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
273 
274  for ( ; inspect_tx_id < total_txs; inspect_tx_id++) {
275  void *inspect_tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, inspect_tx_id);
276  if (inspect_tx != NULL) {
277  AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, inspect_tx);
278  ResetTxState(txd->de_state);
279  }
280  }
281 }
282 
283 /*********Unittests*********/
284 
285 #ifdef UNITTESTS
286 #include "detect-engine-alert.h"
287 
288 static int DeStateTest01(void)
289 {
290  SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX,
291  (uintmax_t)sizeof(DetectEngineState));
292  SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX,
293  (uintmax_t)sizeof(DeStateStore));
294  SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"",
295  (uintmax_t)sizeof(DeStateStoreItem));
296 
297  return 1;
298 }
299 
300 static int DeStateTest02(void)
301 {
302  uint8_t direction = STREAM_TOSERVER;
304  FAIL_IF_NULL(state);
305  FAIL_IF_NOT_NULL(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head);
306 
307  Signature s;
308  memset(&s, 0x00, sizeof(s));
309 
310  s.iid = 0;
311  DeStateSignatureAppend(state, &s, 0, direction);
312  s.iid = 11;
313  DeStateSignatureAppend(state, &s, 0, direction);
314  s.iid = 22;
315  DeStateSignatureAppend(state, &s, 0, direction);
316  s.iid = 33;
317  DeStateSignatureAppend(state, &s, 0, direction);
318  s.iid = 44;
319  DeStateSignatureAppend(state, &s, 0, direction);
320  s.iid = 55;
321  DeStateSignatureAppend(state, &s, 0, direction);
322  s.iid = 66;
323  DeStateSignatureAppend(state, &s, 0, direction);
324  s.iid = 77;
325  DeStateSignatureAppend(state, &s, 0, direction);
326  s.iid = 88;
327  DeStateSignatureAppend(state, &s, 0, direction);
328  s.iid = 99;
329  DeStateSignatureAppend(state, &s, 0, direction);
330  s.iid = 100;
331  DeStateSignatureAppend(state, &s, 0, direction);
332  s.iid = 111;
333  DeStateSignatureAppend(state, &s, 0, direction);
334  s.iid = 122;
335  DeStateSignatureAppend(state, &s, 0, direction);
336  s.iid = 133;
337  DeStateSignatureAppend(state, &s, 0, direction);
338  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
339  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
340 
341  s.iid = 144;
342  DeStateSignatureAppend(state, &s, 0, direction);
343 
344  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
345  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
346  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
347  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur == NULL);
348 
349  s.iid = 155;
350  DeStateSignatureAppend(state, &s, 0, direction);
351 
352  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
353  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
354 
355  s.iid = 166;
356  DeStateSignatureAppend(state, &s, 0, direction);
357 
358  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
359  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
360  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
361  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
362  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
363  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
364 
365  ResetTxState(state);
366 
367  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
368  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
369  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
370 
371  s.iid = 0;
372  DeStateSignatureAppend(state, &s, 0, direction);
373  s.iid = 11;
374  DeStateSignatureAppend(state, &s, 0, direction);
375  s.iid = 22;
376  DeStateSignatureAppend(state, &s, 0, direction);
377  s.iid = 33;
378  DeStateSignatureAppend(state, &s, 0, direction);
379  s.iid = 44;
380  DeStateSignatureAppend(state, &s, 0, direction);
381  s.iid = 55;
382  DeStateSignatureAppend(state, &s, 0, direction);
383  s.iid = 66;
384  DeStateSignatureAppend(state, &s, 0, direction);
385  s.iid = 77;
386  DeStateSignatureAppend(state, &s, 0, direction);
387  s.iid = 88;
388  DeStateSignatureAppend(state, &s, 0, direction);
389  s.iid = 99;
390  DeStateSignatureAppend(state, &s, 0, direction);
391  s.iid = 100;
392  DeStateSignatureAppend(state, &s, 0, direction);
393  s.iid = 111;
394  DeStateSignatureAppend(state, &s, 0, direction);
395  s.iid = 122;
396  DeStateSignatureAppend(state, &s, 0, direction);
397  s.iid = 133;
398  DeStateSignatureAppend(state, &s, 0, direction);
399  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
400  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
401  s.iid = 144;
402  DeStateSignatureAppend(state, &s, 0, direction);
403  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
404  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
405  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
406  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
407  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
408  s.iid = 155;
409  DeStateSignatureAppend(state, &s, 0, direction);
410  s.iid = 166;
411  DeStateSignatureAppend(state, &s, 0, direction);
412 
413  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
414  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
415  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
416  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
417  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
418  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
419 
421 
422  PASS;
423 }
424 
425 static int DeStateTest03(void)
426 {
428  FAIL_IF_NULL(state);
429 
430  Signature s;
431  memset(&s, 0x00, sizeof(s));
432 
433  uint8_t direction = STREAM_TOSERVER;
434 
435  s.iid = 11;
436  DeStateSignatureAppend(state, &s, 0, direction);
437  s.iid = 22;
438  DeStateSignatureAppend(state, &s, BIT_U32(DE_STATE_FLAG_BASE), direction);
439 
440  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
441  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11);
442  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & BIT_U32(DE_STATE_FLAG_BASE));
443  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22);
444  FAIL_IF(!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & BIT_U32(DE_STATE_FLAG_BASE)));
445 
447  PASS;
448 }
449 
450 static int DeStateSigTest01(void)
451 {
452  DetectEngineThreadCtx *det_ctx = NULL;
453  ThreadVars th_v;
454  Flow f;
455  TcpSession ssn;
456  Packet *p = NULL;
457  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\n";
458  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\n";
459  uint8_t httpbuf3[] = "Cookie: dummy\r\nContent-Length: 10\r\n\r\n";
460  uint8_t httpbuf4[] = "Http Body!";
461  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
462  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
463  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
464  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
465 
468 
469  memset(&th_v, 0, sizeof(th_v));
470  StatsThreadInit(&th_v.stats);
471  memset(&f, 0, sizeof(f));
472  memset(&ssn, 0, sizeof(ssn));
473 
474  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
475  FAIL_IF_NULL(p);
476 
477  FLOW_INITIALIZE(&f);
478  f.protoctx = (void *)&ssn;
479  f.proto = IPPROTO_TCP;
480  f.flags |= FLOW_IPV4;
482 
483  p->flow = &f;
487 
488  StreamTcpInitConfig(true);
489 
492  de_ctx->flags |= DE_QUIET;
493 
494  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;)");
495  FAIL_IF_NULL(s);
496 
498  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
499  FAIL_IF_NULL(det_ctx);
500 
501  int r = AppLayerParserParse(
502  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
503  FAIL_IF_NOT(r == 0);
504  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
505  FAIL_IF(PacketAlertCheck(p, 1));
506 
507  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
508  FAIL_IF_NOT(r == 0);
509  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
510  FAIL_IF(PacketAlertCheck(p, 1));
511 
512  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
513  FAIL_IF_NOT(r == 0);
514  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
516 
517  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
518  FAIL_IF_NOT(r == 0);
519  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
520  FAIL_IF(PacketAlertCheck(p, 1));
521 
522  UTHFreePacket(p);
523  FLOW_DESTROY(&f);
525  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
527  StreamTcpFreeConfig(true);
528  StatsThreadCleanup(&th_v.stats);
529  PASS;
530 }
531 
532 /** \test multiple pipelined http transactions */
533 static int DeStateSigTest02(void)
534 {
535  DetectEngineThreadCtx *det_ctx = NULL;
536  ThreadVars th_v;
537  Flow f;
538  TcpSession ssn;
539  Packet *p = NULL;
540  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
541  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
542  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
543  uint8_t httpbuf4[] = "Http Body!";
544  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
545  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
546  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
547  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
548  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
549  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
550  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nHttp Body!";
551  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
552  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
553  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
556 
557  memset(&th_v, 0, sizeof(th_v));
558  StatsThreadInit(&th_v.stats);
559  memset(&f, 0, sizeof(f));
560  memset(&ssn, 0, sizeof(ssn));
561 
562  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
563 
564  FLOW_INITIALIZE(&f);
565  f.protoctx = (void *)&ssn;
566  f.proto = IPPROTO_TCP;
567  f.flags |= FLOW_IPV4;
568 
569  p->flow = &f;
574 
575  StreamTcpInitConfig(true);
576 
579 
580  de_ctx->flags |= DE_QUIET;
581 
582  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;)");
583  FAIL_IF_NULL(s);
584  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;)");
585  FAIL_IF_NULL(s);
586 
588  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
589  FAIL_IF_NULL(det_ctx);
590 
591  int r = AppLayerParserParse(
592  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
593  FAIL_IF(r != 0);
594  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
595  FAIL_IF(PacketAlertCheck(p, 1));
596 
597  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
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, httpbuf3, httplen3);
603  FAIL_IF(r != 0);
604  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
605  FAIL_IF(PacketAlertCheck(p, 1));
606 
607  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f.alstate, 0);
608  FAIL_IF_NULL(tx);
609 
610  AppLayerTxData *tx_data = AppLayerParserGetTxData(IPPROTO_TCP, ALPROTO_HTTP1, tx);
611  FAIL_IF_NULL(tx_data);
612  DetectEngineState *tx_de_state = tx_data->de_state;
613  FAIL_IF_NULL(tx_de_state);
614  FAIL_IF(tx_de_state->dir_state[0].cnt != 1);
615  /* http_header(mpm): 5, uri: 3, method: 6, cookie: 7 */
616  uint32_t expected_flags = (BIT_U32(5) | BIT_U32(3) | BIT_U32(6) | BIT_U32(4));
617  FAIL_IF(tx_de_state->dir_state[0].head->store[0].flags != expected_flags);
618 
619  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
620  FAIL_IF(r != 0);
621  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
622  FAIL_IF(!(PacketAlertCheck(p, 1)));
623 
624  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
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, httpbuf6, httplen6);
630  FAIL_IF(r != 0);
631  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
632  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
633 
634  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
635  FAIL_IF(r != 0);
636  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
637  FAIL_IF(!(PacketAlertCheck(p, 2)));
638 
639  UTHFreePacket(p);
640  FLOW_DESTROY(&f);
642  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
644  StreamTcpFreeConfig(true);
645  StatsThreadCleanup(&th_v.stats);
646  PASS;
647 }
648 
649 static int DeStateSigTest03(void)
650 {
651  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
652  "Host: www.server.lan\r\n"
653  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
654  "Content-Length: 215\r\n"
655  "\r\n"
656  "-----------------------------277531038314945\r\n"
657  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
658  "Content-Type: image/jpeg\r\n"
659  "\r\n"
660  "filecontent\r\n"
661  "-----------------------------277531038314945--";
662  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
663  ThreadVars th_v;
664  TcpSession ssn;
665  Flow *f = NULL;
666  Packet *p = NULL;
669 
670  memset(&th_v, 0, sizeof(th_v));
671  StatsThreadInit(&th_v.stats);
672  memset(&ssn, 0, sizeof(ssn));
673 
674  DetectEngineThreadCtx *det_ctx = NULL;
677 
678  de_ctx->flags |= DE_QUIET;
679 
680  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;)");
681  FAIL_IF_NULL(s);
682 
684  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
685 
686  f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
687  FAIL_IF_NULL(f);
688  f->protoctx = &ssn;
689  f->proto = IPPROTO_TCP;
690  f->alproto = ALPROTO_HTTP1;
691 
692  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
693  FAIL_IF_NULL(p);
694 
695  p->flow = f;
699 
700  StreamTcpInitConfig(true);
701 
702  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
703  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
704  FAIL_IF(r != 0);
705 
706  HtpState *http_state = f->alstate;
707  FAIL_IF_NULL(http_state);
708  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
709  FAIL_IF_NULL(tx);
710  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
711  FAIL_IF_NULL(tx_ud);
712 
713  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
714  FAIL_IF(!(PacketAlertCheck(p, 1)));
715 
716  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
717  FileContainer *fc = files.fc;
718  FAIL_IF_NULL(fc);
719 
720  File *file = fc->head;
721  FAIL_IF_NULL(file);
722 
723  FAIL_IF(!(file->flags & FILE_STORE));
724 
725  UTHFreePacket(p);
726  UTHFreeFlow(f);
727 
729  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
731  StreamTcpFreeConfig(true);
732  StatsThreadCleanup(&th_v.stats);
733  PASS;
734 }
735 
736 static int DeStateSigTest04(void)
737 {
738  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
739  "Host: www.server.lan\r\n"
740  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
741  "Content-Length: 215\r\n"
742  "\r\n"
743  "-----------------------------277531038314945\r\n"
744  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
745  "Content-Type: image/jpeg\r\n"
746  "\r\n"
747  "filecontent\r\n"
748  "-----------------------------277531038314945--";
749  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
750  ThreadVars th_v;
751  TcpSession ssn;
754 
755  memset(&th_v, 0, sizeof(th_v));
756  StatsThreadInit(&th_v.stats);
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 
807  UTHFreePacket(p);
808  UTHFreeFlow(f);
810  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
812  StreamTcpFreeConfig(true);
813  StatsThreadCleanup(&th_v.stats);
814  PASS;
815 }
816 
817 static int DeStateSigTest05(void)
818 {
819  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
820  "Host: www.server.lan\r\n"
821  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
822  "Content-Length: 215\r\n"
823  "\r\n"
824  "-----------------------------277531038314945\r\n"
825  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
826  "Content-Type: image/jpeg\r\n"
827  "\r\n"
828  "filecontent\r\n"
829  "-----------------------------277531038314945--";
830  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
831  ThreadVars th_v;
832  TcpSession ssn;
833 
836 
837  memset(&th_v, 0, sizeof(th_v));
838  StatsThreadInit(&th_v.stats);
839  memset(&ssn, 0, sizeof(ssn));
840 
841  DetectEngineThreadCtx *det_ctx = NULL;
844  de_ctx->flags |= DE_QUIET;
845 
846  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;)");
847  FAIL_IF_NULL(s);
848 
850  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
851 
852  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
853  FAIL_IF_NULL(f);
854  f->protoctx = &ssn;
855  f->proto = IPPROTO_TCP;
856  f->alproto = ALPROTO_HTTP1;
857 
858  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
859  FAIL_IF_NULL(p);
860  p->flow = f;
864 
865  StreamTcpInitConfig(true);
866 
867  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
868  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
869  FAIL_IF_NOT(r == 0);
870  HtpState *http_state = f->alstate;
871  FAIL_IF_NULL(http_state);
872  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
873  FAIL_IF_NULL(tx);
874  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
875  FAIL_IF_NULL(tx_ud);
876 
877  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
878  FileContainer *fc = files.fc;
879  FAIL_IF_NULL(fc);
880  File *file = fc->head;
881  FAIL_IF_NULL(file);
882  FAIL_IF(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
883 
884  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
885  FAIL_IF(PacketAlertCheck(p, 1));
886 
887  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
888  * an opportunity to be applied to the file itself yet */
889  FAIL_IF_NOT(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
890  FAIL_IF(file->flags & FILE_NOSTORE);
891 
892  UTHFreePacket(p);
893  UTHFreeFlow(f);
895  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
897  StreamTcpFreeConfig(true);
898  StatsThreadCleanup(&th_v.stats);
899  PASS;
900 }
901 
902 static int DeStateSigTest06(void)
903 {
904  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
905  "Host: www.server.lan\r\n"
906  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
907  "Content-Length: 215\r\n"
908  "\r\n"
909  "-----------------------------277531038314945\r\n"
910  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
911  "Content-Type: image/jpeg\r\n"
912  "\r\n"
913  "filecontent\r\n"
914  "-----------------------------277531038314945--";
915  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
916  ThreadVars th_v;
917  TcpSession ssn;
918 
921 
922  memset(&th_v, 0, sizeof(th_v));
923  StatsThreadInit(&th_v.stats);
924  memset(&ssn, 0, sizeof(ssn));
925 
926  DetectEngineThreadCtx *det_ctx = NULL;
929  de_ctx->flags |= DE_QUIET;
930 
931  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;)");
932  FAIL_IF_NULL(s);
933 
935  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
936  FAIL_IF_NULL(det_ctx);
937 
938  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
939  FAIL_IF_NULL(f);
940  f->protoctx = &ssn;
941  f->proto = IPPROTO_TCP;
942  f->alproto = ALPROTO_HTTP1;
943 
944  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
945  FAIL_IF_NULL(p);
946  p->flow = f;
950 
951  StreamTcpInitConfig(true);
952 
953  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
954  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
955  FAIL_IF(r != 0);
956  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
957  FAIL_IF(PacketAlertCheck(p, 1));
958 
959  HtpState *http_state = f->alstate;
960  FAIL_IF_NULL(http_state);
961  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
962  FAIL_IF_NULL(tx);
963  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
964  FAIL_IF_NULL(tx_ud);
965 
966  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
967  FileContainer *fc = files.fc;
968  FAIL_IF_NULL(fc);
969  File *file = fc->head;
970  FAIL_IF_NULL(file);
971  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
972  * an opportunity to be applied to the file itself yet */
973  FAIL_IF_NOT(tx_ud->tx_data.file_flags & FLOWFILE_NO_STORE_TS);
974  FAIL_IF(file->flags & FILE_NOSTORE);
975 
976  UTHFreePacket(p);
977  UTHFreeFlow(f);
979  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
981  StreamTcpFreeConfig(true);
982  StatsThreadCleanup(&th_v.stats);
983  PASS;
984 }
985 
986 static int DeStateSigTest07(void)
987 {
988  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
989  "Host: www.server.lan\r\n"
990  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
991  "Content-Length: 215\r\n"
992  "\r\n"
993  "-----------------------------277531038314945\r\n"
994  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
995  "Content-Type: image/jpeg\r\n"
996  "\r\n";
997 
998  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
999  uint8_t httpbuf2[] = "filecontent\r\n"
1000  "-----------------------------277531038314945--";
1001  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1002  ThreadVars th_v;
1003  TcpSession ssn;
1004 
1007 
1008  memset(&th_v, 0, sizeof(th_v));
1009  StatsThreadInit(&th_v.stats);
1010  memset(&ssn, 0, sizeof(ssn));
1011 
1012  DetectEngineThreadCtx *det_ctx = NULL;
1015  de_ctx->flags |= DE_QUIET;
1016 
1017  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;)");
1018  FAIL_IF_NULL(s);
1019 
1021  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1022 
1023  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1024  FAIL_IF_NULL(f);
1025  f->protoctx = &ssn;
1026  f->proto = IPPROTO_TCP;
1027  f->alproto = ALPROTO_HTTP1;
1028 
1029  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1030  FAIL_IF_NULL(p);
1031  p->flow = f;
1035 
1036  StreamTcpInitConfig(true);
1037 
1038  int r = AppLayerParserParse(
1039  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1040  FAIL_IF(r != 0);
1041  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1042  FAIL_IF(PacketAlertCheck(p, 1));
1043 
1044  r = AppLayerParserParse(
1045  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf2, httplen2);
1046  FAIL_IF(r != 0);
1047  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1048  FAIL_IF(PacketAlertCheck(p, 1));
1049 
1050  HtpState *http_state = f->alstate;
1051  FAIL_IF_NULL(http_state);
1052  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1053  FAIL_IF_NULL(tx);
1054  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1055  FAIL_IF_NULL(tx_ud);
1056 
1057  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1058  FileContainer *fc = files.fc;
1059  FAIL_IF_NULL(fc);
1060  File *file = fc->head;
1061  FAIL_IF_NULL(file);
1062  FAIL_IF(file->flags & FILE_STORE);
1063 
1064  UTHFreePacket(p);
1065  UTHFreeFlow(f);
1067  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1069  StreamTcpFreeConfig(true);
1070  StatsThreadCleanup(&th_v.stats);
1071  PASS;
1072 }
1073 
1074 /**
1075  * \test multiple files in a tx
1076  */
1077 static int DeStateSigTest08(void)
1078 {
1079  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1080  "Host: www.server.lan\r\n"
1081  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1082  "Content-Length: 440\r\n"
1083  "\r\n"
1084  "-----------------------------277531038314945\r\n"
1085  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"AAAApicture1.jpg\"\r\n"
1086  "Content-Type: image/jpeg\r\n"
1087  "\r\n";
1088 
1089  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1090  uint8_t httpbuf2[] = "file";
1091  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1092  uint8_t httpbuf3[] = "content\r\n"
1093  "-----------------------------277531038314945\r\n";
1094  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1095 
1096  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"BBBBpicture2.jpg\"\r\n"
1097  "Content-Type: image/jpeg\r\n"
1098  "\r\n"
1099  "filecontent2\r\n"
1100  "-----------------------------277531038314945--";
1101  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1102 
1103  ThreadVars th_v;
1104  TcpSession ssn;
1105 
1108 
1109  memset(&th_v, 0, sizeof(th_v));
1110  StatsThreadInit(&th_v.stats);
1111  memset(&ssn, 0, sizeof(ssn));
1112 
1113  DetectEngineThreadCtx *det_ctx = NULL;
1116  de_ctx->flags |= DE_QUIET;
1117 
1118  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;)");
1119  FAIL_IF_NULL(s);
1120 
1122  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1123 
1124  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1125  FAIL_IF_NULL(f);
1126  f->protoctx = &ssn;
1127  f->proto = IPPROTO_TCP;
1128  f->alproto = ALPROTO_HTTP1;
1129 
1130  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1131  FAIL_IF_NULL(p);
1132  p->flow = f;
1136 
1137  StreamTcpInitConfig(true);
1138 
1139  /* HTTP request with 1st part of the multipart body */
1140 
1141  int r = AppLayerParserParse(
1142  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1143  FAIL_IF(r != 0);
1144  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1145  FAIL_IF(PacketAlertCheck(p, 1));
1146 
1147  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1148  FAIL_IF(r != 0);
1149  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1150  FAIL_IF(PacketAlertCheck(p, 1));
1151 
1152  HtpState *http_state = f->alstate;
1153  FAIL_IF_NULL(http_state);
1154  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1155  FAIL_IF_NULL(tx);
1156  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1157  FAIL_IF_NULL(tx_ud);
1158 
1159  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1160  FileContainer *fc = files.fc;
1161  FAIL_IF_NULL(fc);
1162  File *file = fc->head;
1163  FAIL_IF_NULL(file);
1164  FAIL_IF(file->flags & FILE_STORE);
1165 
1166  /* 2nd multipart body file */
1167 
1168  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1169  FAIL_IF(r != 0);
1170  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1171  FAIL_IF(PacketAlertCheck(p, 1));
1172 
1173  r = AppLayerParserParse(
1174  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1175  FAIL_IF(r != 0);
1176  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1178 
1179  http_state = f->alstate;
1180  FAIL_IF_NULL(http_state);
1181  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1182  FAIL_IF_NULL(tx);
1183  tx_ud = htp_tx_get_user_data(tx);
1184  FAIL_IF_NULL(tx_ud);
1185 
1186  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1187  fc = files.fc;
1188  FAIL_IF_NULL(fc);
1189  file = fc->head;
1190  FAIL_IF_NULL(file);
1191  file = file->next;
1192  FAIL_IF_NULL(file);
1193  FAIL_IF_NOT(file->flags & FILE_STORE);
1194 
1195  UTHFreePacket(p);
1196  UTHFreeFlow(f);
1198  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1200  StreamTcpFreeConfig(true);
1201  StatsThreadCleanup(&th_v.stats);
1202  PASS;
1203 }
1204 
1205 /**
1206  * \test multiple files in a tx. Both files should match
1207  */
1208 static int DeStateSigTest09(void)
1209 {
1210  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1211  "Host: www.server.lan\r\n"
1212  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1213  "Content-Length: 440\r\n"
1214  "\r\n"
1215  "-----------------------------277531038314945\r\n"
1216  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1217  "Content-Type: image/jpeg\r\n"
1218  "\r\n";
1219 
1220  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1221  uint8_t httpbuf2[] = "file";
1222  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1223  uint8_t httpbuf3[] = "content\r\n"
1224  "-----------------------------277531038314945\r\n";
1225  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1226 
1227  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1228  "Content-Type: image/jpeg\r\n"
1229  "\r\n"
1230  "filecontent2\r\n"
1231  "-----------------------------277531038314945--";
1232  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1233 
1234  ThreadVars th_v;
1235  TcpSession ssn;
1236 
1239 
1240  memset(&th_v, 0, sizeof(th_v));
1241  StatsThreadInit(&th_v.stats);
1242  memset(&ssn, 0, sizeof(ssn));
1243 
1244  DetectEngineThreadCtx *det_ctx = NULL;
1247  de_ctx->flags |= DE_QUIET;
1248 
1249  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;)");
1250  FAIL_IF_NULL(s);
1251 
1253  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1254 
1255  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1256  FAIL_IF_NULL(f);
1257  f->protoctx = &ssn;
1258  f->proto = IPPROTO_TCP;
1259  f->alproto = ALPROTO_HTTP1;
1260 
1261  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1262  FAIL_IF_NULL(p);
1263  p->flow = f;
1267 
1268  StreamTcpInitConfig(true);
1269 
1270  /* HTTP request with 1st part of the multipart body */
1271 
1272  int r = AppLayerParserParse(
1273  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1274  FAIL_IF(r != 0);
1275  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1277 
1278  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1279  FAIL_IF(r != 0);
1280  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1281  FAIL_IF(PacketAlertCheck(p, 1));
1282 
1283  HtpState *http_state = f->alstate;
1284  FAIL_IF_NULL(http_state);
1285  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1286  FAIL_IF_NULL(tx);
1287  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1288  FAIL_IF_NULL(tx_ud);
1289 
1290  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1291  FileContainer *fc = files.fc;
1292  FAIL_IF_NULL(fc);
1293  File *file = fc->head;
1294  FAIL_IF_NULL(file);
1295  FAIL_IF_NOT(file->flags & FILE_STORE);
1296 
1297  /* 2nd multipart body file */
1298 
1299  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1300  FAIL_IF(r != 0);
1301  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1302  FAIL_IF(PacketAlertCheck(p, 1));
1303 
1304  r = AppLayerParserParse(
1305  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1306  FAIL_IF(r != 0);
1307  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1309 
1310  http_state = f->alstate;
1311  FAIL_IF_NULL(http_state);
1312  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1313  FAIL_IF_NULL(tx);
1314  tx_ud = htp_tx_get_user_data(tx);
1315  FAIL_IF_NULL(tx_ud);
1316 
1317  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1318  fc = files.fc;
1319  FAIL_IF_NULL(fc);
1320  file = fc->head;
1321  FAIL_IF_NULL(file);
1322  FAIL_IF_NOT(file->flags & FILE_STORE);
1323 
1324  UTHFreePacket(p);
1325  UTHFreeFlow(f);
1327  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1329  StreamTcpFreeConfig(true);
1330  StatsThreadCleanup(&th_v.stats);
1331  PASS;
1332 }
1333 
1334 /**
1335  * \test multiple files in a tx. Both files should match. No other matches.
1336  */
1337 static int DeStateSigTest10(void)
1338 {
1339  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1340  "Host: www.server.lan\r\n"
1341  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1342  "Content-Length: 440\r\n"
1343  "\r\n"
1344  "-----------------------------277531038314945\r\n"
1345  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1346  "Content-Type: image/jpeg\r\n"
1347  "\r\n";
1348 
1349  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1350  uint8_t httpbuf2[] = "file";
1351  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1352  uint8_t httpbuf3[] = "content\r\n"
1353  "-----------------------------277531038314945\r\n";
1354  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1355 
1356  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1357  "Content-Type: image/jpeg\r\n"
1358  "\r\n"
1359  "filecontent2\r\n"
1360  "-----------------------------277531038314945--";
1361  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1362 
1363  ThreadVars th_v;
1364  TcpSession ssn;
1365 
1368 
1369  memset(&th_v, 0, sizeof(th_v));
1370  StatsThreadInit(&th_v.stats);
1371  memset(&ssn, 0, sizeof(ssn));
1372 
1373  DetectEngineThreadCtx *det_ctx = NULL;
1376  de_ctx->flags |= DE_QUIET;
1377 
1378  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1379  FAIL_IF_NULL(s);
1380 
1382  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1383 
1384  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1385  FAIL_IF_NULL(f);
1386  f->protoctx = &ssn;
1387  f->proto = IPPROTO_TCP;
1388  f->alproto = ALPROTO_HTTP1;
1389 
1390  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1391  FAIL_IF_NULL(p);
1392  p->flow = f;
1396 
1397  StreamTcpInitConfig(true);
1398 
1399  /* HTTP request with 1st part of the multipart body */
1400 
1401  int r = AppLayerParserParse(
1402  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1403  FAIL_IF(r != 0);
1404  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1406 
1407  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1408  FAIL_IF(r != 0);
1409  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1410  FAIL_IF(PacketAlertCheck(p, 1));
1411 
1412  HtpState *http_state = f->alstate;
1413  FAIL_IF_NULL(http_state);
1414  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1415  FAIL_IF_NULL(tx);
1416  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1417  FAIL_IF_NULL(tx_ud);
1418 
1419  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1420  FileContainer *fc = files.fc;
1421  FAIL_IF_NULL(fc);
1422  File *file = fc->head;
1423  FAIL_IF_NULL(file);
1424  FAIL_IF_NOT(file->flags & FILE_STORE);
1425 
1426  /* 2nd multipart body file */
1427 
1428  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1429  FAIL_IF(r != 0);
1430  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1431  FAIL_IF(PacketAlertCheck(p, 1));
1432 
1433  r = AppLayerParserParse(
1434  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1435  FAIL_IF(r != 0);
1436  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1438 
1439  http_state = f->alstate;
1440  FAIL_IF_NULL(http_state);
1441  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1442  FAIL_IF_NULL(tx);
1443  tx_ud = htp_tx_get_user_data(tx);
1444  FAIL_IF_NULL(tx_ud);
1445 
1446  files = AppLayerParserGetTxFiles(p->flow, tx, STREAM_TOSERVER);
1447  fc = files.fc;
1448  FAIL_IF_NULL(fc);
1449  file = fc->head;
1450  FAIL_IF_NULL(file);
1451  FAIL_IF_NOT(file->flags & FILE_STORE);
1452 
1453  UTHFreePacket(p);
1454  UTHFreeFlow(f);
1456  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1458  StreamTcpFreeConfig(true);
1459  StatsThreadCleanup(&th_v.stats);
1460  PASS;
1461 }
1462 
1463 #endif
1464 
1466 {
1467 #ifdef UNITTESTS
1468  UtRegisterTest("DeStateTest01", DeStateTest01);
1469  UtRegisterTest("DeStateTest02", DeStateTest02);
1470  UtRegisterTest("DeStateTest03", DeStateTest03);
1471  UtRegisterTest("DeStateSigTest01", DeStateSigTest01);
1472  UtRegisterTest("DeStateSigTest02", DeStateSigTest02);
1473  UtRegisterTest("DeStateSigTest03", DeStateSigTest03);
1474  UtRegisterTest("DeStateSigTest04", DeStateSigTest04);
1475  UtRegisterTest("DeStateSigTest05", DeStateSigTest05);
1476  UtRegisterTest("DeStateSigTest06", DeStateSigTest06);
1477  UtRegisterTest("DeStateSigTest07", DeStateSigTest07);
1478  UtRegisterTest("DeStateSigTest08", DeStateSigTest08);
1479  UtRegisterTest("DeStateSigTest09", DeStateSigTest09);
1480  UtRegisterTest("DeStateSigTest10", DeStateSigTest10);
1481 #endif
1482 }
1483 
1484 /**
1485  * @}
1486  */
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
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1268
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:1628
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:279
DetectEngineStateDirection_::cnt
SigIntId cnt
Definition: detect-engine-state.h:89
Flow_::proto
uint8_t proto
Definition: flow.h:370
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:142
Packet_::flags
uint32_t flags
Definition: decode.h:544
Flow_
Flow data structure.
Definition: flow.h:348
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
FILE_STORE
#define FILE_STORE
Definition: util-file.h:115
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
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:225
SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_TXBOTHDIR
Definition: detect.h:250
MIN
#define MIN(x, y)
Definition: suricata-common.h:408
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
AppLayerTxData
struct AppLayerTxData AppLayerTxData
Definition: app-layer-parser.h:42
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:2418
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3447
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:532
Flow_::protoctx
void * protoctx
Definition: flow.h:433
DeStateStoreItem_::sid
SigIntId sid
Definition: detect-engine-state.h:77
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:100
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:718
util-unittest.h
DetectEngineStateDirection_::cur
DeStateStore * cur
Definition: detect-engine-state.h:87
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:859
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:470
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:496
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
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1245
DeStateStoreItem_::flags
uint32_t flags
Definition: detect-engine-state.h:76
FLOWFILE_NO_STORE_TS
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:134
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:417
AppLayerGetFileState
struct AppLayerGetFileState AppLayerGetFileState
Definition: app-layer-parser.h:41
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:23
SCDetectEngineStateFree
void SCDetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:169
SCEnter
#define SCEnter(...)
Definition: util-debug.h:281
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:185
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3364
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:3105
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:160
SigIntId
#define SigIntId
Definition: detect-engine-state.h:38
SCReturn
#define SCReturn
Definition: util-debug.h:283
Signature_::flags
uint32_t flags
Definition: detect.h:669
Packet_
Definition: decode.h:501
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:1095
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2194
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1258
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:140
DetectEngineStateDirection_::head
DeStateStore * head
Definition: detect-engine-state.h:86
File_
Definition: util-file.h:139
Packet_::flow
struct Flow_ * flow
Definition: decode.h:546
DetectEngineStateResetTxs
void DetectEngineStateResetTxs(Flow *f)
Reset de state for active tx' To be used on detect engine reload.
Definition: detect-engine-state.c:260
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:867
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:1277
suricata-common.h
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:152
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3601
DetectEngineStateDirection_
Definition: detect-engine-state.h:85
AppLayerParserGetTxData
AppLayerTxData * AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1169
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:942
HtpTxUserData_
Definition: app-layer-htp.h:151
DetectEngineStateDirection_::filestore_cnt
uint16_t filestore_cnt
Definition: detect-engine-state.h:90
Signature_::iid
SigIntId iid
Definition: detect.h:680
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:471
DeStateStore_::store
DeStateStoreItem store[DE_STATE_CHUNK_SIZE]
Definition: detect-engine-state.h:81
Flow_::flags
uint32_t flags
Definition: flow.h:413
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:227
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2595
app-layer-protos.h
FILE_NOSTORE
#define FILE_NOSTORE
Definition: util-file.h:114
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:935
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
TcpSession_
Definition: stream-tcp-private.h:283
DeStateStoreItem_
Definition: detect-engine-state.h:75
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:442
DeStateRegisterTests
void DeStateRegisterTests(void)
Definition: detect-engine-state.c:1465
detect-engine-dcepayload.h
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:1634
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1354
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1088
DetectEngineStateDirection_::tail
DeStateStore * tail
Definition: detect-engine-state.h:88
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1264
app-layer.h