]>
Commit | Line | Data |
---|---|---|
94e40907 AS |
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" | |
0ed11906 VJ |
26 | #include "detect-engine-prefilter.h" |
27 | #include "detect-engine-prefilter-common.h" | |
94e40907 AS |
28 | #include "detect-parse.h" |
29 | #include "detect-app-layer-protocol.h" | |
429c6388 | 30 | #include "app-layer.h" |
94e40907 AS |
31 | #include "app-layer-parser.h" |
32 | #include "util-debug.h" | |
33 | #include "util-unittest.h" | |
34 | #include "util-unittest-helper.h" | |
35 | ||
6ab323d3 | 36 | #ifdef UNITTESTS |
6022fa44 | 37 | static void DetectAppLayerProtocolRegisterTests(void); |
6ab323d3 | 38 | #endif |
94e40907 | 39 | |
14896365 | 40 | static int DetectAppLayerProtocolPacketMatch( |
7d7ec78c | 41 | DetectEngineThreadCtx *det_ctx, |
bfd4bc82 | 42 | Packet *p, const Signature *s, const SigMatchCtx *ctx) |
7d7ec78c VJ |
43 | { |
44 | SCEnter(); | |
45 | ||
46 | int r = 0; | |
47 | const DetectAppLayerProtocolData *data = (const DetectAppLayerProtocolData *)ctx; | |
48 | ||
0ed11906 VJ |
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); | |
7d7ec78c VJ |
54 | SCReturnInt(0); |
55 | } | |
56 | ||
57 | const Flow *f = p->flow; | |
58 | if (f == NULL) { | |
0ed11906 | 59 | SCLogDebug("packet %"PRIu64": no flow", p->pcap_cnt); |
7d7ec78c VJ |
60 | SCReturnInt(0); |
61 | } | |
62 | ||
0ed11906 VJ |
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 | ||
7d7ec78c VJ |
70 | r = (data->negated) ? (f->alproto_ts != data->alproto) : |
71 | (f->alproto_ts == data->alproto); | |
0ed11906 VJ |
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 | ||
7d7ec78c VJ |
78 | r = (data->negated) ? (f->alproto_tc != data->alproto) : |
79 | (f->alproto_tc == data->alproto); | |
80 | } | |
0ed11906 VJ |
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 | } | |
7d7ec78c VJ |
87 | |
88 | SCReturnInt(r); | |
89 | } | |
90 | ||
ab1200fb | 91 | static DetectAppLayerProtocolData *DetectAppLayerProtocolParse(const char *arg, bool negate) |
94e40907 AS |
92 | { |
93 | DetectAppLayerProtocolData *data; | |
f5f14880 | 94 | AppProto alproto = ALPROTO_UNKNOWN; |
94e40907 | 95 | |
7d7ec78c VJ |
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 | } | |
94e40907 AS |
105 | } |
106 | ||
107 | data = SCMalloc(sizeof(DetectAppLayerProtocolData)); | |
108 | if (unlikely(data == NULL)) | |
109 | return NULL; | |
110 | data->alproto = alproto; | |
ab1200fb | 111 | data->negated = negate; |
94e40907 AS |
112 | |
113 | return data; | |
114 | } | |
115 | ||
be4c6b85 | 116 | static bool HasConflicts(const DetectAppLayerProtocolData *us, |
449c93e0 VJ |
117 | const DetectAppLayerProtocolData *them) |
118 | { | |
119 | /* mixing negated and non negated is illegal */ | |
120 | if (them->negated ^ us->negated) | |
1eeb9669 | 121 | return true; |
449c93e0 VJ |
122 | /* multiple non-negated is illegal */ |
123 | if (!us->negated) | |
1eeb9669 | 124 | return true; |
449c93e0 VJ |
125 | /* duplicate option */ |
126 | if (us->alproto == them->alproto) | |
1eeb9669 | 127 | return true; |
449c93e0 VJ |
128 | |
129 | /* all good */ | |
1eeb9669 | 130 | return false; |
449c93e0 VJ |
131 | } |
132 | ||
6022fa44 | 133 | static int DetectAppLayerProtocolSetup(DetectEngineCtx *de_ctx, |
ab1200fb | 134 | Signature *s, const char *arg) |
94e40907 AS |
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 | ||
ab1200fb | 147 | data = DetectAppLayerProtocolParse(arg, s->init_data->negated); |
94e40907 AS |
148 | if (data == NULL) |
149 | goto error; | |
150 | ||
779d40ce | 151 | SigMatch *tsm = s->init_data->smlists[DETECT_SM_LIST_MATCH]; |
449c93e0 VJ |
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)) { | |
e955cf33 VJ |
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 | } | |
e955cf33 | 163 | } |
94e40907 AS |
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 | ||
8094b2b1 | 172 | SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); |
94e40907 AS |
173 | return 0; |
174 | ||
175 | error: | |
176 | if (data != NULL) | |
177 | SCFree(data); | |
178 | return -1; | |
179 | } | |
180 | ||
d3a65fe1 | 181 | static void DetectAppLayerProtocolFree(DetectEngineCtx *de_ctx, void *ptr) |
94e40907 AS |
182 | { |
183 | SCFree(ptr); | |
94e40907 AS |
184 | return; |
185 | } | |
186 | ||
0ed11906 VJ |
187 | /** \internal |
188 | * \brief prefilter function for protocol detect matching | |
189 | */ | |
190 | static void | |
191 | PrefilterPacketAppProtoMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx) | |
192 | { | |
193 | const PrefilterPacketHeaderCtx *ctx = pectx; | |
194 | ||
1eeb9669 | 195 | if (!PrefilterPacketHeaderExtraMatch(ctx, p)) { |
0ed11906 VJ |
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 | |
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 | ||
be4c6b85 | 233 | static bool |
0ed11906 VJ |
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) | |
1eeb9669 JL |
239 | return true; |
240 | return false; | |
0ed11906 VJ |
241 | } |
242 | ||
91296d1e | 243 | static int PrefilterSetupAppProto(DetectEngineCtx *de_ctx, SigGroupHead *sgh) |
0ed11906 | 244 | { |
91296d1e | 245 | return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_AL_APP_LAYER_PROTOCOL, |
0ed11906 VJ |
246 | PrefilterPacketAppProtoSet, |
247 | PrefilterPacketAppProtoCompare, | |
248 | PrefilterPacketAppProtoMatch); | |
249 | } | |
250 | ||
be4c6b85 | 251 | static bool PrefilterAppProtoIsPrefilterable(const Signature *s) |
0ed11906 VJ |
252 | { |
253 | if (s->flags & SIG_FLAG_PDONLY) { | |
254 | SCLogDebug("prefilter on PD %u", s->id); | |
1eeb9669 | 255 | return true; |
0ed11906 | 256 | } |
1eeb9669 | 257 | return false; |
0ed11906 VJ |
258 | } |
259 | ||
94e40907 AS |
260 | void DetectAppLayerProtocolRegister(void) |
261 | { | |
262 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].name = "app-layer-protocol"; | |
d801c3e5 | 263 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].desc = "match on the detected app-layer protocol"; |
26bcc975 | 264 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].url = "/rules/app-layer.html#app-layer-protocol"; |
7d7ec78c VJ |
265 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Match = |
266 | DetectAppLayerProtocolPacketMatch; | |
94e40907 AS |
267 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Setup = |
268 | DetectAppLayerProtocolSetup; | |
269 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].Free = | |
270 | DetectAppLayerProtocolFree; | |
6ab323d3 | 271 | #ifdef UNITTESTS |
94e40907 AS |
272 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].RegisterTests = |
273 | DetectAppLayerProtocolRegisterTests; | |
6ab323d3 | 274 | #endif |
ab1200fb VJ |
275 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].flags = |
276 | (SIGMATCH_QUOTES_OPTIONAL|SIGMATCH_HANDLE_NEGATION); | |
94e40907 | 277 | |
0ed11906 VJ |
278 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].SetupPrefilter = |
279 | PrefilterSetupAppProto; | |
280 | sigmatch_table[DETECT_AL_APP_LAYER_PROTOCOL].SupportsPrefilter = | |
281 | PrefilterAppProtoIsPrefilterable; | |
94e40907 AS |
282 | return; |
283 | } | |
284 | ||
285 | /**********************************Unittests***********************************/ | |
286 | ||
287 | #ifdef UNITTESTS | |
288 | ||
e955cf33 | 289 | static int DetectAppLayerProtocolTest01(void) |
94e40907 | 290 | { |
ab1200fb | 291 | DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", false); |
e955cf33 | 292 | FAIL_IF_NULL(data); |
707f0272 | 293 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
e955cf33 | 294 | FAIL_IF(data->negated != 0); |
d3a65fe1 | 295 | DetectAppLayerProtocolFree(NULL, data); |
e955cf33 | 296 | PASS; |
94e40907 AS |
297 | } |
298 | ||
e955cf33 | 299 | static int DetectAppLayerProtocolTest02(void) |
94e40907 | 300 | { |
ab1200fb | 301 | DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("http", true); |
e955cf33 | 302 | FAIL_IF_NULL(data); |
707f0272 | 303 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
e955cf33 | 304 | FAIL_IF(data->negated == 0); |
d3a65fe1 | 305 | DetectAppLayerProtocolFree(NULL, data); |
e955cf33 | 306 | PASS; |
94e40907 AS |
307 | } |
308 | ||
e955cf33 | 309 | static int DetectAppLayerProtocolTest03(void) |
94e40907 | 310 | { |
94e40907 AS |
311 | Signature *s = NULL; |
312 | DetectAppLayerProtocolData *data = NULL; | |
313 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); | |
e955cf33 | 314 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
315 | de_ctx->flags |= DE_QUIET; |
316 | ||
e955cf33 VJ |
317 | s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any " |
318 | "(app-layer-protocol:http; sid:1;)"); | |
319 | FAIL_IF_NULL(s); | |
94e40907 | 320 | |
449c93e0 | 321 | FAIL_IF(s->alproto != ALPROTO_UNKNOWN); |
94e40907 | 322 | |
449c93e0 VJ |
323 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]); |
324 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx); | |
e955cf33 | 325 | |
449c93e0 | 326 | data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx; |
707f0272 | 327 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
e955cf33 | 328 | FAIL_IF(data->negated); |
94e40907 | 329 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 330 | PASS; |
94e40907 AS |
331 | } |
332 | ||
e955cf33 | 333 | static int DetectAppLayerProtocolTest04(void) |
94e40907 | 334 | { |
94e40907 AS |
335 | Signature *s = NULL; |
336 | DetectAppLayerProtocolData *data = NULL; | |
337 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); | |
e955cf33 | 338 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
339 | de_ctx->flags |= DE_QUIET; |
340 | ||
e955cf33 VJ |
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); | |
94e40907 | 346 | |
e955cf33 VJ |
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); | |
707f0272 | 352 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
e955cf33 | 353 | FAIL_IF(data->negated == 0); |
94e40907 | 354 | |
94e40907 | 355 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 356 | PASS; |
94e40907 AS |
357 | } |
358 | ||
e955cf33 | 359 | static int DetectAppLayerProtocolTest05(void) |
94e40907 | 360 | { |
94e40907 | 361 | Signature *s = NULL; |
e955cf33 | 362 | DetectAppLayerProtocolData *data = NULL; |
94e40907 | 363 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
e955cf33 | 364 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
365 | de_ctx->flags |= DE_QUIET; |
366 | ||
e955cf33 VJ |
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 | ||
e955cf33 VJ |
373 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]); |
374 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx); | |
94e40907 | 375 | |
e955cf33 VJ |
376 | data = (DetectAppLayerProtocolData*)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx; |
377 | FAIL_IF_NULL(data); | |
707f0272 | 378 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
e955cf33 VJ |
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); | |
94e40907 | 385 | |
94e40907 | 386 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 387 | PASS; |
94e40907 AS |
388 | } |
389 | ||
e955cf33 | 390 | static int DetectAppLayerProtocolTest06(void) |
94e40907 | 391 | { |
94e40907 AS |
392 | Signature *s = NULL; |
393 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); | |
e955cf33 | 394 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
395 | de_ctx->flags |= DE_QUIET; |
396 | ||
e955cf33 VJ |
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 | } | |
94e40907 | 403 | |
e955cf33 VJ |
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; | |
94e40907 | 410 | |
e955cf33 VJ |
411 | s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any " |
412 | "(app-layer-protocol:!smtp; sid:1;)"); | |
413 | FAIL_IF_NOT_NULL(s); | |
94e40907 | 414 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 415 | PASS; |
94e40907 AS |
416 | } |
417 | ||
e955cf33 | 418 | static int DetectAppLayerProtocolTest08(void) |
94e40907 | 419 | { |
94e40907 AS |
420 | Signature *s = NULL; |
421 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); | |
e955cf33 | 422 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
423 | de_ctx->flags |= DE_QUIET; |
424 | ||
e955cf33 VJ |
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 | } | |
94e40907 | 431 | |
e955cf33 VJ |
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; | |
94e40907 | 438 | |
e955cf33 VJ |
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); | |
94e40907 | 442 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 443 | PASS; |
94e40907 AS |
444 | } |
445 | ||
e955cf33 | 446 | static int DetectAppLayerProtocolTest10(void) |
94e40907 | 447 | { |
94e40907 AS |
448 | Signature *s = NULL; |
449 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); | |
e955cf33 | 450 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
451 | de_ctx->flags |= DE_QUIET; |
452 | ||
e955cf33 VJ |
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 | } | |
94e40907 | 459 | |
e955cf33 VJ |
460 | static int DetectAppLayerProtocolTest11(void) |
461 | { | |
ab1200fb | 462 | DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", false); |
e955cf33 VJ |
463 | FAIL_IF_NULL(data); |
464 | FAIL_IF(data->alproto != ALPROTO_FAILED); | |
465 | FAIL_IF(data->negated != 0); | |
d3a65fe1 | 466 | DetectAppLayerProtocolFree(NULL, data); |
e955cf33 VJ |
467 | PASS; |
468 | } | |
94e40907 | 469 | |
e955cf33 VJ |
470 | static int DetectAppLayerProtocolTest12(void) |
471 | { | |
ab1200fb | 472 | DetectAppLayerProtocolData *data = DetectAppLayerProtocolParse("failed", true); |
e955cf33 VJ |
473 | FAIL_IF_NULL(data); |
474 | FAIL_IF(data->alproto != ALPROTO_FAILED); | |
475 | FAIL_IF(data->negated == 0); | |
d3a65fe1 | 476 | DetectAppLayerProtocolFree(NULL, data); |
e955cf33 | 477 | PASS; |
94e40907 AS |
478 | } |
479 | ||
e955cf33 | 480 | static int DetectAppLayerProtocolTest13(void) |
94e40907 | 481 | { |
94e40907 | 482 | Signature *s = NULL; |
e955cf33 | 483 | DetectAppLayerProtocolData *data = NULL; |
94e40907 | 484 | DetectEngineCtx *de_ctx = DetectEngineCtxInit(); |
e955cf33 | 485 | FAIL_IF_NULL(de_ctx); |
94e40907 AS |
486 | de_ctx->flags |= DE_QUIET; |
487 | ||
e955cf33 VJ |
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); | |
94e40907 | 493 | |
e955cf33 VJ |
494 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]); |
495 | FAIL_IF_NULL(s->sm_lists[DETECT_SM_LIST_MATCH]->ctx); | |
94e40907 | 496 | |
e955cf33 VJ |
497 | data = (DetectAppLayerProtocolData *)s->sm_lists[DETECT_SM_LIST_MATCH]->ctx; |
498 | FAIL_IF(data->alproto != ALPROTO_FAILED); | |
499 | FAIL_IF(data->negated); | |
94e40907 | 500 | DetectEngineCtxFree(de_ctx); |
e955cf33 | 501 | PASS; |
94e40907 AS |
502 | } |
503 | ||
449c93e0 VJ |
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; | |
707f0272 | 518 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
449c93e0 VJ |
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; | |
707f0272 | 528 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
449c93e0 VJ |
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; | |
707f0272 | 539 | FAIL_IF(data->alproto != ALPROTO_HTTP); |
449c93e0 VJ |
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 | ||
94e40907 | 551 | |
6022fa44 | 552 | static void DetectAppLayerProtocolRegisterTests(void) |
94e40907 | 553 | { |
796dd522 JI |
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); | |
e955cf33 VJ |
572 | UtRegisterTest("DetectAppLayerProtocolTest10", |
573 | DetectAppLayerProtocolTest10); | |
574 | UtRegisterTest("DetectAppLayerProtocolTest11", | |
575 | DetectAppLayerProtocolTest11); | |
576 | UtRegisterTest("DetectAppLayerProtocolTest12", | |
577 | DetectAppLayerProtocolTest12); | |
578 | UtRegisterTest("DetectAppLayerProtocolTest13", | |
579 | DetectAppLayerProtocolTest13); | |
449c93e0 VJ |
580 | UtRegisterTest("DetectAppLayerProtocolTest14", |
581 | DetectAppLayerProtocolTest14); | |
94e40907 | 582 | } |
6ab323d3 | 583 | #endif /* UNITTESTS */ |