1 /* Copyright (C) 2007-2018 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  * \ingroup httplayer
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
29  *
30  * Implements support for http_header keyword.
31  */
32 
33 #include "../suricata-common.h"
34 #include "../flow.h"
35 #include "../flow-var.h"
36 #include "../flow-util.h"
37 
38 #include "../app-layer.h"
39 #include "../app-layer-parser.h"
40 
41 #include "../app-layer-htp.h"
42 #include "../detect-http-header.h"
43 #include "../detect-http-header-common.h"
44 
45 #include "../detect-isdataat.h"
46 
47 #include "../stream-tcp.h"
48 
49 #include "../util-unittest.h"
50 #include "../util-unittest-helper.h"
51 
52 /**
53  * \test Test parser accepting valid rules and rejecting invalid rules
54  */
DetectHttpHeaderParserTest01(void)55 static int DetectHttpHeaderParserTest01(void)
56 {
57     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; http_header; sid:1;)", true));
58     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; nocase; http_header; sid:1;)", true));
59     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; endswith; http_header; sid:1;)", true));
60     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; startswith; http_header; sid:1;)", true));
61     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; startswith; endswith; http_header; sid:1;)", true));
62 
63     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (content:\"abc\"; rawbytes; http_header; sid:1;)", false));
64     FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (http_header; sid:1;)", false));
65     FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (content:\"abc\"; http_header; sid:1;)", false));
66     PASS;
67 }
68 
69 /**
70  * \test Test parser accepting valid rules and rejecting invalid rules
71  */
DetectHttpHeaderParserTest02(void)72 static int DetectHttpHeaderParserTest02(void)
73 {
74     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; sid:1;)", true));
75     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; nocase; sid:1;)", true));
76     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; endswith; sid:1;)", true));
77     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; startswith; sid:1;)", true));
78     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; startswith; endswith; sid:1;)", true));
79     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; bsize:10; sid:1;)", true));
80 
81     FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (http.header; content:\"abc\"; rawbytes; sid:1;)", false));
82     FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (http.header; sid:1;)", false));
83     FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (http.header; content:\"abc\"; sid:1;)", false));
84     PASS;
85 }
86 
87 /**
88  * \test Test that a signature containting a http_header is correctly parsed
89  *       and the keyword is registered.
90  */
DetectHttpHeaderTest01(void)91 static int DetectHttpHeaderTest01(void)
92 {
93     DetectEngineCtx *de_ctx = NULL;
94     int result = 0;
95     SigMatch *sm = NULL;
96 
97     de_ctx = DetectEngineCtxInit();
98     if (de_ctx == NULL)
99         goto end;
100 
101     de_ctx->flags |= DE_QUIET;
102     de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
103                                "(msg:\"Testing http_header\"; "
104                                "content:\"one\"; http_header; sid:1;)");
105     if (de_ctx->sig_list != NULL) {
106         result = 1;
107     } else {
108         printf("Error parsing signature: ");
109         goto end;
110     }
111 
112     sm = de_ctx->sig_list->sm_lists[g_http_header_buffer_id];
113     if (sm != NULL) {
114         result &= (sm->type == DETECT_CONTENT);
115         result &= (sm->next == NULL);
116     } else {
117         result = 0;
118         printf("Error updating content pattern to http_header pattern: ");
119     }
120 
121 
122  end:
123     DetectEngineCtxFree(de_ctx);
124 
125     return result;
126 }
127 
128 /**
129  *\test Test that the http_header content matches against a http request
130  *      which holds the content.
131  */
DetectHttpHeaderTest06(void)132 static int DetectHttpHeaderTest06(void)
133 {
134     TcpSession ssn;
135     Packet *p = NULL;
136     ThreadVars th_v;
137     DetectEngineCtx *de_ctx = NULL;
138     DetectEngineThreadCtx *det_ctx = NULL;
139     HtpState *http_state = NULL;
140     Flow f;
141     uint8_t http_buf[] =
142         "GET /index.html HTTP/1.0\r\n"
143         "Host: www.openinfosecfoundation.org\r\n"
144         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
145         "Content-Type: text/html\r\n"
146         "Content-Length: 26\r\n"
147         "\r\n"
148         "This is dummy message body\r\n";
149     uint32_t http_len = sizeof(http_buf) - 1;
150     int result = 0;
151     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
152 
153     memset(&th_v, 0, sizeof(th_v));
154     memset(&f, 0, sizeof(f));
155     memset(&ssn, 0, sizeof(ssn));
156 
157     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
158 
159     FLOW_INITIALIZE(&f);
160     f.protoctx = (void *)&ssn;
161     f.proto = IPPROTO_TCP;
162     f.flags |= FLOW_IPV4;
163     p->flow = &f;
164     p->flowflags |= FLOW_PKT_TOSERVER;
165     p->flowflags |= FLOW_PKT_ESTABLISHED;
166     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
167     f.alproto = ALPROTO_HTTP;
168 
169     StreamTcpInitConfig(TRUE);
170 
171     de_ctx = DetectEngineCtxInit();
172     if (de_ctx == NULL)
173         goto end;
174 
175     de_ctx->flags |= DE_QUIET;
176 
177     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
178                                "(msg:\"http header test\"; "
179                                "content:\"Content-Type: text/html\"; http_header; "
180                                "sid:1;)");
181     if (de_ctx->sig_list == NULL)
182         goto end;
183 
184     SigGroupBuild(de_ctx);
185     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
186 
187     FLOWLOCK_WRLOCK(&f);
188     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
189                                 STREAM_TOSERVER, http_buf, http_len);
190     if (r != 0) {
191         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
192         result = 0;
193         FLOWLOCK_UNLOCK(&f);
194         goto end;
195     }
196     FLOWLOCK_UNLOCK(&f);
197 
198     http_state = f.alstate;
199     if (http_state == NULL) {
200         printf("no http state: ");
201         result = 0;
202         goto end;
203     }
204 
205     /* do detect */
206     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
207 
208     if (!(PacketAlertCheck(p, 1))) {
209         printf("sid 1 didn't match but should have: ");
210         goto end;
211     }
212 
213     result = 1;
214 end:
215     if (alp_tctx != NULL)
216         AppLayerParserThreadCtxFree(alp_tctx);
217     if (de_ctx != NULL)
218         DetectEngineCtxFree(de_ctx);
219 
220     StreamTcpFreeConfig(TRUE);
221     FLOW_DESTROY(&f);
222     UTHFreePackets(&p, 1);
223     return result;
224 }
225 
226 /**
227  *\test Test that the http_header content matches against a http request
228  *      which holds the content.
229  */
DetectHttpHeaderTest07(void)230 static int DetectHttpHeaderTest07(void)
231 {
232     TcpSession ssn;
233     Packet *p1 = NULL;
234     Packet *p2 = NULL;
235     ThreadVars th_v;
236     DetectEngineThreadCtx *det_ctx = NULL;
237     Flow f;
238     uint8_t http1_buf[] =
239         "GET /index.html HTTP/1.0\r\n"
240         "Host: www.openinfosecfoundation.org\r\n"
241         "User-Agent: Mozi";
242     uint8_t http2_buf[] =
243         "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n"
244         "Content-Length: 67\r\n"
245         "\r\n"
246         "This is dummy message body1";
247     uint32_t http1_len = sizeof(http1_buf) - 1;
248     uint32_t http2_len = sizeof(http2_buf) - 1;
249 
250     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
251     FAIL_IF_NULL(alp_tctx);
252 
253     memset(&th_v, 0, sizeof(th_v));
254     memset(&f, 0, sizeof(f));
255     memset(&ssn, 0, sizeof(ssn));
256 
257     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
258     FAIL_IF_NULL(p1);
259     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
260     FAIL_IF_NULL(p2);
261 
262     FLOW_INITIALIZE(&f);
263     f.protoctx = (void *)&ssn;
264     f.proto = IPPROTO_TCP;
265     f.flags |= FLOW_IPV4;
266     p1->flow = &f;
267     p1->flowflags |= FLOW_PKT_TOSERVER;
268     p1->flowflags |= FLOW_PKT_ESTABLISHED;
269     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
270     p2->flow = &f;
271     p2->flowflags |= FLOW_PKT_TOSERVER;
272     p2->flowflags |= FLOW_PKT_ESTABLISHED;
273     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
274     f.alproto = ALPROTO_HTTP;
275 
276     StreamTcpInitConfig(TRUE);
277 
278     DetectEngineCtx *de_ctx = DetectEngineCtxInit();
279     FAIL_IF_NULL(de_ctx);
280     de_ctx->flags |= DE_QUIET;
281 
282     Signature *s = DetectEngineAppendSig(de_ctx,"alert http any any -> any any "
283                                "(msg:\"http header test\"; "
284                                "content:\"Mozilla\"; http_header; "
285                                "sid:1;)");
286     FAIL_IF_NULL(s);
287 
288     SigGroupBuild(de_ctx);
289     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
290     FAIL_IF_NULL(det_ctx);
291 
292     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
293                                 STREAM_TOSERVER, http1_buf, http1_len);
294     FAIL_IF(r != 0);
295 
296     HtpState *http_state = f.alstate;
297     FAIL_IF_NULL(http_state);
298 
299     /* do detect */
300     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
301     FAIL_IF( (PacketAlertCheck(p1, 1)));
302 
303     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
304                             STREAM_TOSERVER, http2_buf, http2_len);
305     FAIL_IF(r != 0);
306 
307     /* do detect */
308     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
309 
310     FAIL_IF(!(PacketAlertCheck(p2, 1)));
311 
312     AppLayerParserThreadCtxFree(alp_tctx);
313     DetectEngineCtxFree(de_ctx);
314 
315     StreamTcpFreeConfig(TRUE);
316     FLOW_DESTROY(&f);
317     UTHFreePackets(&p1, 1);
318     UTHFreePackets(&p2, 1);
319     PASS;
320 }
321 
322 /**
323  *\test Test that the http_header content matches against a http request
324  *      which holds the content.
325  */
DetectHttpHeaderTest08(void)326 static int DetectHttpHeaderTest08(void)
327 {
328     TcpSession ssn;
329     Packet *p1 = NULL;
330     Packet *p2 = NULL;
331     ThreadVars th_v;
332     DetectEngineCtx *de_ctx = NULL;
333     DetectEngineThreadCtx *det_ctx = NULL;
334     HtpState *http_state = NULL;
335     Flow f;
336     uint8_t http1_buf[] =
337         "GET /index.html HTTP/1.0\r\n"
338         "Host: www.openinfosecfoundation.org\r\n";
339     uint8_t http2_buf[] =
340         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
341         "Content-Type: text/html\r\n"
342         "Content-Length: 67\r\n"
343         "\r\n";
344     uint32_t http1_len = sizeof(http1_buf) - 1;
345     uint32_t http2_len = sizeof(http2_buf) - 1;
346     int result = 0;
347     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
348 
349     memset(&th_v, 0, sizeof(th_v));
350     memset(&f, 0, sizeof(f));
351     memset(&ssn, 0, sizeof(ssn));
352 
353     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
354     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
355 
356     FLOW_INITIALIZE(&f);
357     f.protoctx = (void *)&ssn;
358     f.proto = IPPROTO_TCP;
359     f.flags |= FLOW_IPV4;
360     p1->flow = &f;
361     p1->flowflags |= FLOW_PKT_TOSERVER;
362     p1->flowflags |= FLOW_PKT_ESTABLISHED;
363     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
364     p2->flow = &f;
365     p2->flowflags |= FLOW_PKT_TOSERVER;
366     p2->flowflags |= FLOW_PKT_ESTABLISHED;
367     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
368     f.alproto = ALPROTO_HTTP;
369 
370     StreamTcpInitConfig(TRUE);
371 
372     de_ctx = DetectEngineCtxInit();
373     if (de_ctx == NULL)
374         goto end;
375 
376     de_ctx->flags |= DE_QUIET;
377 
378     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
379                                "(msg:\"http header test\"; "
380                                "content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; "
381                                "sid:1;)");
382     if (de_ctx->sig_list == NULL)
383         goto end;
384 
385     SigGroupBuild(de_ctx);
386     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
387 
388     FLOWLOCK_WRLOCK(&f);
389     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
390                                 STREAM_TOSERVER, http1_buf, http1_len);
391     if (r != 0) {
392         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
393         result = 0;
394         FLOWLOCK_UNLOCK(&f);
395         goto end;
396     }
397     FLOWLOCK_UNLOCK(&f);
398 
399     http_state = f.alstate;
400     if (http_state == NULL) {
401         printf("no http state: ");
402         result = 0;
403         goto end;
404     }
405 
406     /* do detect */
407     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
408 
409     if ((PacketAlertCheck(p1, 1))) {
410         printf("sid 1 didn't match but should have: ");
411         goto end;
412     }
413 
414     FLOWLOCK_WRLOCK(&f);
415     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
416                             STREAM_TOSERVER, http2_buf, http2_len);
417     if (r != 0) {
418         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
419         result = 0;
420         FLOWLOCK_UNLOCK(&f);
421         goto end;
422     }
423     FLOWLOCK_UNLOCK(&f);
424 
425     /* do detect */
426     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
427 
428     if (!(PacketAlertCheck(p2, 1))) {
429         printf("sid 1 didn't match but should have: ");
430         goto end;
431     }
432 
433     result = 1;
434 end:
435     if (alp_tctx != NULL)
436         AppLayerParserThreadCtxFree(alp_tctx);
437     if (de_ctx != NULL)
438         DetectEngineCtxFree(de_ctx);
439 
440     StreamTcpFreeConfig(TRUE);
441     FLOW_DESTROY(&f);
442     UTHFreePackets(&p1, 1);
443     UTHFreePackets(&p2, 1);
444     return result;
445 }
446 
447 /**
448  *\test Test that the http_header content matches against a http request
449  *      which holds the content, against a cross boundary present pattern.
450  */
DetectHttpHeaderTest09(void)451 static int DetectHttpHeaderTest09(void)
452 {
453     TcpSession ssn;
454     Packet *p1 = NULL;
455     Packet *p2 = NULL;
456     ThreadVars th_v;
457     DetectEngineCtx *de_ctx = NULL;
458     DetectEngineThreadCtx *det_ctx = NULL;
459     HtpState *http_state = NULL;
460     Flow f;
461     uint8_t http1_buf[] =
462         "GET /index.html HTTP/1.0\r\n"
463         "Host: www.openinfosecfoundation.org\r\n"
464         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
465     uint8_t http2_buf[] =
466         "Content-Type: text/html\r\n"
467         "Content-Length: 67\r\n"
468         "\r\n"
469         "This is dummy body\r\n";
470     uint32_t http1_len = sizeof(http1_buf) - 1;
471     uint32_t http2_len = sizeof(http2_buf) - 1;
472     int result = 0;
473     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
474 
475     memset(&th_v, 0, sizeof(th_v));
476     memset(&f, 0, sizeof(f));
477     memset(&ssn, 0, sizeof(ssn));
478 
479     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
480     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
481 
482     FLOW_INITIALIZE(&f);
483     f.protoctx = (void *)&ssn;
484     f.proto = IPPROTO_TCP;
485     f.flags |= FLOW_IPV4;
486     p1->flow = &f;
487     p1->flowflags |= FLOW_PKT_TOSERVER;
488     p1->flowflags |= FLOW_PKT_ESTABLISHED;
489     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
490     p2->flow = &f;
491     p2->flowflags |= FLOW_PKT_TOSERVER;
492     p2->flowflags |= FLOW_PKT_ESTABLISHED;
493     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
494     f.alproto = ALPROTO_HTTP;
495 
496     StreamTcpInitConfig(TRUE);
497 
498     de_ctx = DetectEngineCtxInit();
499     if (de_ctx == NULL)
500         goto end;
501 
502     de_ctx->flags |= DE_QUIET;
503     de_ctx->mpm_matcher = mpm_default_matcher;
504 
505     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
506                                "(msg:\"http header test\"; "
507                                "content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; "
508                                "sid:1;)");
509     if (de_ctx->sig_list == NULL)
510         goto end;
511 
512     SigGroupBuild(de_ctx);
513     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
514 
515     FLOWLOCK_WRLOCK(&f);
516     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
517                                 STREAM_TOSERVER, http1_buf, http1_len);
518     if (r != 0) {
519         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
520         result = 0;
521         FLOWLOCK_UNLOCK(&f);
522         goto end;
523     }
524     FLOWLOCK_UNLOCK(&f);
525 
526     http_state = f.alstate;
527     if (http_state == NULL) {
528         printf("no http state: ");
529         result = 0;
530         goto end;
531     }
532 
533     /* do detect */
534     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
535 
536     if ((PacketAlertCheck(p1, 1))) {
537         printf("sid 1 matched but shouldn't have: ");
538         goto end;
539     }
540 
541     FLOWLOCK_WRLOCK(&f);
542     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
543                             STREAM_TOSERVER, http2_buf, http2_len);
544     if (r != 0) {
545         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
546         result = 0;
547         FLOWLOCK_UNLOCK(&f);
548         goto end;
549     }
550     FLOWLOCK_UNLOCK(&f);
551 
552     /* do detect */
553     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
554 
555     if (!(PacketAlertCheck(p2, 1))) {
556         printf("sid 1 didn't match but should have: ");
557         goto end;
558     }
559 
560     result = 1;
561 end:
562     if (alp_tctx != NULL)
563         AppLayerParserThreadCtxFree(alp_tctx);
564     if (de_ctx != NULL)
565         DetectEngineCtxFree(de_ctx);
566 
567     StreamTcpFreeConfig(TRUE);
568     FLOW_DESTROY(&f);
569     UTHFreePackets(&p1, 1);
570     UTHFreePackets(&p2, 1);
571     return result;
572 }
573 
574 /**
575  *\test Test that the http_header content matches against a http request
576  *      against a case insensitive pattern.
577  */
DetectHttpHeaderTest10(void)578 static int DetectHttpHeaderTest10(void)
579 {
580     TcpSession ssn;
581     Packet *p1 = NULL;
582     Packet *p2 = NULL;
583     ThreadVars th_v;
584     DetectEngineCtx *de_ctx = NULL;
585     DetectEngineThreadCtx *det_ctx = NULL;
586     HtpState *http_state = NULL;
587     Flow f;
588     uint8_t http1_buf[] =
589         "GET /index.html HTTP/1.0\r\n"
590         "Host: www.openinfosecfoundation.org\r\n"
591         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
592     uint8_t http2_buf[] =
593         "Content-Type: text/html\r\n"
594         "Content-Length: 67\r\n"
595         "\r\n"
596         "This is dummy body";
597     uint32_t http1_len = sizeof(http1_buf) - 1;
598     uint32_t http2_len = sizeof(http2_buf) - 1;
599     int result = 0;
600     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
601 
602     memset(&th_v, 0, sizeof(th_v));
603     memset(&f, 0, sizeof(f));
604     memset(&ssn, 0, sizeof(ssn));
605 
606     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
607     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
608 
609     FLOW_INITIALIZE(&f);
610     f.protoctx = (void *)&ssn;
611     f.proto = IPPROTO_TCP;
612     f.flags |= FLOW_IPV4;
613     p1->flow = &f;
614     p1->flowflags |= FLOW_PKT_TOSERVER;
615     p1->flowflags |= FLOW_PKT_ESTABLISHED;
616     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
617     p2->flow = &f;
618     p2->flowflags |= FLOW_PKT_TOSERVER;
619     p2->flowflags |= FLOW_PKT_ESTABLISHED;
620     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
621     f.alproto = ALPROTO_HTTP;
622 
623     StreamTcpInitConfig(TRUE);
624 
625     de_ctx = DetectEngineCtxInit();
626     if (de_ctx == NULL)
627         goto end;
628 
629     de_ctx->flags |= DE_QUIET;
630 
631     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
632                                "(msg:\"http header test\"; "
633                                "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;"
634                                "sid:1;)");
635     if (de_ctx->sig_list == NULL)
636         goto end;
637 
638     SigGroupBuild(de_ctx);
639     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
640 
641     FLOWLOCK_WRLOCK(&f);
642     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
643                                 STREAM_TOSERVER, http1_buf, http1_len);
644     if (r != 0) {
645         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
646         result = 0;
647         FLOWLOCK_UNLOCK(&f);
648         goto end;
649     }
650     FLOWLOCK_UNLOCK(&f);
651 
652     http_state = f.alstate;
653     if (http_state == NULL) {
654         printf("no http state: ");
655         result = 0;
656         goto end;
657     }
658 
659     /* do detect */
660     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
661 
662     if ((PacketAlertCheck(p1, 1))) {
663         printf("sid 1 didn't match but should have: ");
664         goto end;
665     }
666 
667     FLOWLOCK_WRLOCK(&f);
668     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
669                             STREAM_TOSERVER, http2_buf, http2_len);
670     if (r != 0) {
671         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
672         result = 0;
673         FLOWLOCK_UNLOCK(&f);
674         goto end;
675     }
676     FLOWLOCK_UNLOCK(&f);
677 
678     /* do detect */
679     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
680 
681     if (!(PacketAlertCheck(p2, 1))) {
682         printf("sid 1 didn't match but should have: ");
683         goto end;
684     }
685 
686     result = 1;
687 end:
688     if (alp_tctx != NULL)
689         AppLayerParserThreadCtxFree(alp_tctx);
690     if (de_ctx != NULL)
691         DetectEngineCtxFree(de_ctx);
692 
693     StreamTcpFreeConfig(TRUE);
694     FLOW_DESTROY(&f);
695     UTHFreePackets(&p1, 1);
696     UTHFreePackets(&p2, 1);
697     return result;
698 }
699 
700 /**
701  *\test Test that the negated http_header content matches against a
702  *      http request which doesn't hold the content.
703  */
DetectHttpHeaderTest11(void)704 static int DetectHttpHeaderTest11(void)
705 {
706     TcpSession ssn;
707     Packet *p = NULL;
708     ThreadVars th_v;
709     DetectEngineCtx *de_ctx = NULL;
710     DetectEngineThreadCtx *det_ctx = NULL;
711     HtpState *http_state = NULL;
712     Flow f;
713     uint8_t http_buf[] =
714         "GET /index.html HTTP/1.0\r\n"
715         "Host: www.openinfosecfoundation.org\r\n"
716         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
717         "Content-Type: text/html\r\n"
718         "Content-Length: 26\r\n"
719         "\r\n"
720         "This is dummy message body\r\n";
721     uint32_t http_len = sizeof(http_buf) - 1;
722     int result = 0;
723     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
724 
725     memset(&th_v, 0, sizeof(th_v));
726     memset(&f, 0, sizeof(f));
727     memset(&ssn, 0, sizeof(ssn));
728 
729     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
730 
731     FLOW_INITIALIZE(&f);
732     f.protoctx = (void *)&ssn;
733     f.proto = IPPROTO_TCP;
734     f.flags |= FLOW_IPV4;
735     p->flow = &f;
736     p->flowflags |= FLOW_PKT_TOSERVER;
737     p->flowflags |= FLOW_PKT_ESTABLISHED;
738     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
739     f.alproto = ALPROTO_HTTP;
740 
741     StreamTcpInitConfig(TRUE);
742 
743     de_ctx = DetectEngineCtxInit();
744     if (de_ctx == NULL)
745         goto end;
746 
747     de_ctx->flags |= DE_QUIET;
748 
749     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
750                                "(msg:\"http header test\"; "
751                                "content:!\"lalalalala\"; http_header; "
752                                "sid:1;)");
753     if (de_ctx->sig_list == NULL)
754         goto end;
755 
756     SigGroupBuild(de_ctx);
757     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
758 
759     FLOWLOCK_WRLOCK(&f);
760     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
761                                 STREAM_TOSERVER, http_buf, http_len);
762     if (r != 0) {
763         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
764         result = 0;
765         FLOWLOCK_UNLOCK(&f);
766         goto end;
767     }
768     FLOWLOCK_UNLOCK(&f);
769 
770     http_state = f.alstate;
771     if (http_state == NULL) {
772         printf("no http state: ");
773         result = 0;
774         goto end;
775     }
776 
777     /* do detect */
778     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
779 
780     if (!(PacketAlertCheck(p, 1))) {
781         printf("sid 1 didn't match but should have: ");
782         goto end;
783     }
784 
785     result = 1;
786 end:
787     if (alp_tctx != NULL)
788         AppLayerParserThreadCtxFree(alp_tctx);
789     if (de_ctx != NULL)
790         DetectEngineCtxFree(de_ctx);
791 
792     StreamTcpFreeConfig(TRUE);
793     FLOW_DESTROY(&f);
794     UTHFreePackets(&p, 1);
795     return result;
796 }
797 
798 /**
799  *\test Negative test that the negated http_header content matches against a
800  *      http request which holds hold the content.
801  */
DetectHttpHeaderTest12(void)802 static int DetectHttpHeaderTest12(void)
803 {
804     TcpSession ssn;
805     Packet *p = NULL;
806     ThreadVars th_v;
807     DetectEngineCtx *de_ctx = NULL;
808     DetectEngineThreadCtx *det_ctx = NULL;
809     HtpState *http_state = NULL;
810     Flow f;
811     uint8_t http_buf[] =
812         "GET /index.html HTTP/1.0\r\n"
813         "Host: www.openinfosecfoundation.org\r\n"
814         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
815         "Content-Type: text/html\r\n"
816         "Content-Length: 26\r\n"
817         "\r\n"
818         "This is dummy message body\r\n";
819     uint32_t http_len = sizeof(http_buf) - 1;
820     int result = 0;
821     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
822 
823     memset(&th_v, 0, sizeof(th_v));
824     memset(&f, 0, sizeof(f));
825     memset(&ssn, 0, sizeof(ssn));
826 
827     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
828 
829     FLOW_INITIALIZE(&f);
830     f.protoctx = (void *)&ssn;
831     f.proto = IPPROTO_TCP;
832     f.flags |= FLOW_IPV4;
833     p->flow = &f;
834     p->flowflags |= FLOW_PKT_TOSERVER;
835     p->flowflags |= FLOW_PKT_ESTABLISHED;
836     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
837     f.alproto = ALPROTO_HTTP;
838 
839     StreamTcpInitConfig(TRUE);
840 
841     de_ctx = DetectEngineCtxInit();
842     if (de_ctx == NULL)
843         goto end;
844 
845     de_ctx->flags |= DE_QUIET;
846 
847     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
848                                "(msg:\"http header test\"; "
849                                "content:!\"User-Agent: Mozilla/5.0 \"; http_header; "
850                                "sid:1;)");
851     if (de_ctx->sig_list == NULL)
852         goto end;
853 
854     SigGroupBuild(de_ctx);
855     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
856 
857     FLOWLOCK_WRLOCK(&f);
858     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
859                                 STREAM_TOSERVER, http_buf, http_len);
860     if (r != 0) {
861         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
862         result = 0;
863         FLOWLOCK_UNLOCK(&f);
864         goto end;
865     }
866     FLOWLOCK_UNLOCK(&f);
867 
868     http_state = f.alstate;
869     if (http_state == NULL) {
870         printf("no http state: ");
871         result = 0;
872         goto end;
873     }
874 
875     /* do detect */
876     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
877 
878     if ((PacketAlertCheck(p, 1))) {
879         printf("sid 1 didn't match but should have: ");
880         goto end;
881     }
882 
883     result = 1;
884 end:
885     if (alp_tctx != NULL)
886         AppLayerParserThreadCtxFree(alp_tctx);
887     if (de_ctx != NULL)
888         DetectEngineCtxFree(de_ctx);
889 
890     StreamTcpFreeConfig(TRUE);
891     FLOW_DESTROY(&f);
892     UTHFreePackets(&p, 1);
893     return result;
894 }
895 
896 /**
897  *\test Test that the http_header content matches against a http request
898  *      which holds the content.
899  */
DetectHttpHeaderTest13(void)900 static int DetectHttpHeaderTest13(void)
901 {
902     TcpSession ssn;
903     Packet *p = NULL;
904     ThreadVars th_v;
905     DetectEngineCtx *de_ctx = NULL;
906     DetectEngineThreadCtx *det_ctx = NULL;
907     HtpState *http_state = NULL;
908     Flow f;
909     uint8_t http_buf[] =
910         "GET /index.html HTTP/1.0\r\n"
911         "Host: www.openinfosecfoundation.org\r\n"
912         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
913         "Content-Type: text/html\r\n"
914         "Content-Length: 100\r\n"
915         "\r\n"
916         "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n";
917     uint32_t http_len = sizeof(http_buf) - 1;
918     int result = 0;
919     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
920 
921     memset(&th_v, 0, sizeof(th_v));
922     memset(&f, 0, sizeof(f));
923     memset(&ssn, 0, sizeof(ssn));
924 
925     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
926 
927     FLOW_INITIALIZE(&f);
928     f.protoctx = (void *)&ssn;
929     f.proto = IPPROTO_TCP;
930     f.flags |= FLOW_IPV4;
931 
932     p->flow = &f;
933     p->flowflags |= FLOW_PKT_TOSERVER;
934     p->flowflags |= FLOW_PKT_ESTABLISHED;
935     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
936     f.alproto = ALPROTO_HTTP;
937 
938     StreamTcpInitConfig(TRUE);
939 
940     de_ctx = DetectEngineCtxInit();
941     if (de_ctx == NULL)
942         goto end;
943 
944     de_ctx->flags |= DE_QUIET;
945 
946     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
947                                "(msg:\"http header test\"; "
948                                "content:\"Host: www.openinfosecfoundation.org\"; http_header; "
949                                "sid:1;)");
950     if (de_ctx->sig_list == NULL)
951         goto end;
952 
953     SigGroupBuild(de_ctx);
954     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
955 
956     FLOWLOCK_WRLOCK(&f);
957     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
958                                 STREAM_TOSERVER, http_buf, http_len);
959     if (r != 0) {
960         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
961         result = 0;
962         FLOWLOCK_UNLOCK(&f);
963         goto end;
964     }
965     FLOWLOCK_UNLOCK(&f);
966 
967     http_state = f.alstate;
968     if (http_state == NULL) {
969         printf("no http state: ");
970         result = 0;
971         goto end;
972     }
973 
974     /* do detect */
975     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
976 
977     if (!(PacketAlertCheck(p, 1))) {
978         printf("sid 1 didn't match but should have: ");
979         goto end;
980     }
981 
982     result = 1;
983 end:
984     if (alp_tctx != NULL)
985         AppLayerParserThreadCtxFree(alp_tctx);
986     if (de_ctx != NULL)
987         DetectEngineCtxFree(de_ctx);
988 
989     StreamTcpFreeConfig(TRUE);
990     FLOW_DESTROY(&f);
991     UTHFreePackets(&p, 1);
992     return result;
993 }
994 
DetectHttpHeaderTest20(void)995 static int DetectHttpHeaderTest20(void)
996 {
997     DetectEngineCtx *de_ctx = NULL;
998     int result = 0;
999 
1000     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1001         goto end;
1002 
1003     de_ctx->flags |= DE_QUIET;
1004     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1005                                "(content:\"one\"; http_header; "
1006                                "content:\"two\"; distance:0; http_header; sid:1;)");
1007     if (de_ctx->sig_list == NULL) {
1008         printf("de_ctx->sig_list == NULL\n");
1009         goto end;
1010     }
1011 
1012     if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1013         printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1014         goto end;
1015     }
1016 
1017     if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1018         printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1019         goto end;
1020     }
1021 
1022     DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1023     DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1024     if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
1025         memcmp(hhd1->content, "one", hhd1->content_len) != 0 ||
1026         hhd2->flags != DETECT_CONTENT_DISTANCE ||
1027         memcmp(hhd2->content, "two", hhd1->content_len) != 0) {
1028         goto end;
1029     }
1030 
1031     result = 1;
1032 
1033  end:
1034     DetectEngineCtxFree(de_ctx);
1035     return result;
1036 }
1037 
DetectHttpHeaderTest21(void)1038 static int DetectHttpHeaderTest21(void)
1039 {
1040     DetectEngineCtx *de_ctx = NULL;
1041     int result = 0;
1042 
1043     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1044         goto end;
1045 
1046     de_ctx->flags |= DE_QUIET;
1047     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1048                                "(content:\"one\"; http_header; "
1049                                "content:\"two\"; within:5; http_header; sid:1;)");
1050     if (de_ctx->sig_list == NULL) {
1051         printf("de_ctx->sig_list == NULL\n");
1052         goto end;
1053     }
1054 
1055     if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1056         printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1057         goto end;
1058     }
1059 
1060     if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1061         printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1062         goto end;
1063     }
1064 
1065     DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1066     DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1067     if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
1068         memcmp(hhd1->content, "one", hhd1->content_len) != 0 ||
1069         hhd2->flags != DETECT_CONTENT_WITHIN ||
1070         memcmp(hhd2->content, "two", hhd1->content_len) != 0) {
1071         goto end;
1072     }
1073 
1074     result = 1;
1075 
1076  end:
1077     DetectEngineCtxFree(de_ctx);
1078     return result;
1079 }
1080 
DetectHttpHeaderTest22(void)1081 static int DetectHttpHeaderTest22(void)
1082 {
1083     DetectEngineCtx *de_ctx = NULL;
1084     int result = 0;
1085 
1086     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1087         goto end;
1088 
1089     de_ctx->flags |= DE_QUIET;
1090     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1091                                "(content:\"one\"; within:5; http_header; sid:1;)");
1092     if (de_ctx->sig_list == NULL) {
1093         printf("de_ctx->sig_list == NULL\n");
1094         goto end;
1095     }
1096 
1097     result = 1;
1098 
1099  end:
1100     DetectEngineCtxFree(de_ctx);
1101     return result;
1102 }
1103 
DetectHttpHeaderTest23(void)1104 static int DetectHttpHeaderTest23(void)
1105 {
1106     DetectEngineCtx *de_ctx = NULL;
1107     int result = 0;
1108 
1109     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1110         goto end;
1111 
1112     de_ctx->flags |= DE_QUIET;
1113     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1114                                "(content:\"one\"; http_header; within:5; sid:1;)");
1115     if (de_ctx->sig_list == NULL) {
1116         printf("de_ctx->sig_list == NULL\n");
1117         goto end;
1118     }
1119 
1120     result = 1;
1121 
1122  end:
1123     DetectEngineCtxFree(de_ctx);
1124     return result;
1125 }
1126 
DetectHttpHeaderTest24(void)1127 static int DetectHttpHeaderTest24(void)
1128 {
1129     DetectEngineCtx *de_ctx = NULL;
1130     int result = 0;
1131 
1132     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1133         goto end;
1134 
1135     de_ctx->flags |= DE_QUIET;
1136     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1137                                "(content:\"one\"; within:5; sid:1;)");
1138     if (de_ctx->sig_list == NULL) {
1139         printf("de_ctx->sig_list == NULL\n");
1140         goto end;
1141     }
1142 
1143     result = 1;
1144 
1145  end:
1146     DetectEngineCtxFree(de_ctx);
1147     return result;
1148 }
1149 
DetectHttpHeaderTest25(void)1150 static int DetectHttpHeaderTest25(void)
1151 {
1152     DetectEngineCtx *de_ctx = NULL;
1153     int result = 0;
1154 
1155     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1156         goto end;
1157 
1158     de_ctx->flags |= DE_QUIET;
1159     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1160                                "(pcre:/one/H; "
1161                                "content:\"two\"; within:5; http_header; sid:1;)");
1162     if (de_ctx->sig_list == NULL) {
1163         printf("de_ctx->sig_list == NULL\n");
1164         goto end;
1165     }
1166 
1167     if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1168         printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1169         goto end;
1170     }
1171 
1172     if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1173         printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1174         goto end;
1175     }
1176 
1177     if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1178         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT ||
1179         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1180         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) {
1181 
1182         goto end;
1183     }
1184 
1185     DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1186     DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1187     if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
1188         hhd2->flags != DETECT_CONTENT_WITHIN ||
1189         memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
1190         goto end;
1191     }
1192 
1193     result = 1;
1194 
1195  end:
1196     DetectEngineCtxFree(de_ctx);
1197     return result;
1198 }
1199 
DetectHttpHeaderTest26(void)1200 static int DetectHttpHeaderTest26(void)
1201 {
1202     DetectEngineCtx *de_ctx = NULL;
1203     int result = 0;
1204 
1205     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1206         goto end;
1207 
1208     de_ctx->flags |= DE_QUIET;
1209     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1210                                "(content:\"two\"; http_header; "
1211                                "pcre:/one/HR; sid:1;)");
1212     if (de_ctx->sig_list == NULL) {
1213         printf("de_ctx->sig_list == NULL\n");
1214         goto end;
1215     }
1216 
1217     if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1218         printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1219         goto end;
1220     }
1221 
1222     if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1223         printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1224         goto end;
1225     }
1226 
1227     if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1228         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_PCRE ||
1229         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1230         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_CONTENT) {
1231 
1232         goto end;
1233     }
1234 
1235     DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1236     DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1237     if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
1238         hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
1239         memcmp(hhd1->content, "two", hhd1->content_len) != 0) {
1240         goto end;
1241     }
1242 
1243     result = 1;
1244 
1245  end:
1246     DetectEngineCtxFree(de_ctx);
1247     return result;
1248 }
1249 
DetectHttpHeaderTest27(void)1250 static int DetectHttpHeaderTest27(void)
1251 {
1252     DetectEngineCtx *de_ctx = NULL;
1253     int result = 0;
1254 
1255     if ( (de_ctx = DetectEngineCtxInit()) == NULL)
1256         goto end;
1257 
1258     de_ctx->flags |= DE_QUIET;
1259     de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any "
1260                                "(pcre:/one/H; "
1261                                "content:\"two\"; distance:5; http_header; sid:1;)");
1262     if (de_ctx->sig_list == NULL) {
1263         printf("de_ctx->sig_list == NULL\n");
1264         goto end;
1265     }
1266 
1267     if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
1268         printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
1269         goto end;
1270     }
1271 
1272     if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) {
1273         printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n");
1274         goto end;
1275     }
1276 
1277     if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL ||
1278         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT ||
1279         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL ||
1280         de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) {
1281 
1282         goto end;
1283     }
1284 
1285     DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx;
1286     DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx;
1287     if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
1288         hhd2->flags != DETECT_CONTENT_DISTANCE ||
1289         memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
1290         goto end;
1291     }
1292 
1293     result = 1;
1294 
1295  end:
1296     DetectEngineCtxFree(de_ctx);
1297     return result;
1298 }
1299 
1300 /** \test app-layer-event:http.host_header_ambiguous should not be set
1301  *  \bug 640*/
DetectHttpHeaderTest28(void)1302 static int DetectHttpHeaderTest28(void)
1303 {
1304     TcpSession ssn;
1305     Packet *p = NULL;
1306     ThreadVars th_v;
1307     DetectEngineCtx *de_ctx = NULL;
1308     DetectEngineThreadCtx *det_ctx = NULL;
1309     Flow f;
1310     uint8_t http_buf[] =
1311         "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n"
1312         "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1313         "Host: xxx.intranet.local:8000\r\n"
1314         "\r\n";
1315     uint32_t http_len = sizeof(http_buf) - 1;
1316     int result = 0;
1317     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1318 
1319     memset(&th_v, 0, sizeof(th_v));
1320     memset(&f, 0, sizeof(f));
1321     memset(&ssn, 0, sizeof(ssn));
1322 
1323     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1324 
1325     FLOW_INITIALIZE(&f);
1326     f.protoctx = (void *)&ssn;
1327     f.proto = IPPROTO_TCP;
1328     f.flags |= FLOW_IPV4;
1329     p->flow = &f;
1330     p->flowflags |= FLOW_PKT_TOSERVER;
1331     p->flowflags |= FLOW_PKT_ESTABLISHED;
1332     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1333     f.alproto = ALPROTO_HTTP;
1334 
1335     StreamTcpInitConfig(TRUE);
1336 
1337     de_ctx = DetectEngineCtxInit();
1338     if (de_ctx == NULL)
1339         goto end;
1340 
1341     de_ctx->flags |= DE_QUIET;
1342 
1343     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1344                                "(app-layer-event:http.host_header_ambiguous; "
1345                                "sid:1;)");
1346     if (de_ctx->sig_list == NULL)
1347         goto end;
1348 
1349     SigGroupBuild(de_ctx);
1350     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1351 
1352     FLOWLOCK_WRLOCK(&f);
1353     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1354                                 STREAM_TOSERVER, http_buf, http_len);
1355     if (r != 0) {
1356         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1357         result = 0;
1358         FLOWLOCK_UNLOCK(&f);
1359         goto end;
1360     }
1361     FLOWLOCK_UNLOCK(&f);
1362 
1363     /* do detect */
1364     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1365 
1366     if (PacketAlertCheck(p, 1)) {
1367         printf("sid 1 matched but shouldnt have: ");
1368         goto end;
1369     }
1370 
1371     result = 1;
1372  end:
1373     if (alp_tctx != NULL)
1374         AppLayerParserThreadCtxFree(alp_tctx);
1375     if (de_ctx != NULL)
1376         DetectEngineCtxFree(de_ctx);
1377 
1378     StreamTcpFreeConfig(TRUE);
1379     FLOW_DESTROY(&f);
1380     UTHFreePackets(&p, 1);
1381     return result;
1382 }
1383 
1384 /** \test app-layer-event:http.host_header_ambiguous should be set
1385  *  \bug 640*/
DetectHttpHeaderTest29(void)1386 static int DetectHttpHeaderTest29(void)
1387 {
1388     TcpSession ssn;
1389     Packet *p = NULL;
1390     ThreadVars th_v;
1391     DetectEngineCtx *de_ctx = NULL;
1392     DetectEngineThreadCtx *det_ctx = NULL;
1393     Flow f;
1394     uint8_t http_buf[] =
1395         "POST http://xxx.intranet.local:8001/xxx HTTP/1.1\r\n"
1396         "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1397         "Host: xxx.intranet.local:8000\r\n"
1398         "\r\n";
1399     uint32_t http_len = sizeof(http_buf) - 1;
1400     int result = 0;
1401     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1402 
1403     memset(&th_v, 0, sizeof(th_v));
1404     memset(&f, 0, sizeof(f));
1405     memset(&ssn, 0, sizeof(ssn));
1406 
1407     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1408 
1409     FLOW_INITIALIZE(&f);
1410     f.protoctx = (void *)&ssn;
1411     f.proto = IPPROTO_TCP;
1412     f.flags |= FLOW_IPV4;
1413     p->flow = &f;
1414     p->flowflags |= FLOW_PKT_TOSERVER;
1415     p->flowflags |= FLOW_PKT_ESTABLISHED;
1416     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1417     f.alproto = ALPROTO_HTTP;
1418 
1419     StreamTcpInitConfig(TRUE);
1420 
1421     de_ctx = DetectEngineCtxInit();
1422     if (de_ctx == NULL)
1423         goto end;
1424 
1425     de_ctx->flags |= DE_QUIET;
1426 
1427     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1428                                "(app-layer-event:http.host_header_ambiguous; "
1429                                "sid:1;)");
1430     if (de_ctx->sig_list == NULL)
1431         goto end;
1432 
1433     SigGroupBuild(de_ctx);
1434     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1435 
1436     FLOWLOCK_WRLOCK(&f);
1437     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1438                                 STREAM_TOSERVER, http_buf, http_len);
1439     if (r != 0) {
1440         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1441         result = 0;
1442         FLOWLOCK_UNLOCK(&f);
1443         goto end;
1444     }
1445     FLOWLOCK_UNLOCK(&f);
1446 
1447     /* do detect */
1448     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1449 
1450     if (!(PacketAlertCheck(p, 1))) {
1451         printf("sid 1 didn't match but should have: ");
1452         goto end;
1453     }
1454 
1455     result = 1;
1456  end:
1457     if (alp_tctx != NULL)
1458         AppLayerParserThreadCtxFree(alp_tctx);
1459     if (de_ctx != NULL)
1460         DetectEngineCtxFree(de_ctx);
1461 
1462     StreamTcpFreeConfig(TRUE);
1463     FLOW_DESTROY(&f);
1464     UTHFreePackets(&p, 1);
1465     return result;
1466 }
1467 
1468 /** \test app-layer-event:http.host_header_ambiguous should be set
1469  *  \bug 640*/
DetectHttpHeaderTest30(void)1470 static int DetectHttpHeaderTest30(void)
1471 {
1472     TcpSession ssn;
1473     Packet *p = NULL;
1474     ThreadVars th_v;
1475     DetectEngineCtx *de_ctx = NULL;
1476     DetectEngineThreadCtx *det_ctx = NULL;
1477     Flow f;
1478     uint8_t http_buf[] =
1479         "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n"
1480         "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n"
1481         "Host: xyz.intranet.local:8000\r\n"
1482         "\r\n";
1483     uint32_t http_len = sizeof(http_buf) - 1;
1484     int result = 0;
1485     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1486 
1487     memset(&th_v, 0, sizeof(th_v));
1488     memset(&f, 0, sizeof(f));
1489     memset(&ssn, 0, sizeof(ssn));
1490 
1491     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1492 
1493     FLOW_INITIALIZE(&f);
1494     f.protoctx = (void *)&ssn;
1495     f.proto = IPPROTO_TCP;
1496     f.flags |= FLOW_IPV4;
1497     p->flow = &f;
1498     p->flowflags |= FLOW_PKT_TOSERVER;
1499     p->flowflags |= FLOW_PKT_ESTABLISHED;
1500     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1501     f.alproto = ALPROTO_HTTP;
1502 
1503     StreamTcpInitConfig(TRUE);
1504 
1505     de_ctx = DetectEngineCtxInit();
1506     if (de_ctx == NULL)
1507         goto end;
1508 
1509     de_ctx->flags |= DE_QUIET;
1510 
1511     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1512                                "(app-layer-event:http.host_header_ambiguous; "
1513                                "sid:1;)");
1514     if (de_ctx->sig_list == NULL)
1515         goto end;
1516 
1517     SigGroupBuild(de_ctx);
1518     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1519 
1520     FLOWLOCK_WRLOCK(&f);
1521     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1522                                 STREAM_TOSERVER, http_buf, http_len);
1523     if (r != 0) {
1524         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1525         result = 0;
1526         FLOWLOCK_UNLOCK(&f);
1527         goto end;
1528     }
1529     FLOWLOCK_UNLOCK(&f);
1530 
1531     /* do detect */
1532     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1533 
1534     if (!(PacketAlertCheck(p, 1))) {
1535         printf("sid 1 didn't match but should have: ");
1536         goto end;
1537     }
1538 
1539     result = 1;
1540  end:
1541     if (alp_tctx != NULL)
1542         AppLayerParserThreadCtxFree(alp_tctx);
1543     if (de_ctx != NULL)
1544         DetectEngineCtxFree(de_ctx);
1545 
1546     StreamTcpFreeConfig(TRUE);
1547     FLOW_DESTROY(&f);
1548     UTHFreePackets(&p, 1);
1549     return result;
1550 }
1551 
DetectHttpHeaderIsdataatParseTest(void)1552 static int DetectHttpHeaderIsdataatParseTest(void)
1553 {
1554     DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1555     FAIL_IF_NULL(de_ctx);
1556     de_ctx->flags |= DE_QUIET;
1557 
1558     Signature *s = DetectEngineAppendSig(de_ctx,
1559             "alert tcp any any -> any any ("
1560             "flow:to_server; "
1561             "content:\"one\"; http_header; "
1562             "isdataat:!4,relative; sid:1;)");
1563     FAIL_IF_NULL(s);
1564 
1565     SigMatch *sm = s->init_data->smlists_tail[g_http_header_buffer_id];
1566     FAIL_IF_NULL(sm);
1567     FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
1568 
1569     DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
1570     FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
1571     FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
1572     FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
1573 
1574     DetectEngineCtxFree(de_ctx);
1575     PASS;
1576 }
1577 
1578 /**
1579  *\test Test that the http_header content matches against a http request
1580  *      which holds the content.
1581  */
DetectEngineHttpHeaderTest01(void)1582 static int DetectEngineHttpHeaderTest01(void)
1583 {
1584     TcpSession ssn;
1585     Packet *p = NULL;
1586     ThreadVars th_v;
1587     DetectEngineCtx *de_ctx = NULL;
1588     DetectEngineThreadCtx *det_ctx = NULL;
1589     HtpState *http_state = NULL;
1590     Flow f;
1591     uint8_t http_buf[] =
1592         "GET /index.html HTTP/1.0\r\n"
1593         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1594     uint32_t http_len = sizeof(http_buf) - 1;
1595     int result = 0;
1596     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1597 
1598     memset(&th_v, 0, sizeof(th_v));
1599     memset(&f, 0, sizeof(f));
1600     memset(&ssn, 0, sizeof(ssn));
1601 
1602     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1603 
1604     FLOW_INITIALIZE(&f);
1605     f.protoctx = (void *)&ssn;
1606     f.proto = IPPROTO_TCP;
1607     f.flags |= FLOW_IPV4;
1608     p->flow = &f;
1609     p->flowflags |= FLOW_PKT_TOSERVER;
1610     p->flowflags |= FLOW_PKT_ESTABLISHED;
1611     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1612     f.alproto = ALPROTO_HTTP;
1613 
1614     StreamTcpInitConfig(TRUE);
1615 
1616     de_ctx = DetectEngineCtxInit();
1617     if (de_ctx == NULL)
1618         goto end;
1619 
1620     de_ctx->flags |= DE_QUIET;
1621 
1622     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1623                                "(msg:\"http header test\"; "
1624                                "content:\"one\"; http_header; "
1625                                "sid:1;)");
1626     if (de_ctx->sig_list == NULL)
1627         goto end;
1628 
1629     SigGroupBuild(de_ctx);
1630     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1631 
1632     FLOWLOCK_WRLOCK(&f);
1633     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1634                                 STREAM_TOSERVER, http_buf, http_len);
1635     if (r != 0) {
1636         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1637         result = 0;
1638         FLOWLOCK_UNLOCK(&f);
1639         goto end;
1640     }
1641     FLOWLOCK_UNLOCK(&f);
1642 
1643     http_state = f.alstate;
1644     if (http_state == NULL) {
1645         printf("no http state: ");
1646         result = 0;
1647         goto end;
1648     }
1649 
1650     /* do detect */
1651     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1652 
1653     if (!(PacketAlertCheck(p, 1))) {
1654         printf("sid 1 didn't match but should have: ");
1655         goto end;
1656     }
1657 
1658     result = 1;
1659 end:
1660     if (alp_tctx != NULL)
1661         AppLayerParserThreadCtxFree(alp_tctx);
1662     if (de_ctx != NULL)
1663         DetectEngineCtxFree(de_ctx);
1664 
1665     StreamTcpFreeConfig(TRUE);
1666     FLOW_DESTROY(&f);
1667     UTHFreePackets(&p, 1);
1668     return result;
1669 }
1670 
1671 /**
1672  *\test Test that the http_header content matches against a http request
1673  *      which holds the content.
1674  */
DetectEngineHttpHeaderTest02(void)1675 static int DetectEngineHttpHeaderTest02(void)
1676 {
1677     TcpSession ssn;
1678     Packet *p = NULL;
1679     ThreadVars th_v;
1680     DetectEngineCtx *de_ctx = NULL;
1681     DetectEngineThreadCtx *det_ctx = NULL;
1682     HtpState *http_state = NULL;
1683     Flow f;
1684     uint8_t http_buf[] =
1685         "GET /index.html HTTP/1.0\r\n"
1686         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1687     uint32_t http_len = sizeof(http_buf) - 1;
1688     int result = 0;
1689     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1690 
1691     memset(&th_v, 0, sizeof(th_v));
1692     memset(&f, 0, sizeof(f));
1693     memset(&ssn, 0, sizeof(ssn));
1694 
1695     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1696 
1697     FLOW_INITIALIZE(&f);
1698     f.protoctx = (void *)&ssn;
1699     f.proto = IPPROTO_TCP;
1700     f.flags |= FLOW_IPV4;
1701     p->flow = &f;
1702     p->flowflags |= FLOW_PKT_TOSERVER;
1703     p->flowflags |= FLOW_PKT_ESTABLISHED;
1704     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1705     f.alproto = ALPROTO_HTTP;
1706 
1707     StreamTcpInitConfig(TRUE);
1708 
1709     de_ctx = DetectEngineCtxInit();
1710     if (de_ctx == NULL)
1711         goto end;
1712 
1713     de_ctx->flags |= DE_QUIET;
1714 
1715     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1716                                "(msg:\"http header test\"; "
1717                                "content:\"one\"; depth:15; http_header; "
1718                                "sid:1;)");
1719     if (de_ctx->sig_list == NULL)
1720         goto end;
1721 
1722     SigGroupBuild(de_ctx);
1723     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1724 
1725     FLOWLOCK_WRLOCK(&f);
1726     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1727                                 STREAM_TOSERVER, http_buf, http_len);
1728     if (r != 0) {
1729         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1730         result = 0;
1731         FLOWLOCK_UNLOCK(&f);
1732         goto end;
1733     }
1734     FLOWLOCK_UNLOCK(&f);
1735 
1736     http_state = f.alstate;
1737     if (http_state == NULL) {
1738         printf("no http state: ");
1739         result = 0;
1740         goto end;
1741     }
1742 
1743     /* do detect */
1744     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1745 
1746     if (!(PacketAlertCheck(p, 1))) {
1747         printf("sid 1 didn't match but should have: ");
1748         goto end;
1749     }
1750 
1751     result = 1;
1752 end:
1753     if (alp_tctx != NULL)
1754         AppLayerParserThreadCtxFree(alp_tctx);
1755     if (de_ctx != NULL)
1756         DetectEngineCtxFree(de_ctx);
1757 
1758     StreamTcpFreeConfig(TRUE);
1759     FLOW_DESTROY(&f);
1760     UTHFreePackets(&p, 1);
1761     return result;
1762 }
1763 
1764 /**
1765  *\test Test that the http_header content matches against a http request
1766  *      which holds the content.
1767  */
DetectEngineHttpHeaderTest03(void)1768 static int DetectEngineHttpHeaderTest03(void)
1769 {
1770     TcpSession ssn;
1771     Packet *p = NULL;
1772     ThreadVars th_v;
1773     DetectEngineCtx *de_ctx = NULL;
1774     DetectEngineThreadCtx *det_ctx = NULL;
1775     HtpState *http_state = NULL;
1776     Flow f;
1777     uint8_t http_buf[] =
1778         "GET /index.html HTTP/1.0\r\n"
1779         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1780     uint32_t http_len = sizeof(http_buf) - 1;
1781     int result = 0;
1782     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1783 
1784     memset(&th_v, 0, sizeof(th_v));
1785     memset(&f, 0, sizeof(f));
1786     memset(&ssn, 0, sizeof(ssn));
1787 
1788     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1789 
1790     FLOW_INITIALIZE(&f);
1791     f.protoctx = (void *)&ssn;
1792     f.proto = IPPROTO_TCP;
1793     f.flags |= FLOW_IPV4;
1794     p->flow = &f;
1795     p->flowflags |= FLOW_PKT_TOSERVER;
1796     p->flowflags |= FLOW_PKT_ESTABLISHED;
1797     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1798     f.alproto = ALPROTO_HTTP;
1799 
1800     StreamTcpInitConfig(TRUE);
1801 
1802     de_ctx = DetectEngineCtxInit();
1803     if (de_ctx == NULL)
1804         goto end;
1805 
1806     de_ctx->flags |= DE_QUIET;
1807 
1808     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1809                                "(msg:\"http header test\"; "
1810                                "content:!\"one\"; depth:5; http_header; "
1811                                "sid:1;)");
1812     if (de_ctx->sig_list == NULL)
1813         goto end;
1814 
1815     SigGroupBuild(de_ctx);
1816     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1817 
1818     FLOWLOCK_WRLOCK(&f);
1819     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1820                                 STREAM_TOSERVER, http_buf, http_len);
1821     if (r != 0) {
1822         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1823         result = 0;
1824         FLOWLOCK_UNLOCK(&f);
1825         goto end;
1826     }
1827     FLOWLOCK_UNLOCK(&f);
1828 
1829     http_state = f.alstate;
1830     if (http_state == NULL) {
1831         printf("no http state: ");
1832         result = 0;
1833         goto end;
1834     }
1835 
1836     /* do detect */
1837     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1838 
1839     if (!(PacketAlertCheck(p, 1))) {
1840         printf("sid 1 didn't match but should have: ");
1841         goto end;
1842     }
1843 
1844     result = 1;
1845 end:
1846     if (alp_tctx != NULL)
1847         AppLayerParserThreadCtxFree(alp_tctx);
1848     if (de_ctx != NULL)
1849         DetectEngineCtxFree(de_ctx);
1850 
1851     StreamTcpFreeConfig(TRUE);
1852     FLOW_DESTROY(&f);
1853     UTHFreePackets(&p, 1);
1854     return result;
1855 }
1856 
1857 /**
1858  *\test Test that the http_header content matches against a http request
1859  *      which holds the content.
1860  */
DetectEngineHttpHeaderTest04(void)1861 static int DetectEngineHttpHeaderTest04(void)
1862 {
1863     TcpSession ssn;
1864     Packet *p = NULL;
1865     ThreadVars th_v;
1866     DetectEngineCtx *de_ctx = NULL;
1867     DetectEngineThreadCtx *det_ctx = NULL;
1868     HtpState *http_state = NULL;
1869     Flow f;
1870     uint8_t http_buf[] =
1871         "GET /index.html HTTP/1.0\r\n"
1872         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1873     uint32_t http_len = sizeof(http_buf) - 1;
1874     int result = 0;
1875     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1876 
1877     memset(&th_v, 0, sizeof(th_v));
1878     memset(&f, 0, sizeof(f));
1879     memset(&ssn, 0, sizeof(ssn));
1880 
1881     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1882 
1883     FLOW_INITIALIZE(&f);
1884     f.protoctx = (void *)&ssn;
1885     f.proto = IPPROTO_TCP;
1886     f.flags |= FLOW_IPV4;
1887     p->flow = &f;
1888     p->flowflags |= FLOW_PKT_TOSERVER;
1889     p->flowflags |= FLOW_PKT_ESTABLISHED;
1890     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1891     f.alproto = ALPROTO_HTTP;
1892 
1893     StreamTcpInitConfig(TRUE);
1894 
1895     de_ctx = DetectEngineCtxInit();
1896     if (de_ctx == NULL)
1897         goto end;
1898 
1899     de_ctx->flags |= DE_QUIET;
1900 
1901     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1902                                "(msg:\"http header test\"; "
1903                                "content:\"one\"; depth:5; http_header; "
1904                                "sid:1;)");
1905     if (de_ctx->sig_list == NULL)
1906         goto end;
1907 
1908     SigGroupBuild(de_ctx);
1909     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1910 
1911     FLOWLOCK_WRLOCK(&f);
1912     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
1913                                 STREAM_TOSERVER, http_buf, http_len);
1914     if (r != 0) {
1915         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1916         result = 0;
1917         FLOWLOCK_UNLOCK(&f);
1918         goto end;
1919     }
1920     FLOWLOCK_UNLOCK(&f);
1921 
1922     http_state = f.alstate;
1923     if (http_state == NULL) {
1924         printf("no http state: ");
1925         result = 0;
1926         goto end;
1927     }
1928 
1929     /* do detect */
1930     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1931 
1932     if (PacketAlertCheck(p, 1)) {
1933         printf("sid 1 matched but shouldn't have: ");
1934         goto end;
1935     }
1936 
1937     result = 1;
1938 end:
1939     if (alp_tctx != NULL)
1940         AppLayerParserThreadCtxFree(alp_tctx);
1941     if (de_ctx != NULL)
1942         DetectEngineCtxFree(de_ctx);
1943 
1944     StreamTcpFreeConfig(TRUE);
1945     FLOW_DESTROY(&f);
1946     UTHFreePackets(&p, 1);
1947     return result;
1948 }
1949 
1950 /**
1951  *\test Test that the http_header content matches against a http request
1952  *      which holds the content.
1953  */
DetectEngineHttpHeaderTest05(void)1954 static int DetectEngineHttpHeaderTest05(void)
1955 {
1956     TcpSession ssn;
1957     Packet *p = NULL;
1958     ThreadVars th_v;
1959     DetectEngineCtx *de_ctx = NULL;
1960     DetectEngineThreadCtx *det_ctx = NULL;
1961     HtpState *http_state = NULL;
1962     Flow f;
1963     uint8_t http_buf[] =
1964         "GET /index.html HTTP/1.0\r\n"
1965         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1966     uint32_t http_len = sizeof(http_buf) - 1;
1967     int result = 0;
1968     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1969 
1970     memset(&th_v, 0, sizeof(th_v));
1971     memset(&f, 0, sizeof(f));
1972     memset(&ssn, 0, sizeof(ssn));
1973 
1974     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1975 
1976     FLOW_INITIALIZE(&f);
1977     f.protoctx = (void *)&ssn;
1978     f.proto = IPPROTO_TCP;
1979     f.flags |= FLOW_IPV4;
1980     p->flow = &f;
1981     p->flowflags |= FLOW_PKT_TOSERVER;
1982     p->flowflags |= FLOW_PKT_ESTABLISHED;
1983     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1984     f.alproto = ALPROTO_HTTP;
1985 
1986     StreamTcpInitConfig(TRUE);
1987 
1988     de_ctx = DetectEngineCtxInit();
1989     if (de_ctx == NULL)
1990         goto end;
1991 
1992     de_ctx->flags |= DE_QUIET;
1993 
1994     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1995                                "(msg:\"http header test\"; "
1996                                "content:!\"one\"; depth:15; http_header; "
1997                                "sid:1;)");
1998     if (de_ctx->sig_list == NULL)
1999         goto end;
2000 
2001     SigGroupBuild(de_ctx);
2002     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2003 
2004     FLOWLOCK_WRLOCK(&f);
2005     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2006                                 STREAM_TOSERVER, http_buf, http_len);
2007     if (r != 0) {
2008         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2009         result = 0;
2010         FLOWLOCK_UNLOCK(&f);
2011         goto end;
2012     }
2013     FLOWLOCK_UNLOCK(&f);
2014 
2015     http_state = f.alstate;
2016     if (http_state == NULL) {
2017         printf("no http state: ");
2018         result = 0;
2019         goto end;
2020     }
2021 
2022     /* do detect */
2023     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2024 
2025     if (PacketAlertCheck(p, 1)) {
2026         printf("sid 1 matched but shouldn't have: ");
2027         goto end;
2028     }
2029 
2030     result = 1;
2031 end:
2032     if (alp_tctx != NULL)
2033         AppLayerParserThreadCtxFree(alp_tctx);
2034     if (de_ctx != NULL)
2035         DetectEngineCtxFree(de_ctx);
2036 
2037     StreamTcpFreeConfig(TRUE);
2038     FLOW_DESTROY(&f);
2039     UTHFreePackets(&p, 1);
2040     return result;
2041 }
2042 
2043 /**
2044  *\test Test that the http_header content matches against a http request
2045  *      which holds the content.
2046  */
DetectEngineHttpHeaderTest06(void)2047 static int DetectEngineHttpHeaderTest06(void)
2048 {
2049     TcpSession ssn;
2050     Packet *p = NULL;
2051     ThreadVars th_v;
2052     DetectEngineCtx *de_ctx = NULL;
2053     DetectEngineThreadCtx *det_ctx = NULL;
2054     HtpState *http_state = NULL;
2055     Flow f;
2056     uint8_t http_buf[] =
2057         "GET /index.html HTTP/1.0\r\n"
2058         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2059     uint32_t http_len = sizeof(http_buf) - 1;
2060     int result = 0;
2061     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2062 
2063     memset(&th_v, 0, sizeof(th_v));
2064     memset(&f, 0, sizeof(f));
2065     memset(&ssn, 0, sizeof(ssn));
2066 
2067     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2068 
2069     FLOW_INITIALIZE(&f);
2070     f.protoctx = (void *)&ssn;
2071     f.proto = IPPROTO_TCP;
2072     f.flags |= FLOW_IPV4;
2073     p->flow = &f;
2074     p->flowflags |= FLOW_PKT_TOSERVER;
2075     p->flowflags |= FLOW_PKT_ESTABLISHED;
2076     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2077     f.alproto = ALPROTO_HTTP;
2078 
2079     StreamTcpInitConfig(TRUE);
2080 
2081     de_ctx = DetectEngineCtxInit();
2082     if (de_ctx == NULL)
2083         goto end;
2084 
2085     de_ctx->flags |= DE_QUIET;
2086 
2087     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2088                                "(msg:\"http header test\"; "
2089                                "content:\"one\"; offset:10; http_header; "
2090                                "sid:1;)");
2091     if (de_ctx->sig_list == NULL)
2092         goto end;
2093 
2094     SigGroupBuild(de_ctx);
2095     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2096 
2097     FLOWLOCK_WRLOCK(&f);
2098     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2099                                 STREAM_TOSERVER, http_buf, http_len);
2100     if (r != 0) {
2101         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2102         result = 0;
2103         FLOWLOCK_UNLOCK(&f);
2104         goto end;
2105     }
2106     FLOWLOCK_UNLOCK(&f);
2107 
2108     http_state = f.alstate;
2109     if (http_state == NULL) {
2110         printf("no http state: ");
2111         result = 0;
2112         goto end;
2113     }
2114 
2115     /* do detect */
2116     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2117 
2118     if (!(PacketAlertCheck(p, 1))) {
2119         printf("sid 1 didn't match but should have: ");
2120         goto end;
2121     }
2122 
2123     result = 1;
2124 end:
2125     if (alp_tctx != NULL)
2126         AppLayerParserThreadCtxFree(alp_tctx);
2127     if (de_ctx != NULL)
2128         DetectEngineCtxFree(de_ctx);
2129 
2130     StreamTcpFreeConfig(TRUE);
2131     FLOW_DESTROY(&f);
2132     UTHFreePackets(&p, 1);
2133     return result;
2134 }
2135 
2136 /**
2137  *\test Test that the http_header content matches against a http request
2138  *      which holds the content.
2139  */
DetectEngineHttpHeaderTest07(void)2140 static int DetectEngineHttpHeaderTest07(void)
2141 {
2142     TcpSession ssn;
2143     Packet *p = NULL;
2144     ThreadVars th_v;
2145     DetectEngineCtx *de_ctx = NULL;
2146     DetectEngineThreadCtx *det_ctx = NULL;
2147     HtpState *http_state = NULL;
2148     Flow f;
2149     uint8_t http_buf[] =
2150         "GET /index.html HTTP/1.0\r\n"
2151         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2152     uint32_t http_len = sizeof(http_buf) - 1;
2153     int result = 0;
2154     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2155 
2156     memset(&th_v, 0, sizeof(th_v));
2157     memset(&f, 0, sizeof(f));
2158     memset(&ssn, 0, sizeof(ssn));
2159 
2160     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2161 
2162     FLOW_INITIALIZE(&f);
2163     f.protoctx = (void *)&ssn;
2164     f.proto = IPPROTO_TCP;
2165     f.flags |= FLOW_IPV4;
2166     p->flow = &f;
2167     p->flowflags |= FLOW_PKT_TOSERVER;
2168     p->flowflags |= FLOW_PKT_ESTABLISHED;
2169     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2170     f.alproto = ALPROTO_HTTP;
2171 
2172     StreamTcpInitConfig(TRUE);
2173 
2174     de_ctx = DetectEngineCtxInit();
2175     if (de_ctx == NULL)
2176         goto end;
2177 
2178     de_ctx->flags |= DE_QUIET;
2179 
2180     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2181                                "(msg:\"http header test\"; "
2182                                "content:!\"one\"; offset:15; http_header; "
2183                                "sid:1;)");
2184     if (de_ctx->sig_list == NULL)
2185         goto end;
2186 
2187     SigGroupBuild(de_ctx);
2188     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2189 
2190     FLOWLOCK_WRLOCK(&f);
2191     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2192                                 STREAM_TOSERVER, http_buf, http_len);
2193     if (r != 0) {
2194         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2195         result = 0;
2196         FLOWLOCK_UNLOCK(&f);
2197         goto end;
2198     }
2199     FLOWLOCK_UNLOCK(&f);
2200 
2201     http_state = f.alstate;
2202     if (http_state == NULL) {
2203         printf("no http state: ");
2204         result = 0;
2205         goto end;
2206     }
2207 
2208     /* do detect */
2209     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2210 
2211     if (!(PacketAlertCheck(p, 1))) {
2212         printf("sid 1 didn't match but should have: ");
2213         goto end;
2214     }
2215 
2216     result = 1;
2217 end:
2218     if (alp_tctx != NULL)
2219         AppLayerParserThreadCtxFree(alp_tctx);
2220     if (de_ctx != NULL)
2221         DetectEngineCtxFree(de_ctx);
2222 
2223     StreamTcpFreeConfig(TRUE);
2224     FLOW_DESTROY(&f);
2225     UTHFreePackets(&p, 1);
2226     return result;
2227 }
2228 
2229 /**
2230  *\test Test that the http_header content matches against a http request
2231  *      which holds the content.
2232  */
DetectEngineHttpHeaderTest08(void)2233 static int DetectEngineHttpHeaderTest08(void)
2234 {
2235     TcpSession ssn;
2236     Packet *p = NULL;
2237     ThreadVars th_v;
2238     DetectEngineCtx *de_ctx = NULL;
2239     DetectEngineThreadCtx *det_ctx = NULL;
2240     HtpState *http_state = NULL;
2241     Flow f;
2242     uint8_t http_buf[] =
2243         "GET /index.html HTTP/1.0\r\n"
2244         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2245     uint32_t http_len = sizeof(http_buf) - 1;
2246     int result = 0;
2247     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2248 
2249     memset(&th_v, 0, sizeof(th_v));
2250     memset(&f, 0, sizeof(f));
2251     memset(&ssn, 0, sizeof(ssn));
2252 
2253     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2254 
2255     FLOW_INITIALIZE(&f);
2256     f.protoctx = (void *)&ssn;
2257     f.proto = IPPROTO_TCP;
2258     f.flags |= FLOW_IPV4;
2259     p->flow = &f;
2260     p->flowflags |= FLOW_PKT_TOSERVER;
2261     p->flowflags |= FLOW_PKT_ESTABLISHED;
2262     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2263     f.alproto = ALPROTO_HTTP;
2264 
2265     StreamTcpInitConfig(TRUE);
2266 
2267     de_ctx = DetectEngineCtxInit();
2268     if (de_ctx == NULL)
2269         goto end;
2270 
2271     de_ctx->flags |= DE_QUIET;
2272 
2273     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2274                                "(msg:\"http header test\"; "
2275                                "content:\"one\"; offset:15; http_header; "
2276                                "sid:1;)");
2277     if (de_ctx->sig_list == NULL)
2278         goto end;
2279 
2280     SigGroupBuild(de_ctx);
2281     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2282 
2283     FLOWLOCK_WRLOCK(&f);
2284     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2285                                 STREAM_TOSERVER, http_buf, http_len);
2286     if (r != 0) {
2287         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2288         result = 0;
2289         FLOWLOCK_UNLOCK(&f);
2290         goto end;
2291     }
2292     FLOWLOCK_UNLOCK(&f);
2293 
2294     http_state = f.alstate;
2295     if (http_state == NULL) {
2296         printf("no http state: ");
2297         result = 0;
2298         goto end;
2299     }
2300 
2301     /* do detect */
2302     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2303 
2304     if (PacketAlertCheck(p, 1)) {
2305         printf("sid 1 matched but shouldn't have: ");
2306         goto end;
2307     }
2308 
2309     result = 1;
2310 end:
2311     if (alp_tctx != NULL)
2312         AppLayerParserThreadCtxFree(alp_tctx);
2313     if (de_ctx != NULL)
2314         DetectEngineCtxFree(de_ctx);
2315 
2316     StreamTcpFreeConfig(TRUE);
2317     FLOW_DESTROY(&f);
2318     UTHFreePackets(&p, 1);
2319     return result;
2320 }
2321 
2322 /**
2323  *\test Test that the http_header content matches against a http request
2324  *      which holds the content.
2325  */
DetectEngineHttpHeaderTest09(void)2326 static int DetectEngineHttpHeaderTest09(void)
2327 {
2328     TcpSession ssn;
2329     Packet *p = NULL;
2330     ThreadVars th_v;
2331     DetectEngineCtx *de_ctx = NULL;
2332     DetectEngineThreadCtx *det_ctx = NULL;
2333     HtpState *http_state = NULL;
2334     Flow f;
2335     uint8_t http_buf[] =
2336         "GET /index.html HTTP/1.0\r\n"
2337         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2338     uint32_t http_len = sizeof(http_buf) - 1;
2339     int result = 0;
2340     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2341 
2342     memset(&th_v, 0, sizeof(th_v));
2343     memset(&f, 0, sizeof(f));
2344     memset(&ssn, 0, sizeof(ssn));
2345 
2346     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2347 
2348     FLOW_INITIALIZE(&f);
2349     f.protoctx = (void *)&ssn;
2350     f.proto = IPPROTO_TCP;
2351     f.flags |= FLOW_IPV4;
2352     p->flow = &f;
2353     p->flowflags |= FLOW_PKT_TOSERVER;
2354     p->flowflags |= FLOW_PKT_ESTABLISHED;
2355     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2356     f.alproto = ALPROTO_HTTP;
2357 
2358     StreamTcpInitConfig(TRUE);
2359 
2360     de_ctx = DetectEngineCtxInit();
2361     if (de_ctx == NULL)
2362         goto end;
2363 
2364     de_ctx->flags |= DE_QUIET;
2365 
2366     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2367                                "(msg:\"http header test\"; "
2368                                "content:!\"one\"; offset:10; http_header; "
2369                                "sid:1;)");
2370     if (de_ctx->sig_list == NULL)
2371         goto end;
2372 
2373     SigGroupBuild(de_ctx);
2374     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2375 
2376     FLOWLOCK_WRLOCK(&f);
2377     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2378                                 STREAM_TOSERVER, http_buf, http_len);
2379     if (r != 0) {
2380         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2381         result = 0;
2382         FLOWLOCK_UNLOCK(&f);
2383         goto end;
2384     }
2385     FLOWLOCK_UNLOCK(&f);
2386 
2387     http_state = f.alstate;
2388     if (http_state == NULL) {
2389         printf("no http state: ");
2390         result = 0;
2391         goto end;
2392     }
2393 
2394     /* do detect */
2395     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2396 
2397     if (PacketAlertCheck(p, 1)) {
2398         printf("sid 1 matched but shouldn't have: ");
2399         goto end;
2400     }
2401 
2402     result = 1;
2403 end:
2404     if (alp_tctx != NULL)
2405         AppLayerParserThreadCtxFree(alp_tctx);
2406     if (de_ctx != NULL)
2407         DetectEngineCtxFree(de_ctx);
2408 
2409     StreamTcpFreeConfig(TRUE);
2410     FLOW_DESTROY(&f);
2411     UTHFreePackets(&p, 1);
2412     return result;
2413 }
2414 
2415 /**
2416  *\test Test that the http_header content matches against a http request
2417  *      which holds the content.
2418  */
DetectEngineHttpHeaderTest10(void)2419 static int DetectEngineHttpHeaderTest10(void)
2420 {
2421     TcpSession ssn;
2422     Packet *p = NULL;
2423     ThreadVars th_v;
2424     DetectEngineCtx *de_ctx = NULL;
2425     DetectEngineThreadCtx *det_ctx = NULL;
2426     HtpState *http_state = NULL;
2427     Flow f;
2428     uint8_t http_buf[] =
2429         "GET /index.html HTTP/1.0\r\n"
2430         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2431     uint32_t http_len = sizeof(http_buf) - 1;
2432     int result = 0;
2433     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2434 
2435     memset(&th_v, 0, sizeof(th_v));
2436     memset(&f, 0, sizeof(f));
2437     memset(&ssn, 0, sizeof(ssn));
2438 
2439     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2440 
2441     FLOW_INITIALIZE(&f);
2442     f.protoctx = (void *)&ssn;
2443     f.proto = IPPROTO_TCP;
2444     f.flags |= FLOW_IPV4;
2445     p->flow = &f;
2446     p->flowflags |= FLOW_PKT_TOSERVER;
2447     p->flowflags |= FLOW_PKT_ESTABLISHED;
2448     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2449     f.alproto = ALPROTO_HTTP;
2450 
2451     StreamTcpInitConfig(TRUE);
2452 
2453     de_ctx = DetectEngineCtxInit();
2454     if (de_ctx == NULL)
2455         goto end;
2456 
2457     de_ctx->flags |= DE_QUIET;
2458 
2459     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2460                                "(msg:\"http header test\"; "
2461                                "content:\"one\"; http_header; content:\"three\"; http_header; within:10; "
2462                                "sid:1;)");
2463     if (de_ctx->sig_list == NULL)
2464         goto end;
2465 
2466     SigGroupBuild(de_ctx);
2467     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2468 
2469     FLOWLOCK_WRLOCK(&f);
2470     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2471                                 STREAM_TOSERVER, http_buf, http_len);
2472     if (r != 0) {
2473         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2474         result = 0;
2475         FLOWLOCK_UNLOCK(&f);
2476         goto end;
2477     }
2478     FLOWLOCK_UNLOCK(&f);
2479 
2480     http_state = f.alstate;
2481     if (http_state == NULL) {
2482         printf("no http state: ");
2483         result = 0;
2484         goto end;
2485     }
2486 
2487     /* do detect */
2488     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2489 
2490     if (!(PacketAlertCheck(p, 1))) {
2491         printf("sid 1 didn't match but should have: ");
2492         goto end;
2493     }
2494 
2495     result = 1;
2496 end:
2497     if (alp_tctx != NULL)
2498         AppLayerParserThreadCtxFree(alp_tctx);
2499     if (de_ctx != NULL)
2500         DetectEngineCtxFree(de_ctx);
2501 
2502     StreamTcpFreeConfig(TRUE);
2503     FLOW_DESTROY(&f);
2504     UTHFreePackets(&p, 1);
2505     return result;
2506 }
2507 
2508 /**
2509  *\test Test that the http_header content matches against a http request
2510  *      which holds the content.
2511  */
DetectEngineHttpHeaderTest11(void)2512 static int DetectEngineHttpHeaderTest11(void)
2513 {
2514     TcpSession ssn;
2515     Packet *p = NULL;
2516     ThreadVars th_v;
2517     DetectEngineCtx *de_ctx = NULL;
2518     DetectEngineThreadCtx *det_ctx = NULL;
2519     HtpState *http_state = NULL;
2520     Flow f;
2521     uint8_t http_buf[] =
2522         "GET /index.html HTTP/1.0\r\n"
2523         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2524     uint32_t http_len = sizeof(http_buf) - 1;
2525     int result = 0;
2526     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2527 
2528     memset(&th_v, 0, sizeof(th_v));
2529     memset(&f, 0, sizeof(f));
2530     memset(&ssn, 0, sizeof(ssn));
2531 
2532     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2533 
2534     FLOW_INITIALIZE(&f);
2535     f.protoctx = (void *)&ssn;
2536     f.proto = IPPROTO_TCP;
2537     f.flags |= FLOW_IPV4;
2538     p->flow = &f;
2539     p->flowflags |= FLOW_PKT_TOSERVER;
2540     p->flowflags |= FLOW_PKT_ESTABLISHED;
2541     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2542     f.alproto = ALPROTO_HTTP;
2543 
2544     StreamTcpInitConfig(TRUE);
2545 
2546     de_ctx = DetectEngineCtxInit();
2547     if (de_ctx == NULL)
2548         goto end;
2549 
2550     de_ctx->flags |= DE_QUIET;
2551 
2552     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2553                                "(msg:\"http header test\"; "
2554                                "content:\"one\"; http_header; content:!\"three\"; http_header; within:5; "
2555                                "sid:1;)");
2556     if (de_ctx->sig_list == NULL)
2557         goto end;
2558 
2559     SigGroupBuild(de_ctx);
2560     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2561 
2562     FLOWLOCK_WRLOCK(&f);
2563     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2564                                 STREAM_TOSERVER, http_buf, http_len);
2565     if (r != 0) {
2566         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2567         result = 0;
2568         FLOWLOCK_UNLOCK(&f);
2569         goto end;
2570     }
2571     FLOWLOCK_UNLOCK(&f);
2572 
2573     http_state = f.alstate;
2574     if (http_state == NULL) {
2575         printf("no http state: ");
2576         result = 0;
2577         goto end;
2578     }
2579 
2580     /* do detect */
2581     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2582 
2583     if (!(PacketAlertCheck(p, 1))) {
2584         printf("sid 1 didn't match but should have: ");
2585         goto end;
2586     }
2587 
2588     result = 1;
2589 end:
2590     if (alp_tctx != NULL)
2591         AppLayerParserThreadCtxFree(alp_tctx);
2592     if (de_ctx != NULL)
2593         DetectEngineCtxFree(de_ctx);
2594 
2595     StreamTcpFreeConfig(TRUE);
2596     FLOW_DESTROY(&f);
2597     UTHFreePackets(&p, 1);
2598     return result;
2599 }
2600 
2601 /**
2602  *\test Test that the http_header content matches against a http request
2603  *      which holds the content.
2604  */
DetectEngineHttpHeaderTest12(void)2605 static int DetectEngineHttpHeaderTest12(void)
2606 {
2607     TcpSession ssn;
2608     Packet *p = NULL;
2609     ThreadVars th_v;
2610     DetectEngineCtx *de_ctx = NULL;
2611     DetectEngineThreadCtx *det_ctx = NULL;
2612     HtpState *http_state = NULL;
2613     Flow f;
2614     uint8_t http_buf[] =
2615         "GET /index.html HTTP/1.0\r\n"
2616         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2617     uint32_t http_len = sizeof(http_buf) - 1;
2618     int result = 0;
2619     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2620 
2621     memset(&th_v, 0, sizeof(th_v));
2622     memset(&f, 0, sizeof(f));
2623     memset(&ssn, 0, sizeof(ssn));
2624 
2625     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2626 
2627     FLOW_INITIALIZE(&f);
2628     f.protoctx = (void *)&ssn;
2629     f.proto = IPPROTO_TCP;
2630     f.flags |= FLOW_IPV4;
2631     p->flow = &f;
2632     p->flowflags |= FLOW_PKT_TOSERVER;
2633     p->flowflags |= FLOW_PKT_ESTABLISHED;
2634     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2635     f.alproto = ALPROTO_HTTP;
2636 
2637     StreamTcpInitConfig(TRUE);
2638 
2639     de_ctx = DetectEngineCtxInit();
2640     if (de_ctx == NULL)
2641         goto end;
2642 
2643     de_ctx->flags |= DE_QUIET;
2644 
2645     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2646                                "(msg:\"http header test\"; "
2647                                "content:\"one\"; http_header; content:!\"three\"; http_header; within:10; "
2648                                "sid:1;)");
2649     if (de_ctx->sig_list == NULL)
2650         goto end;
2651 
2652     SigGroupBuild(de_ctx);
2653     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2654 
2655     FLOWLOCK_WRLOCK(&f);
2656     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2657                                 STREAM_TOSERVER, http_buf, http_len);
2658     if (r != 0) {
2659         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2660         result = 0;
2661         FLOWLOCK_UNLOCK(&f);
2662         goto end;
2663     }
2664     FLOWLOCK_UNLOCK(&f);
2665 
2666     http_state = f.alstate;
2667     if (http_state == NULL) {
2668         printf("no http state: ");
2669         result = 0;
2670         goto end;
2671     }
2672 
2673     /* do detect */
2674     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2675 
2676     if (PacketAlertCheck(p, 1)) {
2677         printf("sid 1 matched but shouldn't have: ");
2678         goto end;
2679     }
2680 
2681     result = 1;
2682 end:
2683     if (alp_tctx != NULL)
2684         AppLayerParserThreadCtxFree(alp_tctx);
2685     if (de_ctx != NULL)
2686         DetectEngineCtxFree(de_ctx);
2687 
2688     StreamTcpFreeConfig(TRUE);
2689     FLOW_DESTROY(&f);
2690     UTHFreePackets(&p, 1);
2691     return result;
2692 }
2693 
2694 /**
2695  *\test Test that the http_header content matches against a http request
2696  *      which holds the content.
2697  */
DetectEngineHttpHeaderTest13(void)2698 static int DetectEngineHttpHeaderTest13(void)
2699 {
2700     TcpSession ssn;
2701     Packet *p = NULL;
2702     ThreadVars th_v;
2703     DetectEngineCtx *de_ctx = NULL;
2704     DetectEngineThreadCtx *det_ctx = NULL;
2705     HtpState *http_state = NULL;
2706     Flow f;
2707     uint8_t http_buf[] =
2708         "GET /index.html HTTP/1.0\r\n"
2709         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2710     uint32_t http_len = sizeof(http_buf) - 1;
2711     int result = 0;
2712     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2713 
2714     memset(&th_v, 0, sizeof(th_v));
2715     memset(&f, 0, sizeof(f));
2716     memset(&ssn, 0, sizeof(ssn));
2717 
2718     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2719 
2720     FLOW_INITIALIZE(&f);
2721     f.protoctx = (void *)&ssn;
2722     f.proto = IPPROTO_TCP;
2723     f.flags |= FLOW_IPV4;
2724     p->flow = &f;
2725     p->flowflags |= FLOW_PKT_TOSERVER;
2726     p->flowflags |= FLOW_PKT_ESTABLISHED;
2727     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2728     f.alproto = ALPROTO_HTTP;
2729 
2730     StreamTcpInitConfig(TRUE);
2731 
2732     de_ctx = DetectEngineCtxInit();
2733     if (de_ctx == NULL)
2734         goto end;
2735 
2736     de_ctx->flags |= DE_QUIET;
2737 
2738     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2739                                "(msg:\"http header test\"; "
2740                                "content:\"one\"; http_header; content:\"three\"; http_header; within:5; "
2741                                "sid:1;)");
2742     if (de_ctx->sig_list == NULL)
2743         goto end;
2744 
2745     SigGroupBuild(de_ctx);
2746     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2747 
2748     FLOWLOCK_WRLOCK(&f);
2749     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2750                                 STREAM_TOSERVER, http_buf, http_len);
2751     if (r != 0) {
2752         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2753         result = 0;
2754         FLOWLOCK_UNLOCK(&f);
2755         goto end;
2756     }
2757     FLOWLOCK_UNLOCK(&f);
2758 
2759     http_state = f.alstate;
2760     if (http_state == NULL) {
2761         printf("no http state: ");
2762         result = 0;
2763         goto end;
2764     }
2765 
2766     /* do detect */
2767     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2768 
2769     if (PacketAlertCheck(p, 1)) {
2770         printf("sid 1 matched but shouldn't have: ");
2771         goto end;
2772     }
2773 
2774     result = 1;
2775 end:
2776     if (alp_tctx != NULL)
2777         AppLayerParserThreadCtxFree(alp_tctx);
2778     if (de_ctx != NULL)
2779         DetectEngineCtxFree(de_ctx);
2780 
2781     StreamTcpFreeConfig(TRUE);
2782     FLOW_DESTROY(&f);
2783     UTHFreePackets(&p, 1);
2784     return result;
2785 }
2786 
2787 /**
2788  *\test Test that the http_header content matches against a http request
2789  *      which holds the content.
2790  */
DetectEngineHttpHeaderTest14(void)2791 static int DetectEngineHttpHeaderTest14(void)
2792 {
2793     TcpSession ssn;
2794     Packet *p = NULL;
2795     ThreadVars th_v;
2796     DetectEngineCtx *de_ctx = NULL;
2797     DetectEngineThreadCtx *det_ctx = NULL;
2798     HtpState *http_state = NULL;
2799     Flow f;
2800     uint8_t http_buf[] =
2801         "GET /index.html HTTP/1.0\r\n"
2802         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2803     uint32_t http_len = sizeof(http_buf) - 1;
2804     int result = 0;
2805     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2806 
2807     memset(&th_v, 0, sizeof(th_v));
2808     memset(&f, 0, sizeof(f));
2809     memset(&ssn, 0, sizeof(ssn));
2810 
2811     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2812 
2813     FLOW_INITIALIZE(&f);
2814     f.protoctx = (void *)&ssn;
2815     f.proto = IPPROTO_TCP;
2816     f.flags |= FLOW_IPV4;
2817     p->flow = &f;
2818     p->flowflags |= FLOW_PKT_TOSERVER;
2819     p->flowflags |= FLOW_PKT_ESTABLISHED;
2820     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2821     f.alproto = ALPROTO_HTTP;
2822 
2823     StreamTcpInitConfig(TRUE);
2824 
2825     de_ctx = DetectEngineCtxInit();
2826     if (de_ctx == NULL)
2827         goto end;
2828 
2829     de_ctx->flags |= DE_QUIET;
2830 
2831     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2832                                "(msg:\"http header test\"; "
2833                                "content:\"one\"; http_header; content:\"five\"; http_header; distance:7; "
2834                                "sid:1;)");
2835     if (de_ctx->sig_list == NULL)
2836         goto end;
2837 
2838     SigGroupBuild(de_ctx);
2839     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2840 
2841     FLOWLOCK_WRLOCK(&f);
2842     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2843                                 STREAM_TOSERVER, http_buf, http_len);
2844     if (r != 0) {
2845         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2846         result = 0;
2847         FLOWLOCK_UNLOCK(&f);
2848         goto end;
2849     }
2850     FLOWLOCK_UNLOCK(&f);
2851 
2852     http_state = f.alstate;
2853     if (http_state == NULL) {
2854         printf("no http state: ");
2855         result = 0;
2856         goto end;
2857     }
2858 
2859     /* do detect */
2860     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2861 
2862     if (!(PacketAlertCheck(p, 1))) {
2863         printf("sid 1 didn't match but should have: ");
2864         goto end;
2865     }
2866 
2867     result = 1;
2868 end:
2869     if (alp_tctx != NULL)
2870         AppLayerParserThreadCtxFree(alp_tctx);
2871     if (de_ctx != NULL)
2872         DetectEngineCtxFree(de_ctx);
2873 
2874     StreamTcpFreeConfig(TRUE);
2875     FLOW_DESTROY(&f);
2876     UTHFreePackets(&p, 1);
2877     return result;
2878 }
2879 
2880 /**
2881  *\test Test that the http_header content matches against a http request
2882  *      which holds the content.
2883  */
DetectEngineHttpHeaderTest15(void)2884 static int DetectEngineHttpHeaderTest15(void)
2885 {
2886     TcpSession ssn;
2887     Packet *p = NULL;
2888     ThreadVars th_v;
2889     DetectEngineCtx *de_ctx = NULL;
2890     DetectEngineThreadCtx *det_ctx = NULL;
2891     HtpState *http_state = NULL;
2892     Flow f;
2893     uint8_t http_buf[] =
2894         "GET /index.html HTTP/1.0\r\n"
2895         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2896     uint32_t http_len = sizeof(http_buf) - 1;
2897     int result = 0;
2898     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2899 
2900     memset(&th_v, 0, sizeof(th_v));
2901     memset(&f, 0, sizeof(f));
2902     memset(&ssn, 0, sizeof(ssn));
2903 
2904     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2905 
2906     FLOW_INITIALIZE(&f);
2907     f.protoctx = (void *)&ssn;
2908     f.proto = IPPROTO_TCP;
2909     f.flags |= FLOW_IPV4;
2910     p->flow = &f;
2911     p->flowflags |= FLOW_PKT_TOSERVER;
2912     p->flowflags |= FLOW_PKT_ESTABLISHED;
2913     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2914     f.alproto = ALPROTO_HTTP;
2915 
2916     StreamTcpInitConfig(TRUE);
2917 
2918     de_ctx = DetectEngineCtxInit();
2919     if (de_ctx == NULL)
2920         goto end;
2921 
2922     de_ctx->flags |= DE_QUIET;
2923 
2924     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
2925                                "(msg:\"http header test\"; "
2926                                "content:\"one\"; http_header; content:!\"five\"; http_header; distance:15; "
2927                                "sid:1;)");
2928     if (de_ctx->sig_list == NULL)
2929         goto end;
2930 
2931     SigGroupBuild(de_ctx);
2932     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2933 
2934     FLOWLOCK_WRLOCK(&f);
2935     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
2936                                 STREAM_TOSERVER, http_buf, http_len);
2937     if (r != 0) {
2938         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2939         result = 0;
2940         FLOWLOCK_UNLOCK(&f);
2941         goto end;
2942     }
2943     FLOWLOCK_UNLOCK(&f);
2944 
2945     http_state = f.alstate;
2946     if (http_state == NULL) {
2947         printf("no http state: ");
2948         result = 0;
2949         goto end;
2950     }
2951 
2952     /* do detect */
2953     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2954 
2955     if (!(PacketAlertCheck(p, 1))) {
2956         printf("sid 1 didn't match but should have: ");
2957         goto end;
2958     }
2959 
2960     result = 1;
2961 end:
2962     if (alp_tctx != NULL)
2963         AppLayerParserThreadCtxFree(alp_tctx);
2964     if (de_ctx != NULL)
2965         DetectEngineCtxFree(de_ctx);
2966 
2967     StreamTcpFreeConfig(TRUE);
2968     FLOW_DESTROY(&f);
2969     UTHFreePackets(&p, 1);
2970     return result;
2971 }
2972 
2973 /**
2974  *\test Test that the http_header content matches against a http request
2975  *      which holds the content.
2976  */
DetectEngineHttpHeaderTest16(void)2977 static int DetectEngineHttpHeaderTest16(void)
2978 {
2979     TcpSession ssn;
2980     Packet *p = NULL;
2981     ThreadVars th_v;
2982     DetectEngineCtx *de_ctx = NULL;
2983     DetectEngineThreadCtx *det_ctx = NULL;
2984     HtpState *http_state = NULL;
2985     Flow f;
2986     uint8_t http_buf[] =
2987         "GET /index.html HTTP/1.0\r\n"
2988         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
2989     uint32_t http_len = sizeof(http_buf) - 1;
2990     int result = 0;
2991     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
2992 
2993     memset(&th_v, 0, sizeof(th_v));
2994     memset(&f, 0, sizeof(f));
2995     memset(&ssn, 0, sizeof(ssn));
2996 
2997     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
2998 
2999     FLOW_INITIALIZE(&f);
3000     f.protoctx = (void *)&ssn;
3001     f.proto = IPPROTO_TCP;
3002     f.flags |= FLOW_IPV4;
3003     p->flow = &f;
3004     p->flowflags |= FLOW_PKT_TOSERVER;
3005     p->flowflags |= FLOW_PKT_ESTABLISHED;
3006     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3007     f.alproto = ALPROTO_HTTP;
3008 
3009     StreamTcpInitConfig(TRUE);
3010 
3011     de_ctx = DetectEngineCtxInit();
3012     if (de_ctx == NULL)
3013         goto end;
3014 
3015     de_ctx->flags |= DE_QUIET;
3016 
3017     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3018                                "(msg:\"http header test\"; "
3019                                "content:\"one\"; http_header; content:!\"five\"; http_header; distance:7; "
3020                                "sid:1;)");
3021     if (de_ctx->sig_list == NULL)
3022         goto end;
3023 
3024     SigGroupBuild(de_ctx);
3025     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3026 
3027     FLOWLOCK_WRLOCK(&f);
3028     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3029                                 STREAM_TOSERVER, http_buf, http_len);
3030     if (r != 0) {
3031         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3032         result = 0;
3033         FLOWLOCK_UNLOCK(&f);
3034         goto end;
3035     }
3036     FLOWLOCK_UNLOCK(&f);
3037 
3038     http_state = f.alstate;
3039     if (http_state == NULL) {
3040         printf("no http state: ");
3041         result = 0;
3042         goto end;
3043     }
3044 
3045     /* do detect */
3046     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3047 
3048     if (PacketAlertCheck(p, 1)) {
3049         printf("sid 1 matched but shouldn't have: ");
3050         goto end;
3051     }
3052 
3053     result = 1;
3054 end:
3055     if (alp_tctx != NULL)
3056         AppLayerParserThreadCtxFree(alp_tctx);
3057     if (de_ctx != NULL)
3058         DetectEngineCtxFree(de_ctx);
3059 
3060     StreamTcpFreeConfig(TRUE);
3061     FLOW_DESTROY(&f);
3062     UTHFreePackets(&p, 1);
3063     return result;
3064 }
3065 
3066 /**
3067  *\test Test that the http_header content matches against a http request
3068  *      which holds the content.
3069  */
DetectEngineHttpHeaderTest17(void)3070 static int DetectEngineHttpHeaderTest17(void)
3071 {
3072     TcpSession ssn;
3073     Packet *p = NULL;
3074     ThreadVars th_v;
3075     DetectEngineCtx *de_ctx = NULL;
3076     DetectEngineThreadCtx *det_ctx = NULL;
3077     HtpState *http_state = NULL;
3078     Flow f;
3079     uint8_t http_buf[] =
3080         "GET /index.html HTTP/1.0\r\n"
3081         "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
3082     uint32_t http_len = sizeof(http_buf) - 1;
3083     int result = 0;
3084     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3085 
3086     memset(&th_v, 0, sizeof(th_v));
3087     memset(&f, 0, sizeof(f));
3088     memset(&ssn, 0, sizeof(ssn));
3089 
3090     p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3091 
3092     FLOW_INITIALIZE(&f);
3093     f.protoctx = (void *)&ssn;
3094     f.proto = IPPROTO_TCP;
3095     f.flags |= FLOW_IPV4;
3096     p->flow = &f;
3097     p->flowflags |= FLOW_PKT_TOSERVER;
3098     p->flowflags |= FLOW_PKT_ESTABLISHED;
3099     p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3100     f.alproto = ALPROTO_HTTP;
3101 
3102     StreamTcpInitConfig(TRUE);
3103 
3104     de_ctx = DetectEngineCtxInit();
3105     if (de_ctx == NULL)
3106         goto end;
3107 
3108     de_ctx->flags |= DE_QUIET;
3109 
3110     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3111                                "(msg:\"http header test\"; "
3112                                "content:\"one\"; http_header; content:\"five\"; http_header; distance:15; "
3113                                "sid:1;)");
3114     if (de_ctx->sig_list == NULL)
3115         goto end;
3116 
3117     SigGroupBuild(de_ctx);
3118     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3119 
3120     FLOWLOCK_WRLOCK(&f);
3121     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3122                                 STREAM_TOSERVER, http_buf, http_len);
3123     if (r != 0) {
3124         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3125         result = 0;
3126         FLOWLOCK_UNLOCK(&f);
3127         goto end;
3128     }
3129     FLOWLOCK_UNLOCK(&f);
3130 
3131     http_state = f.alstate;
3132     if (http_state == NULL) {
3133         printf("no http state: ");
3134         result = 0;
3135         goto end;
3136     }
3137 
3138     /* do detect */
3139     SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
3140 
3141     if (PacketAlertCheck(p, 1)) {
3142         printf("sid 1 matched but shouldn't have: ");
3143         goto end;
3144     }
3145 
3146     result = 1;
3147 end:
3148     if (alp_tctx != NULL)
3149         AppLayerParserThreadCtxFree(alp_tctx);
3150     if (de_ctx != NULL)
3151         DetectEngineCtxFree(de_ctx);
3152 
3153     StreamTcpFreeConfig(TRUE);
3154     FLOW_DESTROY(&f);
3155     UTHFreePackets(&p, 1);
3156     return result;
3157 }
3158 
DetectEngineHttpHeaderTest20(void)3159 static int DetectEngineHttpHeaderTest20(void)
3160 {
3161     TcpSession ssn;
3162     Packet *p1 = NULL;
3163     Packet *p2 = NULL;
3164     ThreadVars th_v;
3165     DetectEngineCtx *de_ctx = NULL;
3166     DetectEngineThreadCtx *det_ctx = NULL;
3167     HtpState *http_state = NULL;
3168     Flow f;
3169     uint8_t http1_buf[] =
3170         "GET /index.html HTTP/1.0\r\n"
3171         "Host: This_is_dummy_body1";
3172     uint8_t http2_buf[] =
3173         "This_is_dummy_message_body2\r\n"
3174         "\r\n";
3175     uint32_t http1_len = sizeof(http1_buf) - 1;
3176     uint32_t http2_len = sizeof(http2_buf) - 1;
3177     int result = 0;
3178     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3179 
3180     memset(&th_v, 0, sizeof(th_v));
3181     memset(&f, 0, sizeof(f));
3182     memset(&ssn, 0, sizeof(ssn));
3183 
3184     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3185     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3186 
3187     FLOW_INITIALIZE(&f);
3188     f.protoctx = (void *)&ssn;
3189     f.proto = IPPROTO_TCP;
3190     f.flags |= FLOW_IPV4;
3191 
3192     p1->flow = &f;
3193     p1->flowflags |= FLOW_PKT_TOSERVER;
3194     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3195     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3196     p2->flow = &f;
3197     p2->flowflags |= FLOW_PKT_TOSERVER;
3198     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3199     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3200     f.alproto = ALPROTO_HTTP;
3201 
3202     StreamTcpInitConfig(TRUE);
3203 
3204     de_ctx = DetectEngineCtxInit();
3205     if (de_ctx == NULL)
3206         goto end;
3207 
3208     de_ctx->flags |= DE_QUIET;
3209 
3210     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3211                                "(msg:\"http client body test\"; "
3212                                "pcre:/body1/H; "
3213                                "content:!\"dummy\"; http_header; within:7; "
3214                                "sid:1;)");
3215     if (de_ctx->sig_list == NULL)
3216         goto end;
3217 
3218     SigGroupBuild(de_ctx);
3219     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3220 
3221     FLOWLOCK_WRLOCK(&f);
3222     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3223                                 STREAM_TOSERVER, http1_buf, http1_len);
3224     if (r != 0) {
3225         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3226         result = 0;
3227         FLOWLOCK_UNLOCK(&f);
3228         goto end;
3229     }
3230     FLOWLOCK_UNLOCK(&f);
3231 
3232     http_state = f.alstate;
3233     if (http_state == NULL) {
3234         printf("no http state: \n");
3235         result = 0;
3236         goto end;
3237     }
3238 
3239     /* do detect */
3240     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3241 
3242     if (PacketAlertCheck(p1, 1)) {
3243         printf("sid 1 matched but shouldn't have\n");
3244         goto end;
3245     }
3246 
3247     FLOWLOCK_WRLOCK(&f);
3248     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3249                             STREAM_TOSERVER, http2_buf, http2_len);
3250     if (r != 0) {
3251         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3252         result = 0;
3253         FLOWLOCK_UNLOCK(&f);
3254         goto end;
3255     }
3256     FLOWLOCK_UNLOCK(&f);
3257 
3258     /* do detect */
3259     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3260 
3261     if (!PacketAlertCheck(p2, 1)) {
3262         printf("sid 1 didn't match but shouldn't have");
3263         goto end;
3264     }
3265 
3266     result = 1;
3267 
3268 end:
3269     if (alp_tctx != NULL)
3270         AppLayerParserThreadCtxFree(alp_tctx);
3271     if (de_ctx != NULL)
3272         DetectEngineCtxFree(de_ctx);
3273 
3274     StreamTcpFreeConfig(TRUE);
3275     FLOW_DESTROY(&f);
3276     UTHFreePackets(&p1, 1);
3277     UTHFreePackets(&p2, 1);
3278     return result;
3279 }
3280 
DetectEngineHttpHeaderTest21(void)3281 static int DetectEngineHttpHeaderTest21(void)
3282 {
3283     TcpSession ssn;
3284     Packet *p1 = NULL;
3285     Packet *p2 = NULL;
3286     ThreadVars th_v;
3287     DetectEngineCtx *de_ctx = NULL;
3288     DetectEngineThreadCtx *det_ctx = NULL;
3289     HtpState *http_state = NULL;
3290     Flow f;
3291     uint8_t http1_buf[] =
3292         "GET /index.html HTTP/1.0\r\n"
3293         "Host: This_is_dummy_body1";
3294     uint8_t http2_buf[] =
3295         "This_is_dummy_message_body2\r\n"
3296         "\r\n";
3297     uint32_t http1_len = sizeof(http1_buf) - 1;
3298     uint32_t http2_len = sizeof(http2_buf) - 1;
3299     int result = 0;
3300     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3301 
3302     memset(&th_v, 0, sizeof(th_v));
3303     memset(&f, 0, sizeof(f));
3304     memset(&ssn, 0, sizeof(ssn));
3305 
3306     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3307     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3308 
3309     FLOW_INITIALIZE(&f);
3310     f.protoctx = (void *)&ssn;
3311     f.proto = IPPROTO_TCP;
3312     f.flags |= FLOW_IPV4;
3313 
3314     p1->flow = &f;
3315     p1->flowflags |= FLOW_PKT_TOSERVER;
3316     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3317     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3318     p2->flow = &f;
3319     p2->flowflags |= FLOW_PKT_TOSERVER;
3320     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3321     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3322     f.alproto = ALPROTO_HTTP;
3323 
3324     StreamTcpInitConfig(TRUE);
3325 
3326     de_ctx = DetectEngineCtxInit();
3327     if (de_ctx == NULL)
3328         goto end;
3329 
3330     de_ctx->flags |= DE_QUIET;
3331 
3332     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3333                                "(msg:\"http client body test\"; "
3334                                "pcre:/body1/H; "
3335                                "content:!\"dummy\"; within:7; http_header; "
3336                                "sid:1;)");
3337     if (de_ctx->sig_list == NULL)
3338         goto end;
3339 
3340     SigGroupBuild(de_ctx);
3341     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3342 
3343     FLOWLOCK_WRLOCK(&f);
3344     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3345                                 STREAM_TOSERVER, http1_buf, http1_len);
3346     if (r != 0) {
3347         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3348         result = 0;
3349         FLOWLOCK_UNLOCK(&f);
3350         goto end;
3351     }
3352     FLOWLOCK_UNLOCK(&f);
3353 
3354     http_state = f.alstate;
3355     if (http_state == NULL) {
3356         printf("no http state: \n");
3357         result = 0;
3358         goto end;
3359     }
3360 
3361     /* do detect */
3362     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3363 
3364     if (PacketAlertCheck(p1, 1)) {
3365         printf("sid 1 matched but shouldn't have\n");
3366         goto end;
3367     }
3368 
3369     FLOWLOCK_WRLOCK(&f);
3370     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3371                             STREAM_TOSERVER, http2_buf, http2_len);
3372     if (r != 0) {
3373         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3374         result = 0;
3375         FLOWLOCK_UNLOCK(&f);
3376         goto end;
3377     }
3378     FLOWLOCK_UNLOCK(&f);
3379 
3380     /* do detect */
3381     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3382 
3383     if (!PacketAlertCheck(p2, 1)) {
3384         printf("sid 1 didn't match but shouldn't have");
3385         goto end;
3386     }
3387 
3388     result = 1;
3389 
3390 end:
3391     if (alp_tctx != NULL)
3392         AppLayerParserThreadCtxFree(alp_tctx);
3393     if (de_ctx != NULL)
3394         DetectEngineCtxFree(de_ctx);
3395 
3396     StreamTcpFreeConfig(TRUE);
3397     FLOW_DESTROY(&f);
3398     UTHFreePackets(&p1, 1);
3399     UTHFreePackets(&p2, 1);
3400     return result;
3401 }
3402 
DetectEngineHttpHeaderTest22(void)3403 static int DetectEngineHttpHeaderTest22(void)
3404 {
3405     TcpSession ssn;
3406     Packet *p1 = NULL;
3407     Packet *p2 = NULL;
3408     ThreadVars th_v;
3409     DetectEngineCtx *de_ctx = NULL;
3410     DetectEngineThreadCtx *det_ctx = NULL;
3411     HtpState *http_state = NULL;
3412     Flow f;
3413     uint8_t http1_buf[] =
3414         "GET /index.html HTTP/1.0\r\n"
3415         "Host: This_is_dummy_body1";
3416     uint8_t http2_buf[] =
3417         "This_is_dummy_message_body2\r\n"
3418         "\r\n";
3419     uint32_t http1_len = sizeof(http1_buf) - 1;
3420     uint32_t http2_len = sizeof(http2_buf) - 1;
3421     int result = 0;
3422     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3423 
3424     memset(&th_v, 0, sizeof(th_v));
3425     memset(&f, 0, sizeof(f));
3426     memset(&ssn, 0, sizeof(ssn));
3427 
3428     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3429     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3430 
3431     FLOW_INITIALIZE(&f);
3432     f.protoctx = (void *)&ssn;
3433     f.proto = IPPROTO_TCP;
3434     f.flags |= FLOW_IPV4;
3435 
3436     p1->flow = &f;
3437     p1->flowflags |= FLOW_PKT_TOSERVER;
3438     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3439     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3440     p2->flow = &f;
3441     p2->flowflags |= FLOW_PKT_TOSERVER;
3442     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3443     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3444     f.alproto = ALPROTO_HTTP;
3445 
3446     StreamTcpInitConfig(TRUE);
3447 
3448     de_ctx = DetectEngineCtxInit();
3449     if (de_ctx == NULL)
3450         goto end;
3451 
3452     de_ctx->flags |= DE_QUIET;
3453 
3454     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3455                                "(msg:\"http client body test\"; "
3456                                "pcre:/body1/H; "
3457                                "content:!\"dummy\"; distance:3; http_header; "
3458                                "sid:1;)");
3459     if (de_ctx->sig_list == NULL)
3460         goto end;
3461 
3462     SigGroupBuild(de_ctx);
3463     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3464 
3465     FLOWLOCK_WRLOCK(&f);
3466     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3467                                 STREAM_TOSERVER, http1_buf, http1_len);
3468     if (r != 0) {
3469         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3470         result = 0;
3471         FLOWLOCK_UNLOCK(&f);
3472         goto end;
3473     }
3474     FLOWLOCK_UNLOCK(&f);
3475 
3476     http_state = f.alstate;
3477     if (http_state == NULL) {
3478         printf("no http state: \n");
3479         result = 0;
3480         goto end;
3481     }
3482 
3483     /* do detect */
3484     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3485 
3486     if (PacketAlertCheck(p1, 1)) {
3487         printf("sid 1 matched but shouldn't have\n");
3488         goto end;
3489     }
3490 
3491     FLOWLOCK_WRLOCK(&f);
3492     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3493                             STREAM_TOSERVER, http2_buf, http2_len);
3494     if (r != 0) {
3495         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3496         result = 0;
3497         FLOWLOCK_UNLOCK(&f);
3498         goto end;
3499     }
3500     FLOWLOCK_UNLOCK(&f);
3501 
3502     /* do detect */
3503     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3504 
3505     if (PacketAlertCheck(p2, 1)) {
3506         printf("sid 1 matched but shouldn't have");
3507         goto end;
3508     }
3509 
3510     result = 1;
3511 
3512 end:
3513     if (alp_tctx != NULL)
3514         AppLayerParserThreadCtxFree(alp_tctx);
3515     if (de_ctx != NULL)
3516         DetectEngineCtxFree(de_ctx);
3517 
3518     StreamTcpFreeConfig(TRUE);
3519     FLOW_DESTROY(&f);
3520     UTHFreePackets(&p1, 1);
3521     UTHFreePackets(&p2, 1);
3522     return result;
3523 }
3524 
DetectEngineHttpHeaderTest23(void)3525 static int DetectEngineHttpHeaderTest23(void)
3526 {
3527     TcpSession ssn;
3528     Packet *p1 = NULL;
3529     Packet *p2 = NULL;
3530     ThreadVars th_v;
3531     DetectEngineCtx *de_ctx = NULL;
3532     DetectEngineThreadCtx *det_ctx = NULL;
3533     HtpState *http_state = NULL;
3534     Flow f;
3535     uint8_t http1_buf[] =
3536         "GET /index.html HTTP/1.0\r\n"
3537         "Host: This_is_dummy_body1";
3538     uint8_t http2_buf[] =
3539         "This_is_dummy_message_body2\r\n"
3540         "\r\n";
3541     uint32_t http1_len = sizeof(http1_buf) - 1;
3542     uint32_t http2_len = sizeof(http2_buf) - 1;
3543     int result = 0;
3544     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3545 
3546     memset(&th_v, 0, sizeof(th_v));
3547     memset(&f, 0, sizeof(f));
3548     memset(&ssn, 0, sizeof(ssn));
3549 
3550     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3551     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3552 
3553     FLOW_INITIALIZE(&f);
3554     f.protoctx = (void *)&ssn;
3555     f.proto = IPPROTO_TCP;
3556     f.flags |= FLOW_IPV4;
3557 
3558     p1->flow = &f;
3559     p1->flowflags |= FLOW_PKT_TOSERVER;
3560     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3561     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3562     p2->flow = &f;
3563     p2->flowflags |= FLOW_PKT_TOSERVER;
3564     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3565     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3566     f.alproto = ALPROTO_HTTP;
3567 
3568     StreamTcpInitConfig(TRUE);
3569 
3570     de_ctx = DetectEngineCtxInit();
3571     if (de_ctx == NULL)
3572         goto end;
3573 
3574     de_ctx->flags |= DE_QUIET;
3575 
3576     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3577                                "(msg:\"http client body test\"; "
3578                                "pcre:/body1/H; "
3579                                "content:!\"dummy\"; distance:13; http_header; "
3580                                "sid:1;)");
3581     if (de_ctx->sig_list == NULL)
3582         goto end;
3583 
3584     SigGroupBuild(de_ctx);
3585     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3586 
3587     FLOWLOCK_WRLOCK(&f);
3588     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3589                                 STREAM_TOSERVER, http1_buf, http1_len);
3590     if (r != 0) {
3591         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3592         result = 0;
3593         FLOWLOCK_UNLOCK(&f);
3594         goto end;
3595     }
3596     FLOWLOCK_UNLOCK(&f);
3597 
3598     http_state = f.alstate;
3599     if (http_state == NULL) {
3600         printf("no http state: \n");
3601         result = 0;
3602         goto end;
3603     }
3604 
3605     /* do detect */
3606     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3607 
3608     if (PacketAlertCheck(p1, 1)) {
3609         printf("sid 1 matched but shouldn't have\n");
3610         goto end;
3611     }
3612 
3613     FLOWLOCK_WRLOCK(&f);
3614     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3615                             STREAM_TOSERVER, http2_buf, http2_len);
3616     if (r != 0) {
3617         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3618         result = 0;
3619         FLOWLOCK_UNLOCK(&f);
3620         goto end;
3621     }
3622     FLOWLOCK_UNLOCK(&f);
3623 
3624     /* do detect */
3625     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3626 
3627     if (!PacketAlertCheck(p2, 1)) {
3628         printf("sid 1 didn't match but should have");
3629         goto end;
3630     }
3631 
3632     result = 1;
3633 
3634 end:
3635     if (alp_tctx != NULL)
3636         AppLayerParserThreadCtxFree(alp_tctx);
3637     if (de_ctx != NULL)
3638         DetectEngineCtxFree(de_ctx);
3639 
3640     StreamTcpFreeConfig(TRUE);
3641     FLOW_DESTROY(&f);
3642     UTHFreePackets(&p1, 1);
3643     UTHFreePackets(&p2, 1);
3644     return result;
3645 }
3646 
DetectEngineHttpHeaderTest24(void)3647 static int DetectEngineHttpHeaderTest24(void)
3648 {
3649     TcpSession ssn;
3650     Packet *p1 = NULL;
3651     Packet *p2 = NULL;
3652     ThreadVars th_v;
3653     DetectEngineCtx *de_ctx = NULL;
3654     DetectEngineThreadCtx *det_ctx = NULL;
3655     HtpState *http_state = NULL;
3656     Flow f;
3657     uint8_t http1_buf[] =
3658         "GET /index.html HTTP/1.0\r\n"
3659         "Host: This_is_dummy_body1";
3660     uint8_t http2_buf[] =
3661         "This_is_dummy_message_body2\r\n"
3662         "\r\n";
3663     uint32_t http1_len = sizeof(http1_buf) - 1;
3664     uint32_t http2_len = sizeof(http2_buf) - 1;
3665     int result = 0;
3666     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3667 
3668     memset(&th_v, 0, sizeof(th_v));
3669     memset(&f, 0, sizeof(f));
3670     memset(&ssn, 0, sizeof(ssn));
3671 
3672     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3673     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3674 
3675     FLOW_INITIALIZE(&f);
3676     f.protoctx = (void *)&ssn;
3677     f.proto = IPPROTO_TCP;
3678     f.flags |= FLOW_IPV4;
3679 
3680     p1->flow = &f;
3681     p1->flowflags |= FLOW_PKT_TOSERVER;
3682     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3683     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3684     p2->flow = &f;
3685     p2->flowflags |= FLOW_PKT_TOSERVER;
3686     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3687     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3688     f.alproto = ALPROTO_HTTP;
3689 
3690     StreamTcpInitConfig(TRUE);
3691 
3692     de_ctx = DetectEngineCtxInit();
3693     if (de_ctx == NULL)
3694         goto end;
3695 
3696     de_ctx->flags |= DE_QUIET;
3697 
3698     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3699                                "(msg:\"http client body test\"; "
3700                                "pcre:/body1/H; "
3701                                "content:\"dummy\"; within:15; http_header; "
3702                                "sid:1;)");
3703     if (de_ctx->sig_list == NULL)
3704         goto end;
3705 
3706     SigGroupBuild(de_ctx);
3707     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3708 
3709     FLOWLOCK_WRLOCK(&f);
3710     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3711                                 STREAM_TOSERVER, http1_buf, http1_len);
3712     if (r != 0) {
3713         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3714         result = 0;
3715         FLOWLOCK_UNLOCK(&f);
3716         goto end;
3717     }
3718     FLOWLOCK_UNLOCK(&f);
3719 
3720     http_state = f.alstate;
3721     if (http_state == NULL) {
3722         printf("no http state: \n");
3723         result = 0;
3724         goto end;
3725     }
3726 
3727     /* do detect */
3728     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3729 
3730     if (PacketAlertCheck(p1, 1)) {
3731         printf("sid 1 matched but shouldn't have\n");
3732         goto end;
3733     }
3734 
3735     FLOWLOCK_WRLOCK(&f);
3736     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3737                             STREAM_TOSERVER, http2_buf, http2_len);
3738     if (r != 0) {
3739         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3740         result = 0;
3741         FLOWLOCK_UNLOCK(&f);
3742         goto end;
3743     }
3744     FLOWLOCK_UNLOCK(&f);
3745 
3746     /* do detect */
3747     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3748 
3749     if (!PacketAlertCheck(p2, 1)) {
3750         printf("sid 1 didn't match but should have");
3751         goto end;
3752     }
3753 
3754     result = 1;
3755 
3756 end:
3757     if (alp_tctx != NULL)
3758         AppLayerParserThreadCtxFree(alp_tctx);
3759     if (de_ctx != NULL)
3760         DetectEngineCtxFree(de_ctx);
3761 
3762     StreamTcpFreeConfig(TRUE);
3763     FLOW_DESTROY(&f);
3764     UTHFreePackets(&p1, 1);
3765     UTHFreePackets(&p2, 1);
3766     return result;
3767 }
3768 
DetectEngineHttpHeaderTest25(void)3769 static int DetectEngineHttpHeaderTest25(void)
3770 {
3771     TcpSession ssn;
3772     Packet *p1 = NULL;
3773     Packet *p2 = NULL;
3774     ThreadVars th_v;
3775     DetectEngineCtx *de_ctx = NULL;
3776     DetectEngineThreadCtx *det_ctx = NULL;
3777     HtpState *http_state = NULL;
3778     Flow f;
3779     uint8_t http1_buf[] =
3780         "GET /index.html HTTP/1.0\r\n"
3781         "Host: This_is_dummy_body1";
3782     uint8_t http2_buf[] =
3783         "This_is_dummy_message_body2\r\n"
3784         "\r\n";
3785     uint32_t http1_len = sizeof(http1_buf) - 1;
3786     uint32_t http2_len = sizeof(http2_buf) - 1;
3787     int result = 0;
3788     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3789 
3790     memset(&th_v, 0, sizeof(th_v));
3791     memset(&f, 0, sizeof(f));
3792     memset(&ssn, 0, sizeof(ssn));
3793 
3794     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3795     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3796 
3797     FLOW_INITIALIZE(&f);
3798     f.protoctx = (void *)&ssn;
3799     f.proto = IPPROTO_TCP;
3800     f.flags |= FLOW_IPV4;
3801 
3802     p1->flow = &f;
3803     p1->flowflags |= FLOW_PKT_TOSERVER;
3804     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3805     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3806     p2->flow = &f;
3807     p2->flowflags |= FLOW_PKT_TOSERVER;
3808     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3809     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3810     f.alproto = ALPROTO_HTTP;
3811 
3812     StreamTcpInitConfig(TRUE);
3813 
3814     de_ctx = DetectEngineCtxInit();
3815     if (de_ctx == NULL)
3816         goto end;
3817 
3818     de_ctx->flags |= DE_QUIET;
3819 
3820     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3821                                "(msg:\"http client body test\"; "
3822                                "pcre:/body1/H; "
3823                                "content:\"dummy\"; within:10; http_header; "
3824                                "sid:1;)");
3825     if (de_ctx->sig_list == NULL)
3826         goto end;
3827 
3828     SigGroupBuild(de_ctx);
3829     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3830 
3831     FLOWLOCK_WRLOCK(&f);
3832     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3833                                 STREAM_TOSERVER, http1_buf, http1_len);
3834     if (r != 0) {
3835         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3836         result = 0;
3837         FLOWLOCK_UNLOCK(&f);
3838         goto end;
3839     }
3840     FLOWLOCK_UNLOCK(&f);
3841 
3842     http_state = f.alstate;
3843     if (http_state == NULL) {
3844         printf("no http state: \n");
3845         result = 0;
3846         goto end;
3847     }
3848 
3849     /* do detect */
3850     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3851 
3852     if (PacketAlertCheck(p1, 1)) {
3853         printf("sid 1 matched but shouldn't have\n");
3854         goto end;
3855     }
3856 
3857     FLOWLOCK_WRLOCK(&f);
3858     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3859                             STREAM_TOSERVER, http2_buf, http2_len);
3860     if (r != 0) {
3861         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3862         result = 0;
3863         FLOWLOCK_UNLOCK(&f);
3864         goto end;
3865     }
3866     FLOWLOCK_UNLOCK(&f);
3867 
3868     /* do detect */
3869     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3870 
3871     if (PacketAlertCheck(p2, 1)) {
3872         printf("sid 1 matched but shouldn't have");
3873         goto end;
3874     }
3875 
3876     result = 1;
3877 
3878 end:
3879     if (alp_tctx != NULL)
3880         AppLayerParserThreadCtxFree(alp_tctx);
3881     if (de_ctx != NULL)
3882         DetectEngineCtxFree(de_ctx);
3883 
3884     StreamTcpFreeConfig(TRUE);
3885     FLOW_DESTROY(&f);
3886     UTHFreePackets(&p1, 1);
3887     UTHFreePackets(&p2, 1);
3888     return result;
3889 }
3890 
DetectEngineHttpHeaderTest26(void)3891 static int DetectEngineHttpHeaderTest26(void)
3892 {
3893     TcpSession ssn;
3894     Packet *p1 = NULL;
3895     Packet *p2 = NULL;
3896     ThreadVars th_v;
3897     DetectEngineCtx *de_ctx = NULL;
3898     DetectEngineThreadCtx *det_ctx = NULL;
3899     HtpState *http_state = NULL;
3900     Flow f;
3901     uint8_t http1_buf[] =
3902         "GET /index.html HTTP/1.0\r\n"
3903         "Host: This_is_dummy_body1";
3904     uint8_t http2_buf[] =
3905         "This_is_dummy_message_body2\r\n"
3906         "\r\n";
3907     uint32_t http1_len = sizeof(http1_buf) - 1;
3908     uint32_t http2_len = sizeof(http2_buf) - 1;
3909     int result = 0;
3910     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
3911 
3912     memset(&th_v, 0, sizeof(th_v));
3913     memset(&f, 0, sizeof(f));
3914     memset(&ssn, 0, sizeof(ssn));
3915 
3916     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3917     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
3918 
3919     FLOW_INITIALIZE(&f);
3920     f.protoctx = (void *)&ssn;
3921     f.proto = IPPROTO_TCP;
3922     f.flags |= FLOW_IPV4;
3923 
3924     p1->flow = &f;
3925     p1->flowflags |= FLOW_PKT_TOSERVER;
3926     p1->flowflags |= FLOW_PKT_ESTABLISHED;
3927     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3928     p2->flow = &f;
3929     p2->flowflags |= FLOW_PKT_TOSERVER;
3930     p2->flowflags |= FLOW_PKT_ESTABLISHED;
3931     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3932     f.alproto = ALPROTO_HTTP;
3933 
3934     StreamTcpInitConfig(TRUE);
3935 
3936     de_ctx = DetectEngineCtxInit();
3937     if (de_ctx == NULL)
3938         goto end;
3939 
3940     de_ctx->flags |= DE_QUIET;
3941 
3942     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
3943                                "(msg:\"http client body test\"; "
3944                                "pcre:/body1/H; "
3945                                "content:\"dummy\"; distance:8; http_header; "
3946                                "sid:1;)");
3947     if (de_ctx->sig_list == NULL)
3948         goto end;
3949 
3950     SigGroupBuild(de_ctx);
3951     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
3952 
3953     FLOWLOCK_WRLOCK(&f);
3954     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3955                                 STREAM_TOSERVER, http1_buf, http1_len);
3956     if (r != 0) {
3957         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3958         result = 0;
3959         FLOWLOCK_UNLOCK(&f);
3960         goto end;
3961     }
3962     FLOWLOCK_UNLOCK(&f);
3963 
3964     http_state = f.alstate;
3965     if (http_state == NULL) {
3966         printf("no http state: \n");
3967         result = 0;
3968         goto end;
3969     }
3970 
3971     /* do detect */
3972     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
3973 
3974     if (PacketAlertCheck(p1, 1)) {
3975         printf("sid 1 matched but shouldn't have\n");
3976         goto end;
3977     }
3978 
3979     FLOWLOCK_WRLOCK(&f);
3980     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
3981                             STREAM_TOSERVER, http2_buf, http2_len);
3982     if (r != 0) {
3983         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
3984         result = 0;
3985         FLOWLOCK_UNLOCK(&f);
3986         goto end;
3987     }
3988     FLOWLOCK_UNLOCK(&f);
3989 
3990     /* do detect */
3991     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
3992 
3993     if (!PacketAlertCheck(p2, 1)) {
3994         printf("sid 1 didn't match but should have");
3995         goto end;
3996     }
3997 
3998     result = 1;
3999 
4000 end:
4001     if (alp_tctx != NULL)
4002         AppLayerParserThreadCtxFree(alp_tctx);
4003     if (de_ctx != NULL)
4004         DetectEngineCtxFree(de_ctx);
4005 
4006     StreamTcpFreeConfig(TRUE);
4007     FLOW_DESTROY(&f);
4008     UTHFreePackets(&p1, 1);
4009     UTHFreePackets(&p2, 1);
4010     return result;
4011 }
4012 
DetectEngineHttpHeaderTest27(void)4013 static int DetectEngineHttpHeaderTest27(void)
4014 {
4015     TcpSession ssn;
4016     Packet *p1 = NULL;
4017     Packet *p2 = NULL;
4018     ThreadVars th_v;
4019     DetectEngineCtx *de_ctx = NULL;
4020     DetectEngineThreadCtx *det_ctx = NULL;
4021     HtpState *http_state = NULL;
4022     Flow f;
4023     uint8_t http1_buf[] =
4024         "GET /index.html HTTP/1.0\r\n"
4025         "Host: This_is_dummy_body1";
4026     uint8_t http2_buf[] =
4027         "This_is_dummy_message_body2\r\n"
4028         "\r\n";
4029     uint32_t http1_len = sizeof(http1_buf) - 1;
4030     uint32_t http2_len = sizeof(http2_buf) - 1;
4031     int result = 0;
4032     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4033 
4034     memset(&th_v, 0, sizeof(th_v));
4035     memset(&f, 0, sizeof(f));
4036     memset(&ssn, 0, sizeof(ssn));
4037 
4038     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4039     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4040 
4041     FLOW_INITIALIZE(&f);
4042     f.protoctx = (void *)&ssn;
4043     f.proto = IPPROTO_TCP;
4044     f.flags |= FLOW_IPV4;
4045 
4046     p1->flow = &f;
4047     p1->flowflags |= FLOW_PKT_TOSERVER;
4048     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4049     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4050     p2->flow = &f;
4051     p2->flowflags |= FLOW_PKT_TOSERVER;
4052     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4053     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4054     f.alproto = ALPROTO_HTTP;
4055 
4056     StreamTcpInitConfig(TRUE);
4057 
4058     de_ctx = DetectEngineCtxInit();
4059     if (de_ctx == NULL)
4060         goto end;
4061 
4062     de_ctx->flags |= DE_QUIET;
4063 
4064     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4065                                "(msg:\"http client body test\"; "
4066                                "pcre:/body1/H; "
4067                                "content:\"dummy\"; distance:14; http_header; "
4068                                "sid:1;)");
4069     if (de_ctx->sig_list == NULL)
4070         goto end;
4071 
4072     SigGroupBuild(de_ctx);
4073     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4074 
4075     FLOWLOCK_WRLOCK(&f);
4076     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4077                                 STREAM_TOSERVER, http1_buf, http1_len);
4078     if (r != 0) {
4079         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4080         result = 0;
4081         FLOWLOCK_UNLOCK(&f);
4082         goto end;
4083     }
4084     FLOWLOCK_UNLOCK(&f);
4085 
4086     http_state = f.alstate;
4087     if (http_state == NULL) {
4088         printf("no http state: \n");
4089         result = 0;
4090         goto end;
4091     }
4092 
4093     /* do detect */
4094     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4095 
4096     if (PacketAlertCheck(p1, 1)) {
4097         printf("sid 1 matched but shouldn't have\n");
4098         goto end;
4099     }
4100 
4101     FLOWLOCK_WRLOCK(&f);
4102     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4103                             STREAM_TOSERVER, http2_buf, http2_len);
4104     if (r != 0) {
4105         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4106         result = 0;
4107         FLOWLOCK_UNLOCK(&f);
4108         goto end;
4109     }
4110     FLOWLOCK_UNLOCK(&f);
4111 
4112     /* do detect */
4113     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4114 
4115     if (PacketAlertCheck(p2, 1)) {
4116         printf("sid 1 matched but shouldn't have");
4117         goto end;
4118     }
4119 
4120     result = 1;
4121 
4122 end:
4123     if (alp_tctx != NULL)
4124         AppLayerParserThreadCtxFree(alp_tctx);
4125     if (de_ctx != NULL)
4126         DetectEngineCtxFree(de_ctx);
4127 
4128     StreamTcpFreeConfig(TRUE);
4129     FLOW_DESTROY(&f);
4130     UTHFreePackets(&p1, 1);
4131     UTHFreePackets(&p2, 1);
4132     return result;
4133 }
4134 
DetectEngineHttpHeaderTest28(void)4135 static int DetectEngineHttpHeaderTest28(void)
4136 {
4137     TcpSession ssn;
4138     Packet *p1 = NULL;
4139     Packet *p2 = NULL;
4140     ThreadVars th_v;
4141     DetectEngineCtx *de_ctx = NULL;
4142     DetectEngineThreadCtx *det_ctx = NULL;
4143     HtpState *http_state = NULL;
4144     Flow f;
4145     uint8_t http_buf1[] =
4146         "GET /index.html HTTP/1.0\r\n"
4147         "Host: www.openinfosecfoundation.org\r\n"
4148         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4149         "\r\n";
4150     uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4151     uint8_t http_buf2[] =
4152         "HTTP/1.0 200 ok\r\n"
4153         "Content-Type: text/html\r\n"
4154         "Content-Length: 6\r\n"
4155         "\r\n"
4156         "abcdef";
4157     uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4158     int result = 0;
4159     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4160 
4161     memset(&th_v, 0, sizeof(th_v));
4162     memset(&f, 0, sizeof(f));
4163     memset(&ssn, 0, sizeof(ssn));
4164 
4165     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4166     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4167 
4168     FLOW_INITIALIZE(&f);
4169     f.protoctx = (void *)&ssn;
4170     f.proto = IPPROTO_TCP;
4171     f.flags |= FLOW_IPV4;
4172 
4173     p1->flow = &f;
4174     p1->flowflags |= FLOW_PKT_TOSERVER;
4175     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4176     p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4177     p2->flow = &f;
4178     p2->flowflags |= FLOW_PKT_TOCLIENT;
4179     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4180     p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4181     f.alproto = ALPROTO_HTTP;
4182 
4183     StreamTcpInitConfig(TRUE);
4184 
4185     de_ctx = DetectEngineCtxInit();
4186     if (de_ctx == NULL)
4187         goto end;
4188 
4189     de_ctx->flags |= DE_QUIET;
4190 
4191     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4192                                "(msg:\"http header test\"; "
4193                                "content:\"Content-Length: 6\"; http_header; "
4194                                "sid:1;)");
4195     if (de_ctx->sig_list == NULL)
4196         goto end;
4197 
4198     SigGroupBuild(de_ctx);
4199     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4200 
4201     FLOWLOCK_WRLOCK(&f);
4202     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4203                                 STREAM_TOSERVER, http_buf1, http_buf1_len);
4204     if (r != 0) {
4205         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4206         result = 0;
4207         FLOWLOCK_UNLOCK(&f);
4208         goto end;
4209     }
4210     FLOWLOCK_UNLOCK(&f);
4211 
4212     http_state = f.alstate;
4213     if (http_state == NULL) {
4214         printf("no http state: \n");
4215         result = 0;
4216         goto end;
4217     }
4218 
4219     /* do detect */
4220     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4221 
4222     if (PacketAlertCheck(p1, 1)) {
4223         printf("sid 1 matched but shouldn't have\n");
4224         goto end;
4225     }
4226 
4227     FLOWLOCK_WRLOCK(&f);
4228     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4229                             STREAM_TOCLIENT, http_buf2, http_buf2_len);
4230     if (r != 0) {
4231         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4232         result = 0;
4233         FLOWLOCK_UNLOCK(&f);
4234         goto end;
4235     }
4236     FLOWLOCK_UNLOCK(&f);
4237 
4238     /* do detect */
4239     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4240 
4241     FAIL_IF(!PacketAlertCheck(p2, 1));
4242 
4243     result = 1;
4244 
4245 end:
4246     if (alp_tctx != NULL)
4247         AppLayerParserThreadCtxFree(alp_tctx);
4248     if (de_ctx != NULL)
4249         DetectEngineCtxFree(de_ctx);
4250 
4251     StreamTcpFreeConfig(TRUE);
4252     FLOW_DESTROY(&f);
4253     UTHFreePackets(&p1, 1);
4254     UTHFreePackets(&p2, 1);
4255     return result;
4256 }
4257 
DetectEngineHttpHeaderTest29(void)4258 static int DetectEngineHttpHeaderTest29(void)
4259 {
4260     TcpSession ssn;
4261     Packet *p1 = NULL;
4262     Packet *p2 = NULL;
4263     ThreadVars th_v;
4264     DetectEngineCtx *de_ctx = NULL;
4265     DetectEngineThreadCtx *det_ctx = NULL;
4266     HtpState *http_state = NULL;
4267     Flow f;
4268     uint8_t http_buf1[] =
4269         "GET /index.html HTTP/1.0\r\n"
4270         "Host: www.openinfosecfoundation.org\r\n"
4271         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4272         "\r\n";
4273     uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4274     uint8_t http_buf2[] =
4275         "HTTP/1.0 200 ok\r\n"
4276         "Content-Type: text/html\r\n"
4277         "Content-Length: 6\r\n"
4278         "\r\n"
4279         "abcdef";
4280     uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4281     int result = 0;
4282     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4283 
4284     memset(&th_v, 0, sizeof(th_v));
4285     memset(&f, 0, sizeof(f));
4286     memset(&ssn, 0, sizeof(ssn));
4287 
4288     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4289     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4290 
4291     FLOW_INITIALIZE(&f);
4292     f.protoctx = (void *)&ssn;
4293     f.proto = IPPROTO_TCP;
4294     f.flags |= FLOW_IPV4;
4295 
4296     p1->flow = &f;
4297     p1->flowflags |= FLOW_PKT_TOSERVER;
4298     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4299     p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4300     p2->flow = &f;
4301     p2->flowflags |= FLOW_PKT_TOCLIENT;
4302     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4303     p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4304     f.alproto = ALPROTO_HTTP;
4305 
4306     StreamTcpInitConfig(TRUE);
4307 
4308     de_ctx = DetectEngineCtxInit();
4309     if (de_ctx == NULL)
4310         goto end;
4311 
4312     de_ctx->flags |= DE_QUIET;
4313 
4314     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4315                                "(msg:\"http header test\"; "
4316                                "content:\"Content-Length: 7\"; http_header; "
4317                                "sid:1;)");
4318     if (de_ctx->sig_list == NULL)
4319         goto end;
4320 
4321     SigGroupBuild(de_ctx);
4322     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4323 
4324     FLOWLOCK_WRLOCK(&f);
4325     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4326                                 STREAM_TOSERVER, http_buf1, http_buf1_len);
4327     if (r != 0) {
4328         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4329         result = 0;
4330         FLOWLOCK_UNLOCK(&f);
4331         goto end;
4332     }
4333     FLOWLOCK_UNLOCK(&f);
4334 
4335     http_state = f.alstate;
4336     if (http_state == NULL) {
4337         printf("no http state: \n");
4338         result = 0;
4339         goto end;
4340     }
4341 
4342     /* do detect */
4343     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4344 
4345     if (PacketAlertCheck(p1, 1)) {
4346         printf("sid 1 matched but shouldn't have\n");
4347         goto end;
4348     }
4349 
4350     FLOWLOCK_WRLOCK(&f);
4351     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4352                             STREAM_TOCLIENT, http_buf2, http_buf2_len);
4353     if (r != 0) {
4354         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4355         result = 0;
4356         FLOWLOCK_UNLOCK(&f);
4357         goto end;
4358     }
4359     FLOWLOCK_UNLOCK(&f);
4360 
4361     /* do detect */
4362     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4363 
4364     if (PacketAlertCheck(p2, 1)) {
4365         printf("sid 1 matched but shouldn't have");
4366         goto end;
4367     }
4368 
4369     result = 1;
4370 
4371 end:
4372     if (alp_tctx != NULL)
4373         AppLayerParserThreadCtxFree(alp_tctx);
4374     if (de_ctx != NULL)
4375         DetectEngineCtxFree(de_ctx);
4376 
4377     StreamTcpFreeConfig(TRUE);
4378     FLOW_DESTROY(&f);
4379     UTHFreePackets(&p1, 1);
4380     UTHFreePackets(&p2, 1);
4381     return result;
4382 }
4383 
4384 #if 0
4385 
4386 static int DetectEngineHttpHeaderTest30(void)
4387 {
4388     int result = 0;
4389     DetectEngineCtx *de_ctx = DetectEngineCtxInit();
4390 
4391     if (de_ctx == NULL) {
4392         goto end;
4393     }
4394 
4395     de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
4396                                "(msg:\"http header test\"; "
4397                                "content:\"Content-Length: 6\"; http_header; "
4398                                "content:\"User-Agent: Mozilla\"; http_header; "
4399                                "sid:1;)");
4400     if (de_ctx->sig_list != NULL) {
4401         goto end;
4402     }
4403 
4404     result = 1;
4405 
4406  end:
4407     if (de_ctx != NULL)
4408         DetectEngineCtxFree(de_ctx);
4409     return result;
4410 }
4411 
4412 #endif /* #if 0 */
4413 
DetectEngineHttpHeaderTest30(void)4414 static int DetectEngineHttpHeaderTest30(void)
4415 {
4416     TcpSession ssn;
4417     Packet *p1 = NULL;
4418     Packet *p2 = NULL;
4419     ThreadVars th_v;
4420     DetectEngineCtx *de_ctx = NULL;
4421     DetectEngineThreadCtx *det_ctx = NULL;
4422     HtpState *http_state = NULL;
4423     Flow f;
4424     uint8_t http_buf1[] =
4425         "GET /index.html HTTP/1.0\r\n"
4426         "Host: www.openinfosecfoundation.org\r\n"
4427         "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
4428         "\r\n";
4429     uint32_t http_buf1_len = sizeof(http_buf1) - 1;
4430     uint8_t http_buf2[] =
4431         "HTTP/1.0 200 ok\r\n"
4432         "Set-Cookie: dummycookieset\r\n"
4433         "Content-Type: text/html\r\n"
4434         "Content-Length: 6\r\n"
4435         "\r\n"
4436         "abcdef";
4437     uint32_t http_buf2_len = sizeof(http_buf2) - 1;
4438     int result = 0;
4439     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4440 
4441     memset(&th_v, 0, sizeof(th_v));
4442     memset(&f, 0, sizeof(f));
4443     memset(&ssn, 0, sizeof(ssn));
4444 
4445     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4446     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4447 
4448     FLOW_INITIALIZE(&f);
4449     f.protoctx = (void *)&ssn;
4450     f.proto = IPPROTO_TCP;
4451     f.flags |= FLOW_IPV4;
4452 
4453     p1->flow = &f;
4454     p1->flowflags |= FLOW_PKT_TOSERVER;
4455     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4456     p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4457     p2->flow = &f;
4458     p2->flowflags |= FLOW_PKT_TOCLIENT;
4459     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4460     p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
4461     f.alproto = ALPROTO_HTTP;
4462 
4463     StreamTcpInitConfig(TRUE);
4464 
4465     de_ctx = DetectEngineCtxInit();
4466     if (de_ctx == NULL)
4467         goto end;
4468 
4469     de_ctx->flags |= DE_QUIET;
4470 
4471     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4472                                "(msg:\"http header test\"; "
4473                                "content:\"dummycookieset\"; http_header; "
4474                                "sid:1;)");
4475     if (de_ctx->sig_list == NULL)
4476         goto end;
4477 
4478     SigGroupBuild(de_ctx);
4479     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4480 
4481     FLOWLOCK_WRLOCK(&f);
4482     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4483                                 STREAM_TOSERVER, http_buf1, http_buf1_len);
4484     if (r != 0) {
4485         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4486         result = 0;
4487         FLOWLOCK_UNLOCK(&f);
4488         goto end;
4489     }
4490     FLOWLOCK_UNLOCK(&f);
4491 
4492     http_state = f.alstate;
4493     if (http_state == NULL) {
4494         printf("no http state: \n");
4495         result = 0;
4496         goto end;
4497     }
4498 
4499     /* do detect */
4500     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4501 
4502     if (PacketAlertCheck(p1, 1)) {
4503         printf("sid 1 matched but shouldn't have\n");
4504         goto end;
4505     }
4506 
4507     FLOWLOCK_WRLOCK(&f);
4508     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4509                             STREAM_TOCLIENT, http_buf2, http_buf2_len);
4510     if (r != 0) {
4511         printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
4512         result = 0;
4513         FLOWLOCK_UNLOCK(&f);
4514         goto end;
4515     }
4516     FLOWLOCK_UNLOCK(&f);
4517 
4518     /* do detect */
4519     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4520 
4521     if (PacketAlertCheck(p2, 1)) {
4522         printf("sid 1 matched but shouldn't have\n");
4523         goto end;
4524     }
4525 
4526     result = 1;
4527 
4528 end:
4529     if (alp_tctx != NULL)
4530         AppLayerParserThreadCtxFree(alp_tctx);
4531     if (de_ctx != NULL)
4532         DetectEngineCtxFree(de_ctx);
4533 
4534     StreamTcpFreeConfig(TRUE);
4535     FLOW_DESTROY(&f);
4536     UTHFreePackets(&p1, 1);
4537     UTHFreePackets(&p2, 1);
4538     return result;
4539 }
4540 
4541 /** \test reassembly bug where headers with names of length 6 were
4542   *       skipped
4543   */
DetectEngineHttpHeaderTest31(void)4544 static int DetectEngineHttpHeaderTest31(void)
4545 {
4546     TcpSession ssn;
4547     Packet *p1 = NULL;
4548     ThreadVars th_v;
4549     DetectEngineCtx *de_ctx = NULL;
4550     DetectEngineThreadCtx *det_ctx = NULL;
4551     HtpState *http_state = NULL;
4552     Flow f;
4553     uint8_t http1_buf[] =
4554         "GET /index.html HTTP/1.0\r\n"
4555         "Accept: blah\r\n"
4556         "Cookie: blah\r\n"
4557         "Crazy6: blah\r\n"
4558         "SixZix: blah\r\n\r\n";
4559     uint32_t http1_len = sizeof(http1_buf) - 1;
4560     int result = 0;
4561     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4562 
4563     memset(&th_v, 0, sizeof(th_v));
4564     memset(&f, 0, sizeof(f));
4565     memset(&ssn, 0, sizeof(ssn));
4566 
4567     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4568 
4569     FLOW_INITIALIZE(&f);
4570     f.protoctx = (void *)&ssn;
4571     f.proto = IPPROTO_TCP;
4572     f.flags |= FLOW_IPV4;
4573 
4574     p1->flow = &f;
4575     p1->flowflags |= FLOW_PKT_TOSERVER;
4576     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4577     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4578     f.alproto = ALPROTO_HTTP;
4579 
4580     StreamTcpInitConfig(TRUE);
4581 
4582     de_ctx = DetectEngineCtxInit();
4583     if (de_ctx == NULL)
4584         goto end;
4585 
4586     de_ctx->flags |= DE_QUIET;
4587 
4588     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4589                                "(content:\"Accept|3a|\"; http_header; "
4590                                "content:!\"Cookie|3a|\"; http_header; "
4591                                "content:\"Crazy6|3a|\"; http_header; "
4592                                "content:\"SixZix|3a|\"; http_header; "
4593                                "sid:1;)");
4594     if (de_ctx->sig_list == NULL)
4595         goto end;
4596 
4597     SigGroupBuild(de_ctx);
4598     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4599 
4600     FLOWLOCK_WRLOCK(&f);
4601     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4602                                 STREAM_TOSERVER, http1_buf, http1_len);
4603     if (r != 0) {
4604         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4605         result = 0;
4606         FLOWLOCK_UNLOCK(&f);
4607         goto end;
4608     }
4609     FLOWLOCK_UNLOCK(&f);
4610 
4611     http_state = f.alstate;
4612     if (http_state == NULL) {
4613         printf("no http state: \n");
4614         result = 0;
4615         goto end;
4616     }
4617 
4618     /* do detect */
4619     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4620 
4621     if (!(PacketAlertCheck(p1, 1))) {
4622         printf("sid 1 didn't match but should have: ");
4623         goto end;
4624     }
4625 
4626     result = 1;
4627 
4628 end:
4629     if (alp_tctx != NULL)
4630         AppLayerParserThreadCtxFree(alp_tctx);
4631     if (de_ctx != NULL)
4632         DetectEngineCtxFree(de_ctx);
4633 
4634     StreamTcpFreeConfig(TRUE);
4635     FLOW_DESTROY(&f);
4636     UTHFreePackets(&p1, 1);
4637     return result;
4638 }
4639 
4640 /**
4641  * \test Trailing headers.
4642  */
DetectEngineHttpHeaderTest32(void)4643 static int DetectEngineHttpHeaderTest32(void)
4644 {
4645     TcpSession ssn;
4646     Packet *p1 = NULL;
4647     ThreadVars th_v;
4648     DetectEngineCtx *de_ctx = NULL;
4649     DetectEngineThreadCtx *det_ctx = NULL;
4650     HtpState *http_state = NULL;
4651     Flow f;
4652     uint8_t http1_buf[] =
4653         "GET /index.html HTTP/1.0\r\n"
4654         "host: boom\r\n"
4655         "Transfer-Encoding: chunked\r\n"
4656         "\r\n"
4657         "13\r\n"
4658         "This is dummy body1\r\n"
4659         "0\r\n"
4660         "Dummy-Header: kaboom\r\n"
4661         "\r\n";
4662     uint32_t http1_len = sizeof(http1_buf) - 1;
4663     int result = 0;
4664     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4665 
4666     memset(&th_v, 0, sizeof(th_v));
4667     memset(&f, 0, sizeof(f));
4668     memset(&ssn, 0, sizeof(ssn));
4669 
4670     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4671 
4672     FLOW_INITIALIZE(&f);
4673     f.protoctx = (void *)&ssn;
4674     f.proto = IPPROTO_TCP;
4675     f.flags |= FLOW_IPV4;
4676 
4677     p1->flow = &f;
4678     p1->flowflags |= FLOW_PKT_TOSERVER;
4679     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4680     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4681     f.alproto = ALPROTO_HTTP;
4682 
4683     StreamTcpInitConfig(TRUE);
4684 
4685     de_ctx = DetectEngineCtxInit();
4686     if (de_ctx == NULL)
4687         goto end;
4688 
4689     de_ctx->flags |= DE_QUIET;
4690 
4691     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4692                                "(content:\"Dummy\"; http_header; "
4693                                "sid:1;)");
4694     if (de_ctx->sig_list == NULL)
4695         goto end;
4696 
4697     SigGroupBuild(de_ctx);
4698     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4699 
4700     FLOWLOCK_WRLOCK(&f);
4701     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4702                                 STREAM_TOSERVER, http1_buf, http1_len);
4703     if (r != 0) {
4704         printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
4705         result = 0;
4706         FLOWLOCK_UNLOCK(&f);
4707         goto end;
4708     }
4709     FLOWLOCK_UNLOCK(&f);
4710 
4711     http_state = f.alstate;
4712     if (http_state == NULL) {
4713         printf("no http state: \n");
4714         result = 0;
4715         goto end;
4716     }
4717 
4718     /* do detect */
4719     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4720 
4721     if (!(PacketAlertCheck(p1, 1))) {
4722         printf("sid 1 didn't match but should have: ");
4723         goto end;
4724     }
4725 
4726     result = 1;
4727 
4728 end:
4729     if (alp_tctx != NULL)
4730         AppLayerParserThreadCtxFree(alp_tctx);
4731     if (de_ctx != NULL)
4732         DetectEngineCtxFree(de_ctx);
4733 
4734     StreamTcpFreeConfig(TRUE);
4735     FLOW_DESTROY(&f);
4736     UTHFreePackets(&p1, 1);
4737     return result;
4738 }
4739 
4740 /**
4741  * \test Trailing headers.
4742  */
DetectEngineHttpHeaderTest33(void)4743 static int DetectEngineHttpHeaderTest33(void)
4744 {
4745     TcpSession ssn;
4746     Packet *p1 = NULL;
4747     Packet *p2 = NULL;
4748     ThreadVars th_v;
4749     DetectEngineCtx *de_ctx = NULL;
4750     DetectEngineThreadCtx *det_ctx = NULL;
4751     HtpState *http_state = NULL;
4752     Flow f;
4753     uint8_t http1_buf[] =
4754         "GET /index.html HTTP/1.0\r\n"
4755         "host: boom\r\n"
4756         "Transfer-Encoding: chunked\r\n"
4757         "\r\n"
4758         "13\r\n"
4759         "This is dummy body1\r\n"
4760         "0\r\n";
4761     uint8_t http2_buf[] =
4762         "Dummy-Header: kaboom\r\n"
4763         "\r\n";
4764     uint32_t http1_len = sizeof(http1_buf) - 1;
4765     uint32_t http2_len = sizeof(http2_buf) - 1;
4766 
4767     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4768     FAIL_IF_NULL(alp_tctx);
4769 
4770     memset(&th_v, 0, sizeof(th_v));
4771     memset(&f, 0, sizeof(f));
4772     memset(&ssn, 0, sizeof(ssn));
4773 
4774     p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4775     p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4776 
4777     FLOW_INITIALIZE(&f);
4778     f.protoctx = (void *)&ssn;
4779     f.proto = IPPROTO_TCP;
4780     f.flags |= FLOW_IPV4;
4781 
4782     p1->flow = &f;
4783     p1->flowflags |= FLOW_PKT_TOSERVER;
4784     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4785     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4786     p2->flow = &f;
4787     p2->flowflags |= FLOW_PKT_TOSERVER;
4788     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4789     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4790     f.alproto = ALPROTO_HTTP;
4791 
4792     StreamTcpInitConfig(TRUE);
4793 
4794     de_ctx = DetectEngineCtxInit();
4795     FAIL_IF(de_ctx == NULL);
4796     de_ctx->flags |= DE_QUIET;
4797 
4798     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4799                                "(content:\"Dummy\"; http_header; "
4800                                "sid:1;)");
4801     FAIL_IF(de_ctx->sig_list == NULL);
4802 
4803     SigGroupBuild(de_ctx);
4804     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4805 
4806     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4807                                 STREAM_TOSERVER, http1_buf, http1_len);
4808     FAIL_IF_NOT(r == 0);
4809 
4810     http_state = f.alstate;
4811     FAIL_IF(http_state == NULL);
4812 
4813     /* do detect */
4814     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4815 
4816     FAIL_IF(PacketAlertCheck(p1, 1));
4817 
4818     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4819                             STREAM_TOSERVER, http2_buf, http2_len);
4820     FAIL_IF_NOT(r == 0);
4821 
4822     /* do detect */
4823     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4824 
4825     FAIL_IF(!PacketAlertCheck(p2, 1));
4826 
4827     AppLayerParserThreadCtxFree(alp_tctx);
4828     DetectEngineCtxFree(de_ctx);
4829 
4830     StreamTcpFreeConfig(TRUE);
4831     FLOW_DESTROY(&f);
4832     UTHFreePackets(&p1, 1);
4833     UTHFreePackets(&p2, 1);
4834     PASS;
4835 }
4836 
4837 /**
4838  * \test Trailing headers.
4839  */
DetectEngineHttpHeaderTest34(void)4840 static int DetectEngineHttpHeaderTest34(void)
4841 {
4842     TcpSession ssn;
4843     ThreadVars th_v;
4844     DetectEngineCtx *de_ctx = NULL;
4845     DetectEngineThreadCtx *det_ctx = NULL;
4846     HtpState *http_state = NULL;
4847     Flow f;
4848     uint8_t http1_buf[] =
4849         "GET /index.html HTTP/1.0\r\n"
4850         "host: boom\r\n"
4851         "Dummy-Header1: blah\r\n"
4852         "Transfer-Encoding: chunked\r\n"
4853         "\r\n";
4854     uint8_t http2_buf[] =
4855         "13\r\n"
4856         "This is dummy body1\r\n"
4857         "0\r\n";
4858     uint8_t http3_buf[] =
4859         "Dummy-Header2: kaboom\r\n"
4860         "\r\n";
4861     uint32_t http1_len = sizeof(http1_buf) - 1;
4862     uint32_t http2_len = sizeof(http2_buf) - 1;
4863     uint32_t http3_len = sizeof(http3_buf) - 1;
4864 
4865     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4866     FAIL_IF_NULL(alp_tctx);
4867 
4868     memset(&th_v, 0, sizeof(th_v));
4869     memset(&f, 0, sizeof(f));
4870     memset(&ssn, 0, sizeof(ssn));
4871 
4872     Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4873     Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4874     Packet *p3 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4875 
4876     FLOW_INITIALIZE(&f);
4877     f.protoctx = (void *)&ssn;
4878     f.proto = IPPROTO_TCP;
4879     f.flags |= FLOW_IPV4;
4880 
4881     p1->flow = &f;
4882     p1->flowflags |= FLOW_PKT_TOSERVER;
4883     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4884     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4885     p1->pcap_cnt = 1;
4886     p2->flow = &f;
4887     p2->flowflags |= FLOW_PKT_TOSERVER;
4888     p2->flowflags |= FLOW_PKT_ESTABLISHED;
4889     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4890     p2->pcap_cnt = 2;
4891     p3->flow = &f;
4892     p3->flowflags |= FLOW_PKT_TOSERVER;
4893     p3->flowflags |= FLOW_PKT_ESTABLISHED;
4894     p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4895     p3->pcap_cnt = 3;
4896     f.alproto = ALPROTO_HTTP;
4897 
4898     StreamTcpInitConfig(TRUE);
4899 
4900     de_ctx = DetectEngineCtxInit();
4901     FAIL_IF(de_ctx == NULL);
4902     de_ctx->flags |= DE_QUIET;
4903 
4904     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
4905                                "(content:\"Dummy\"; http_header; content:\"Header2\"; http_header; within:8; "
4906                                "sid:1;)");
4907     FAIL_IF(de_ctx->sig_list == NULL);
4908 
4909     SigGroupBuild(de_ctx);
4910     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
4911 
4912     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4913                                 STREAM_TOSERVER, http1_buf, http1_len);
4914     FAIL_IF_NOT(r == 0);
4915 
4916     http_state = f.alstate;
4917     FAIL_IF(http_state == NULL);
4918 
4919     /* do detect */
4920     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
4921     FAIL_IF(PacketAlertCheck(p1, 1));
4922 
4923     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4924                             STREAM_TOSERVER, http2_buf, http2_len);
4925     FAIL_IF_NOT(r == 0);
4926 
4927     /* do detect */
4928     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
4929     FAIL_IF(PacketAlertCheck(p2, 1));
4930 
4931     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
4932                             STREAM_TOSERVER, http3_buf, http3_len);
4933     FAIL_IF_NOT(r == 0);
4934 
4935     /* do detect */
4936     SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
4937     FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */
4938 
4939     AppLayerParserThreadCtxFree(alp_tctx);
4940     DetectEngineCtxFree(de_ctx);
4941 
4942     StreamTcpFreeConfig(TRUE);
4943     FLOW_DESTROY(&f);
4944     UTHFreePackets(&p1, 1);
4945     UTHFreePackets(&p2, 1);
4946     UTHFreePackets(&p3, 1);
4947     PASS;
4948 }
4949 
4950 /**
4951  * \test Trailing headers.
4952  */
DetectEngineHttpHeaderTest35(void)4953 static int DetectEngineHttpHeaderTest35(void)
4954 {
4955     TcpSession ssn;
4956     ThreadVars th_v;
4957     DetectEngineCtx *de_ctx = NULL;
4958     DetectEngineThreadCtx *det_ctx = NULL;
4959     HtpState *http_state = NULL;
4960     Flow f;
4961     uint8_t http1_buf[] =
4962         "GET /index.html HTTP/1.0\r\n"
4963         "host: boom\r\n"
4964         "Dummy-Header1: blah\r\n"
4965         "Transfer-Encoding: chunked\r\n"
4966         "\r\n";
4967     uint8_t http2_buf[] =
4968         "13\r\n"
4969         "This is dummy body1\r\n"
4970         "0\r\n";
4971     uint8_t http3_buf[] =
4972         "Dummy-Header2: kaboom\r\n"
4973         "\r\n";
4974     uint32_t http1_len = sizeof(http1_buf) - 1;
4975     uint32_t http2_len = sizeof(http2_buf) - 1;
4976     uint32_t http3_len = sizeof(http3_buf) - 1;
4977 
4978     AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
4979     FAIL_IF_NULL(alp_tctx);
4980 
4981     memset(&th_v, 0, sizeof(th_v));
4982     memset(&f, 0, sizeof(f));
4983     memset(&ssn, 0, sizeof(ssn));
4984 
4985     Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4986     Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4987     Packet *p3 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
4988 
4989     FLOW_INITIALIZE(&f);
4990     f.protoctx = (void *)&ssn;
4991     f.proto = IPPROTO_TCP;
4992     f.flags |= FLOW_IPV4;
4993 
4994     p1->flow = &f;
4995     p1->flowflags |= FLOW_PKT_TOSERVER;
4996     p1->flowflags |= FLOW_PKT_ESTABLISHED;
4997     p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
4998     p1->pcap_cnt = 1;
4999     p2->flow = &f;
5000     p2->flowflags |= FLOW_PKT_TOSERVER;
5001     p2->flowflags |= FLOW_PKT_ESTABLISHED;
5002     p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
5003     p2->pcap_cnt = 2;
5004     p3->flow = &f;
5005     p3->flowflags |= FLOW_PKT_TOSERVER;
5006     p3->flowflags |= FLOW_PKT_ESTABLISHED;
5007     p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
5008     p3->pcap_cnt = 3;
5009     f.alproto = ALPROTO_HTTP;
5010 
5011     StreamTcpInitConfig(TRUE);
5012 
5013     de_ctx = DetectEngineCtxInit();
5014     FAIL_IF(de_ctx == NULL);
5015     de_ctx->flags |= DE_QUIET;
5016 
5017     de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
5018                                "(content:\"Dummy\"; http_header; fast_pattern; content:\"Header2\"; http_header; within:8; "
5019                                "sid:1;)");
5020     FAIL_IF(de_ctx->sig_list == NULL);
5021 
5022     SigGroupBuild(de_ctx);
5023     DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
5024 
5025     int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5026                                 STREAM_TOSERVER, http1_buf, http1_len);
5027     FAIL_IF_NOT(r == 0);
5028 
5029     http_state = f.alstate;
5030     FAIL_IF(http_state == NULL);
5031 
5032     /* do detect */
5033     SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
5034     FAIL_IF(PacketAlertCheck(p1, 1));
5035 
5036     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5037                             STREAM_TOSERVER, http2_buf, http2_len);
5038     FAIL_IF_NOT(r == 0);
5039 
5040     /* do detect */
5041     SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
5042     FAIL_IF(PacketAlertCheck(p2, 1));
5043 
5044     r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
5045                             STREAM_TOSERVER, http3_buf, http3_len);
5046     FAIL_IF_NOT(r == 0);
5047 
5048     /* do detect */
5049     SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
5050     FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */
5051 
5052     AppLayerParserThreadCtxFree(alp_tctx);
5053     DetectEngineCtxFree(de_ctx);
5054 
5055     StreamTcpFreeConfig(TRUE);
5056     FLOW_DESTROY(&f);
5057     UTHFreePackets(&p1, 1);
5058     UTHFreePackets(&p2, 1);
5059     UTHFreePackets(&p3, 1);
5060     PASS;
5061 }
5062 
DetectHttpHeaderRegisterTests(void)5063 void DetectHttpHeaderRegisterTests(void)
5064 {
5065     UtRegisterTest("DetectHttpHeaderParserTest01", DetectHttpHeaderParserTest01);
5066     UtRegisterTest("DetectHttpHeaderParserTest02", DetectHttpHeaderParserTest02);
5067 
5068     UtRegisterTest("DetectHttpHeaderTest01", DetectHttpHeaderTest01);
5069     UtRegisterTest("DetectHttpHeaderTest06", DetectHttpHeaderTest06);
5070     UtRegisterTest("DetectHttpHeaderTest07", DetectHttpHeaderTest07);
5071     UtRegisterTest("DetectHttpHeaderTest08", DetectHttpHeaderTest08);
5072     UtRegisterTest("DetectHttpHeaderTest09", DetectHttpHeaderTest09);
5073     UtRegisterTest("DetectHttpHeaderTest10", DetectHttpHeaderTest10);
5074     UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11);
5075     UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12);
5076     UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13);
5077     UtRegisterTest("DetectHttpHeaderTest20", DetectHttpHeaderTest20);
5078     UtRegisterTest("DetectHttpHeaderTest21", DetectHttpHeaderTest21);
5079     UtRegisterTest("DetectHttpHeaderTest22", DetectHttpHeaderTest22);
5080     UtRegisterTest("DetectHttpHeaderTest23", DetectHttpHeaderTest23);
5081     UtRegisterTest("DetectHttpHeaderTest24", DetectHttpHeaderTest24);
5082     UtRegisterTest("DetectHttpHeaderTest25", DetectHttpHeaderTest25);
5083     UtRegisterTest("DetectHttpHeaderTest26", DetectHttpHeaderTest26);
5084     UtRegisterTest("DetectHttpHeaderTest27", DetectHttpHeaderTest27);
5085     UtRegisterTest("DetectHttpHeaderTest28", DetectHttpHeaderTest28);
5086     UtRegisterTest("DetectHttpHeaderTest29", DetectHttpHeaderTest29);
5087     UtRegisterTest("DetectHttpHeaderTest30", DetectHttpHeaderTest30);
5088 
5089     UtRegisterTest("DetectHttpHeaderIsdataatParseTest",
5090             DetectHttpHeaderIsdataatParseTest);
5091 
5092     UtRegisterTest("DetectEngineHttpHeaderTest01",
5093                    DetectEngineHttpHeaderTest01);
5094     UtRegisterTest("DetectEngineHttpHeaderTest02",
5095                    DetectEngineHttpHeaderTest02);
5096     UtRegisterTest("DetectEngineHttpHeaderTest03",
5097                    DetectEngineHttpHeaderTest03);
5098     UtRegisterTest("DetectEngineHttpHeaderTest04",
5099                    DetectEngineHttpHeaderTest04);
5100     UtRegisterTest("DetectEngineHttpHeaderTest05",
5101                    DetectEngineHttpHeaderTest05);
5102     UtRegisterTest("DetectEngineHttpHeaderTest06",
5103                    DetectEngineHttpHeaderTest06);
5104     UtRegisterTest("DetectEngineHttpHeaderTest07",
5105                    DetectEngineHttpHeaderTest07);
5106     UtRegisterTest("DetectEngineHttpHeaderTest08",
5107                    DetectEngineHttpHeaderTest08);
5108     UtRegisterTest("DetectEngineHttpHeaderTest09",
5109                    DetectEngineHttpHeaderTest09);
5110     UtRegisterTest("DetectEngineHttpHeaderTest10",
5111                    DetectEngineHttpHeaderTest10);
5112     UtRegisterTest("DetectEngineHttpHeaderTest11",
5113                    DetectEngineHttpHeaderTest11);
5114     UtRegisterTest("DetectEngineHttpHeaderTest12",
5115                    DetectEngineHttpHeaderTest12);
5116     UtRegisterTest("DetectEngineHttpHeaderTest13",
5117                    DetectEngineHttpHeaderTest13);
5118     UtRegisterTest("DetectEngineHttpHeaderTest14",
5119                    DetectEngineHttpHeaderTest14);
5120     UtRegisterTest("DetectEngineHttpHeaderTest15",
5121                    DetectEngineHttpHeaderTest15);
5122     UtRegisterTest("DetectEngineHttpHeaderTest16",
5123                    DetectEngineHttpHeaderTest16);
5124     UtRegisterTest("DetectEngineHttpHeaderTest17",
5125                    DetectEngineHttpHeaderTest17);
5126     UtRegisterTest("DetectEngineHttpHeaderTest20",
5127                    DetectEngineHttpHeaderTest20);
5128     UtRegisterTest("DetectEngineHttpHeaderTest21",
5129                    DetectEngineHttpHeaderTest21);
5130     UtRegisterTest("DetectEngineHttpHeaderTest22",
5131                    DetectEngineHttpHeaderTest22);
5132     UtRegisterTest("DetectEngineHttpHeaderTest23",
5133                    DetectEngineHttpHeaderTest23);
5134     UtRegisterTest("DetectEngineHttpHeaderTest24",
5135                    DetectEngineHttpHeaderTest24);
5136     UtRegisterTest("DetectEngineHttpHeaderTest25",
5137                    DetectEngineHttpHeaderTest25);
5138     UtRegisterTest("DetectEngineHttpHeaderTest26",
5139                    DetectEngineHttpHeaderTest26);
5140     UtRegisterTest("DetectEngineHttpHeaderTest27",
5141                    DetectEngineHttpHeaderTest27);
5142     UtRegisterTest("DetectEngineHttpHeaderTest28",
5143                    DetectEngineHttpHeaderTest28);
5144     UtRegisterTest("DetectEngineHttpHeaderTest29",
5145                    DetectEngineHttpHeaderTest29);
5146     UtRegisterTest("DetectEngineHttpHeaderTest30",
5147                    DetectEngineHttpHeaderTest30);
5148     UtRegisterTest("DetectEngineHttpHeaderTest31",
5149                    DetectEngineHttpHeaderTest31);
5150 #if 0
5151     UtRegisterTest("DetectEngineHttpHeaderTest30",
5152                    DetectEngineHttpHeaderTest30, 1);
5153 #endif
5154     UtRegisterTest("DetectEngineHttpHeaderTest32",
5155                    DetectEngineHttpHeaderTest32);
5156     UtRegisterTest("DetectEngineHttpHeaderTest33 -- Trailer",
5157                    DetectEngineHttpHeaderTest33);
5158     UtRegisterTest("DetectEngineHttpHeaderTest34 -- Trailer",
5159                    DetectEngineHttpHeaderTest34);
5160     UtRegisterTest("DetectEngineHttpHeaderTest35 -- Trailer",
5161                    DetectEngineHttpHeaderTest35);
5162 }
5163 
5164 /**
5165  * @}
5166  */
5167