1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18 /**
19 * \file
20 *
21 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
22 */
23
24 #include "suricata-common.h"
25 #include "detect-engine.h"
26 #include "detect-engine-prefilter.h"
27 #include "detect-engine-prefilter-common.h"
28 #include "detect-parse.h"
29 #include "detect-app-layer-protocol.h"
30 #include "app-layer.h"
31 #include "app-layer-parser.h"
32 #include "util-debug.h"
33 #include "util-unittest.h"
34 #include "util-unittest-helper.h"
35
36 #ifdef UNITTESTS
37 static void DetectAppLayerProtocolRegisterTests(void);
38 #endif
39
DetectAppLayerProtocolPacketMatch(DetectEngineThreadCtx * det_ctx,Packet * p,const Signature * s,const SigMatchCtx * ctx)40 static int DetectAppLayerProtocolPacketMatch(
41 DetectEngineThreadCtx *det_ctx,
42 Packet *p, const Signature *s, const SigMatchCtx *ctx)
43 {
44 SCEnter();
45
46 int r = 0;
47 const DetectAppLayerProtocolData *data = (const DetectAppLayerProtocolData *)ctx;
48
49 /* if the sig is PD-only we only match when PD packet flags are set */
50 if ((s->flags & SIG_FLAG_PDONLY) &&
51 (p->flags & (PKT_PROTO_DETECT_TS_DONE|PKT_PROTO_DETECT_TC_DONE)) == 0)
52 {
53 SCLogDebug("packet %"PRIu64": flags not set", p->pcap_cnt);
54 SCReturnInt(0);
55 }
56
57 const Flow *f = p->flow;
58 if (f == NULL) {
59 SCLogDebug("packet %"PRIu64": no flow", p->pcap_cnt);
60 SCReturnInt(0);
61 }
62
63 /* unknown means protocol detection isn't ready yet */
64
65 if ((f->alproto_ts != ALPROTO_UNKNOWN) && (p->flowflags & FLOW_PKT_TOSERVER))
66 {
67 SCLogDebug("toserver packet %"PRIu64": looking for %u/neg %u, got %u",
68 p->pcap_cnt, data->alproto, data->negated, f->alproto_ts);
69
70 r = (data->negated) ? (f->alproto_ts != data->alproto) :
71 (f->alproto_ts == data->alproto);
72
73 } else if ((f->alproto_tc != ALPROTO_UNKNOWN) && (p->flowflags & FLOW_PKT_TOCLIENT))
74 {
75 SCLogDebug("toclient packet %"PRIu64": looking for %u/neg %u, got %u",
76 p->pcap_cnt, data->alproto, data->negated, f->alproto_tc);
77
78 r = (data->negated) ? (f->alproto_tc != data->alproto) :
79 (f->alproto_tc == data->alproto);
80 }
81 else {
82 SCLogDebug("packet %"PRIu64": default case: direction %02x, approtos %u/%u/%u",
83 p->pcap_cnt,
84 p->flowflags & (FLOW_PKT_TOCLIENT|FLOW_PKT_TOSERVER),
85 f->alproto, f->alproto_ts, f->alproto_tc);
86 }
87
88 SCReturnInt(r);
89 }
90
DetectAppLayerProtocolParse(const char * arg,bool negate)91 static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg, bool negate)
92 {
93 DetectAppLayerProtocolData *data;
94 AppProto alproto = ALPROTO_UNKNOWN;
95
96 if (strcmp(arg, "failed") == 0) {
97 alproto = ALPROTO_FAILED;
98 } else {
99 alproto = AppLayerGetProtoByName((char *)arg);
100 if (alproto == ALPROTO_UNKNOWN) {
101 SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-protocol "
102 "keyword supplied with unknown protocol \"%s\"", arg);
103 return NULL;
104 }
105 }
106
107 data = SCMalloc(sizeof(DetectAppLayerProtocolData));
108 if (unlikely(data == NULL))
109 return NULL;
110 data->alproto = alproto;
111 data->negated = negate;
112
113 return data;
114 }
115
HasConflicts(const DetectAppLayerProtocolData * us,const DetectAppLayerProtocolData * them)116 static bool HasConflicts(const DetectAppLayerProtocolData *us,
117 const DetectAppLayerProtocolData *them)
118 {
119 /* mixing negated and non negated is illegal */
120 if (them->negated ^ us->negated)
121 return TRUE;
122 /* multiple non-negated is illegal */
123 if (!us->negated)
124 return TRUE;
125 /* duplicate option */
126 if (us->alproto == them->alproto)
127 return TRUE;
128
129 /* all good */
130 return FALSE;
131 }
132
DetectAppLayerProtocolSetup(DetectEngineCtx * de_ctx,Signature * s,const char * arg)133 static int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx,
134 Signature *s, const char *arg)
135 {
136 DetectAppLayerProtocolData *data = NULL;
137 SigMatch *sm = NULL;
138
139 if (s->alproto != ALPROTO_UNKNOWN) {
140 SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Either we already "
141 "have the rule match on an app layer protocol set through "
142 "other keywords that match on this protocol, or have "
143 "already seen a non-negated app-layer-protocol.");
144 goto error;
145 }
146
147 data = DetectAppLayerProtocolParse(arg, s->init_data->negated);
148 if (data == NULL)
149 goto error;
150
151 SigMatch *tsm = s->init_data->smlists[DETECT_SM_LIST_MATCH];
152 for ( ; tsm != NULL; tsm = tsm->next) {
153 if (tsm->type == DETECT_AL_APP_LAYER_PROTOCOL) {
154 const DetectAppLayerProtocolData *them = (const DetectAppLayerProtocolData *)tsm->ctx;
155
156 if (HasConflicts(data, them)) {
157 SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "can't mix "
158 "positive app-layer-protocol match with negated "
159 "match or match for 'failed'.");
160 goto error;
161 }
162 }
163 }
164
165 sm = SigMatchAlloc();
166 if (sm == NULL)
167 goto error;
168
169 sm->type = DETECT_AL_APP_LAYER_PROTOCOL;
170 sm->ctx = (void *)data;
171
172 SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
173 return 0;
174
175 error:
176 if (data != NULL)
177 SCFree(data);
178 return -1;
179 }
180
DetectAppLayerProtocolFree(DetectEngineCtx * de_ctx,void * ptr)181 static void DetectAppLayerProtocolFree(DetectEngineCtx *de_ctx, void *ptr)
182 {
183 SCFree(ptr);
184 return;
185 }
186
187 /** \internal
188 * \brief prefilter function for protocol detect matching
189 */
190 static void
PrefilterPacketAppProtoMatch(DetectEngineThreadCtx * det_ctx,Packet * p,const void * pectx)191 PrefilterPacketAppProtoMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
192 {
193 const PrefilterPacketHeaderCtx *ctx = pectx;
194
195 if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE) {
196 SCLogDebug("packet %"PRIu64": extra match failed", p->pcap_cnt);
197 SCReturn;
198 }
199
200 if (p->flow == NULL) {
201 SCLogDebug("packet %"PRIu64": no flow, no alproto", p->pcap_cnt);
202 SCReturn;
203 }
204
205 if ((p->flags & (PKT_PROTO_DETECT_TS_DONE|PKT_PROTO_DETECT_TC_DONE)) == 0) {
206 SCLogDebug("packet %"PRIu64": flags not set", p->pcap_cnt);
207 SCReturn;
208 }
209
210 if ((p->flags & PKT_PROTO_DETECT_TS_DONE) && (p->flowflags & FLOW_PKT_TOSERVER))
211 {
212 int r = (ctx->v1.u16[0] == p->flow->alproto_ts) ^ ctx->v1.u8[2];
213 if (r) {
214 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
215 }
216 } else if ((p->flags & PKT_PROTO_DETECT_TC_DONE) && (p->flowflags & FLOW_PKT_TOCLIENT))
217 {
218 int r = (ctx->v1.u16[0] == p->flow->alproto_tc) ^ ctx->v1.u8[2];
219 if (r) {
220 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
221 }
222 }
223 }
224
225 static void
PrefilterPacketAppProtoSet(PrefilterPacketHeaderValue * v,void * smctx)226 PrefilterPacketAppProtoSet(PrefilterPacketHeaderValue *v, void *smctx)
227 {
228 const DetectAppLayerProtocolData *a = smctx;
229 v->u16[0] = a->alproto;
230 v->u8[2] = (uint8_t)a->negated;
231 }
232
233 static bool
PrefilterPacketAppProtoCompare(PrefilterPacketHeaderValue v,void * smctx)234 PrefilterPacketAppProtoCompare(PrefilterPacketHeaderValue v, void *smctx)
235 {
236 const DetectAppLayerProtocolData *a = smctx;
237 if (v.u16[0] == a->alproto &&
238 v.u8[2] == (uint8_t)a->negated)
239 return TRUE;
240 return FALSE;
241 }
242
PrefilterSetupAppProto(DetectEngineCtx * de_ctx,SigGroupHead * sgh)243 static int PrefilterSetupAppProto(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
244 {
245 return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_AL_APP_LAYER_PROTOCOL,
246 PrefilterPacketAppProtoSet,
247 PrefilterPacketAppProtoCompare,
248 PrefilterPacketAppProtoMatch);
249 }
250
PrefilterAppProtoIsPrefilterable(const Signature * s)251 static bool PrefilterAppProtoIsPrefilterable(const Signature *s)
252 {
253 if (s->flags & SIG_FLAG_PDONLY) {
254 SCLogDebug("prefilter on PD %u", s->id);
255 return TRUE;
256 }
257 return FALSE;
258 }
259
DetectAppLayerProtocolRegister(void)260 void DetectAppLayerProtocolRegister(void)
261 {
262 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].name = "app-layer-protocol";
263 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].desc = "match on the detected app-layer protocol";
264 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].url = "/rules/app-layer.html#app-layer-protocol";
265 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Match =
266 DetectAppLayerProtocolPacketMatch;
267 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Setup =
268 DetectAppLayerProtocolSetup;
269 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Free =
270 DetectAppLayerProtocolFree;
271 #ifdef UNITTESTS
272 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].RegisterTests =
273 DetectAppLayerProtocolRegisterTests;
274 #endif
275 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].flags =
276 (SIGMATCH_QUOTES_OPTIONAL|SIGMATCH_HANDLE_NEGATION);
277
278 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].SetupPrefilter =
279 PrefilterSetupAppProto;
280 sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].SupportsPrefilter =
281 PrefilterAppProtoIsPrefilterable;
282 return;
283 }
284
285 /**********************************Unittests***********************************/
286
287 #ifdef UNITTESTS
288
DetectAppLayerProtocolTest01(void)289 static int DetectAppLayerProtocolTest01(void)
290 {
291 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", false);
292 FAIL_IF_NULL(data);
293 FAIL_IF(data->alproto != ALPROTO_HTTP);
294 FAIL_IF(data->negated != 0);
295 DetectAppLayerProtocolFree(NULL, data);
296 PASS;
297 }
298
DetectAppLayerProtocolTest02(void)299 static int DetectAppLayerProtocolTest02(void)
300 {
301 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", true);
302 FAIL_IF_NULL(data);
303 FAIL_IF(data->alproto != ALPROTO_HTTP);
304 FAIL_IF(data->negated == 0);
305 DetectAppLayerProtocolFree(NULL, data);
306 PASS;
307 }
308
DetectAppLayerProtocolTest03(void)309 static int DetectAppLayerProtocolTest03(void)
310 {
311 Signature *s = NULL;
312 DetectAppLayerProtocolData *data = NULL;
313 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
314 FAIL_IF_NULL(de_ctx);
315 de_ctx->flags |= DE_QUIET;
316
317 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
318 "(app-layer-protocol:http; sid:1;)");
319 FAIL_IF_NULL(s);
320
321 FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
322
323 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]);
324 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
325
326 data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
327 FAIL_IF(data->alproto != ALPROTO_HTTP);
328 FAIL_IF(data->negated);
329 DetectEngineCtxFree(de_ctx);
330 PASS;
331 }
332
DetectAppLayerProtocolTest04(void)333 static int DetectAppLayerProtocolTest04(void)
334 {
335 Signature *s = NULL;
336 DetectAppLayerProtocolData *data = NULL;
337 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
338 FAIL_IF_NULL(de_ctx);
339 de_ctx->flags |= DE_QUIET;
340
341 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
342 "(app-layer-protocol:!http; sid:1;)");
343 FAIL_IF_NULL(s);
344 FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
345 FAIL_IF(s->flags & SIG_FLAG_APPLAYER);
346
347 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]);
348 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
349
350 data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
351 FAIL_IF_NULL(data);
352 FAIL_IF(data->alproto != ALPROTO_HTTP);
353 FAIL_IF(data->negated == 0);
354
355 DetectEngineCtxFree(de_ctx);
356 PASS;
357 }
358
DetectAppLayerProtocolTest05(void)359 static int DetectAppLayerProtocolTest05(void)
360 {
361 Signature *s = NULL;
362 DetectAppLayerProtocolData *data = NULL;
363 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
364 FAIL_IF_NULL(de_ctx);
365 de_ctx->flags |= DE_QUIET;
366
367 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
368 "(app-layer-protocol:!http; app-layer-protocol:!smtp; sid:1;)");
369 FAIL_IF_NULL(s);
370 FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
371 FAIL_IF(s->flags & SIG_FLAG_APPLAYER);
372
373 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]);
374 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
375
376 data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
377 FAIL_IF_NULL(data);
378 FAIL_IF(data->alproto != ALPROTO_HTTP);
379 FAIL_IF(data->negated == 0);
380
381 data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->next->ctx;
382 FAIL_IF_NULL(data);
383 FAIL_IF(data->alproto != ALPROTO_SMTP);
384 FAIL_IF(data->negated == 0);
385
386 DetectEngineCtxFree(de_ctx);
387 PASS;
388 }
389
DetectAppLayerProtocolTest06(void)390 static int DetectAppLayerProtocolTest06(void)
391 {
392 Signature *s = NULL;
393 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
394 FAIL_IF_NULL(de_ctx);
395 de_ctx->flags |= DE_QUIET;
396
397 s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
398 "(app-layer-protocol:smtp; sid:1;)");
399 FAIL_IF_NOT_NULL(s);
400 DetectEngineCtxFree(de_ctx);
401 PASS;
402 }
403
DetectAppLayerProtocolTest07(void)404 static int DetectAppLayerProtocolTest07(void)
405 {
406 Signature *s = NULL;
407 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
408 FAIL_IF_NULL(de_ctx);
409 de_ctx->flags |= DE_QUIET;
410
411 s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
412 "(app-layer-protocol:!smtp; sid:1;)");
413 FAIL_IF_NOT_NULL(s);
414 DetectEngineCtxFree(de_ctx);
415 PASS;
416 }
417
DetectAppLayerProtocolTest08(void)418 static int DetectAppLayerProtocolTest08(void)
419 {
420 Signature *s = NULL;
421 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
422 FAIL_IF_NULL(de_ctx);
423 de_ctx->flags |= DE_QUIET;
424
425 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
426 "(app-layer-protocol:!smtp; app-layer-protocol:http; sid:1;)");
427 FAIL_IF_NOT_NULL(s);
428 DetectEngineCtxFree(de_ctx);
429 PASS;
430 }
431
DetectAppLayerProtocolTest09(void)432 static int DetectAppLayerProtocolTest09(void)
433 {
434 Signature *s = NULL;
435 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
436 FAIL_IF_NULL(de_ctx);
437 de_ctx->flags |= DE_QUIET;
438
439 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
440 "(app-layer-protocol:http; app-layer-protocol:!smtp; sid:1;)");
441 FAIL_IF_NOT_NULL(s);
442 DetectEngineCtxFree(de_ctx);
443 PASS;
444 }
445
DetectAppLayerProtocolTest10(void)446 static int DetectAppLayerProtocolTest10(void)
447 {
448 Signature *s = NULL;
449 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
450 FAIL_IF_NULL(de_ctx);
451 de_ctx->flags |= DE_QUIET;
452
453 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
454 "(app-layer-protocol:smtp; app-layer-protocol:!http; sid:1;)");
455 FAIL_IF_NOT_NULL(s);
456 DetectEngineCtxFree(de_ctx);
457 PASS;
458 }
459
DetectAppLayerProtocolTest11(void)460 static int DetectAppLayerProtocolTest11(void)
461 {
462 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", false);
463 FAIL_IF_NULL(data);
464 FAIL_IF(data->alproto != ALPROTO_FAILED);
465 FAIL_IF(data->negated != 0);
466 DetectAppLayerProtocolFree(NULL, data);
467 PASS;
468 }
469
DetectAppLayerProtocolTest12(void)470 static int DetectAppLayerProtocolTest12(void)
471 {
472 DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", true);
473 FAIL_IF_NULL(data);
474 FAIL_IF(data->alproto != ALPROTO_FAILED);
475 FAIL_IF(data->negated == 0);
476 DetectAppLayerProtocolFree(NULL, data);
477 PASS;
478 }
479
DetectAppLayerProtocolTest13(void)480 static int DetectAppLayerProtocolTest13(void)
481 {
482 Signature *s = NULL;
483 DetectAppLayerProtocolData *data = NULL;
484 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
485 FAIL_IF_NULL(de_ctx);
486 de_ctx->flags |= DE_QUIET;
487
488 s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
489 "(app-layer-protocol:failed; sid:1;)");
490 FAIL_IF_NULL(s);
491
492 FAIL_IF(s->alproto != ALPROTO_UNKNOWN);
493
494 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]);
495 FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
496
497 data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
498 FAIL_IF(data->alproto != ALPROTO_FAILED);
499 FAIL_IF(data->negated);
500 DetectEngineCtxFree(de_ctx);
501 PASS;
502 }
503
DetectAppLayerProtocolTest14(void)504 static int DetectAppLayerProtocolTest14(void)
505 {
506 DetectAppLayerProtocolData *data = NULL;
507 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
508 FAIL_IF_NULL(de_ctx);
509 de_ctx->flags |= DE_QUIET;
510
511 Signature *s1 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
512 "(app-layer-protocol:http; flowbits:set,blah; sid:1;)");
513 FAIL_IF_NULL(s1);
514 FAIL_IF(s1->alproto != ALPROTO_UNKNOWN);
515 FAIL_IF_NULL(s1->sm_lists[DETECT_SM_LIST_MATCH]);
516 FAIL_IF_NULL(s1->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
517 data = (DetectAppLayerProtocolData *)s1->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
518 FAIL_IF(data->alproto != ALPROTO_HTTP);
519 FAIL_IF(data->negated);
520
521 Signature *s2 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
522 "(app-layer-protocol:http; flow:to_client; sid:2;)");
523 FAIL_IF_NULL(s2);
524 FAIL_IF(s2->alproto != ALPROTO_UNKNOWN);
525 FAIL_IF_NULL(s2->sm_lists[DETECT_SM_LIST_MATCH]);
526 FAIL_IF_NULL(s2->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
527 data = (DetectAppLayerProtocolData *)s2->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
528 FAIL_IF(data->alproto != ALPROTO_HTTP);
529 FAIL_IF(data->negated);
530
531 /* flow:established and other options not supported for PD-only */
532 Signature *s3 = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
533 "(app-layer-protocol:http; flow:to_client,established; sid:3;)");
534 FAIL_IF_NULL(s3);
535 FAIL_IF(s3->alproto != ALPROTO_UNKNOWN);
536 FAIL_IF_NULL(s3->sm_lists[DETECT_SM_LIST_MATCH]);
537 FAIL_IF_NULL(s3->sm_lists[DETECT_SM_LIST_MATCH]->ctx);
538 data = (DetectAppLayerProtocolData *)s3->sm_lists[DETECT_SM_LIST_MATCH]->ctx;
539 FAIL_IF(data->alproto != ALPROTO_HTTP);
540 FAIL_IF(data->negated);
541
542 SigGroupBuild(de_ctx);
543 FAIL_IF_NOT(s1->flags & SIG_FLAG_PDONLY);
544 FAIL_IF_NOT(s2->flags & SIG_FLAG_PDONLY);
545 FAIL_IF(s3->flags & SIG_FLAG_PDONLY); // failure now
546
547 DetectEngineCtxFree(de_ctx);
548 PASS;
549 }
550
551
DetectAppLayerProtocolRegisterTests(void)552 static void DetectAppLayerProtocolRegisterTests(void)
553 {
554 UtRegisterTest("DetectAppLayerProtocolTest01",
555 DetectAppLayerProtocolTest01);
556 UtRegisterTest("DetectAppLayerProtocolTest02",
557 DetectAppLayerProtocolTest02);
558 UtRegisterTest("DetectAppLayerProtocolTest03",
559 DetectAppLayerProtocolTest03);
560 UtRegisterTest("DetectAppLayerProtocolTest04",
561 DetectAppLayerProtocolTest04);
562 UtRegisterTest("DetectAppLayerProtocolTest05",
563 DetectAppLayerProtocolTest05);
564 UtRegisterTest("DetectAppLayerProtocolTest06",
565 DetectAppLayerProtocolTest06);
566 UtRegisterTest("DetectAppLayerProtocolTest07",
567 DetectAppLayerProtocolTest07);
568 UtRegisterTest("DetectAppLayerProtocolTest08",
569 DetectAppLayerProtocolTest08);
570 UtRegisterTest("DetectAppLayerProtocolTest09",
571 DetectAppLayerProtocolTest09);
572 UtRegisterTest("DetectAppLayerProtocolTest10",
573 DetectAppLayerProtocolTest10);
574 UtRegisterTest("DetectAppLayerProtocolTest11",
575 DetectAppLayerProtocolTest11);
576 UtRegisterTest("DetectAppLayerProtocolTest12",
577 DetectAppLayerProtocolTest12);
578 UtRegisterTest("DetectAppLayerProtocolTest13",
579 DetectAppLayerProtocolTest13);
580 UtRegisterTest("DetectAppLayerProtocolTest14",
581 DetectAppLayerProtocolTest14);
582 }
583 #endif /* UNITTESTS */
584