1 /* Copyright (C) 2007-2020 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 Victor Julien <victor@inliniac.net>
22 *
23 * Generic App-layer parsing functions.
24 */
25
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "util-unittest.h"
29 #include "decode.h"
30 #include "threads.h"
31
32 #include "util-print.h"
33 #include "util-pool.h"
34
35 #include "flow-util.h"
36 #include "flow-private.h"
37
38 #include "detect-engine-state.h"
39 #include "detect-engine-port.h"
40
41 #include "stream-tcp.h"
42 #include "stream-tcp-private.h"
43 #include "stream.h"
44 #include "stream-tcp-reassemble.h"
45
46 #include "app-layer.h"
47 #include "app-layer-protos.h"
48 #include "app-layer-parser.h"
49 #include "app-layer-dcerpc.h"
50 #include "app-layer-dcerpc-udp.h"
51 #include "app-layer-smb.h"
52 #include "app-layer-htp.h"
53 #include "app-layer-ftp.h"
54 #include "app-layer-ssl.h"
55 #include "app-layer-ssh.h"
56 #include "app-layer-smtp.h"
57 #include "app-layer-modbus.h"
58 #include "app-layer-enip.h"
59 #include "app-layer-dnp3.h"
60 #include "app-layer-nfs-tcp.h"
61 #include "app-layer-nfs-udp.h"
62 #include "app-layer-ntp.h"
63 #include "app-layer-tftp.h"
64 #include "app-layer-ikev2.h"
65 #include "app-layer-krb5.h"
66 #include "app-layer-snmp.h"
67 #include "app-layer-sip.h"
68 #include "app-layer-rfb.h"
69 #include "app-layer-mqtt.h"
70 #include "app-layer-template.h"
71 #include "app-layer-template-rust.h"
72 #include "app-layer-rdp.h"
73 #include "app-layer-http2.h"
74
75 #include "conf.h"
76 #include "util-spm.h"
77
78 #include "util-debug.h"
79 #include "decode-events.h"
80 #include "util-unittest-helper.h"
81 #include "util-validate.h"
82
83 #include "runmodes.h"
84
85 #include "rust.h"
86
87 struct AppLayerParserThreadCtx_ {
88 void *alproto_local_storage[FLOW_PROTO_MAX][ALPROTO_MAX];
89 };
90
91
92 /**
93 * \brief App layer protocol parser context.
94 */
95 typedef struct AppLayerParserProtoCtx_
96 {
97 /* 0 - to_server, 1 - to_client. */
98 AppLayerParserFPtr Parser[2];
99 bool logger;
100 uint32_t logger_bits; /**< registered loggers for this proto */
101
102 void *(*StateAlloc)(void *, AppProto);
103 void (*StateFree)(void *);
104 void (*StateTransactionFree)(void *, uint64_t);
105 void *(*LocalStorageAlloc)(void);
106 void (*LocalStorageFree)(void *);
107
108 void (*Truncate)(void *, uint8_t);
109 FileContainer *(*StateGetFiles)(void *, uint8_t);
110 AppLayerDecoderEvents *(*StateGetEvents)(void *);
111
112 int (*StateGetProgress)(void *alstate, uint8_t direction);
113 uint64_t (*StateGetTxCnt)(void *alstate);
114 void *(*StateGetTx)(void *alstate, uint64_t tx_id);
115 AppLayerGetTxIteratorFunc StateGetTxIterator;
116 int (*StateGetProgressCompletionStatus)(uint8_t direction);
117 int (*StateGetEventInfoById)(int event_id, const char **event_name,
118 AppLayerEventType *event_type);
119 int (*StateGetEventInfo)(const char *event_name,
120 int *event_id, AppLayerEventType *event_type);
121
122 DetectEngineState *(*GetTxDetectState)(void *tx);
123 int (*SetTxDetectState)(void *tx, DetectEngineState *);
124
125 AppLayerTxData *(*GetTxData)(void *tx);
126 bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig);
127
128 void (*SetStreamDepthFlag)(void *tx, uint8_t flags);
129
130 /* each app-layer has its own value */
131 uint32_t stream_depth;
132
133 /* Indicates the direction the parser is ready to see the data
134 * the first time for a flow. Values accepted -
135 * STREAM_TOSERVER, STREAM_TOCLIENT */
136 uint8_t first_data_dir;
137
138 /* Option flags such as supporting gaps or not. */
139 uint32_t option_flags;
140 /* coccinelle: AppLayerParserProtoCtx:option_flags:APP_LAYER_PARSER_OPT_ */
141
142 uint32_t internal_flags;
143 /* coccinelle: AppLayerParserProtoCtx:internal_flags:APP_LAYER_PARSER_INT_ */
144
145 #ifdef UNITTESTS
146 void (*RegisterUnittests)(void);
147 #endif
148 } AppLayerParserProtoCtx;
149
150 typedef struct AppLayerParserCtx_ {
151 AppLayerParserProtoCtx ctxs[FLOW_PROTO_MAX][ALPROTO_MAX];
152 } AppLayerParserCtx;
153
154 struct AppLayerParserState_ {
155 /* coccinelle: AppLayerParserState:flags:APP_LAYER_PARSER_ */
156 uint8_t flags;
157
158 /* Indicates the current transaction that is being inspected.
159 * We have a var per direction. */
160 uint64_t inspect_id[2];
161 /* Indicates the current transaction being logged. Unlike inspect_id,
162 * we don't need a var per direction since we don't log a transaction
163 * unless we have the entire transaction. */
164 uint64_t log_id;
165
166 uint64_t min_id;
167
168 /* Used to store decoder events. */
169 AppLayerDecoderEvents *decoder_events;
170 };
171
172 #ifdef UNITTESTS
UTHAppLayerParserStateGetIds(void * ptr,uint64_t * i1,uint64_t * i2,uint64_t * log,uint64_t * min)173 void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min)
174 {
175 struct AppLayerParserState_ *s = ptr;
176 *i1 = s->inspect_id[0];
177 *i2 = s->inspect_id[1];
178 *log = s->log_id;
179 *min = s->min_id;
180 }
181 #endif
182
183 /* Static global version of the parser context.
184 * Post 2.0 let's look at changing this to move it out to app-layer.c. */
185 static AppLayerParserCtx alp_ctx;
186
AppLayerParserProtoIsRegistered(uint8_t ipproto,AppProto alproto)187 int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
188 {
189 uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
190
191 return (alp_ctx.ctxs[ipproto_map][alproto].StateAlloc != NULL) ? 1 : 0;
192 }
193
AppLayerParserStateAlloc(void)194 AppLayerParserState *AppLayerParserStateAlloc(void)
195 {
196 SCEnter();
197
198 AppLayerParserState *pstate = (AppLayerParserState *)SCMalloc(sizeof(*pstate));
199 if (pstate == NULL)
200 goto end;
201 memset(pstate, 0, sizeof(*pstate));
202
203 end:
204 SCReturnPtr(pstate, "AppLayerParserState");
205 }
206
AppLayerParserStateFree(AppLayerParserState * pstate)207 void AppLayerParserStateFree(AppLayerParserState *pstate)
208 {
209 SCEnter();
210
211 if (pstate->decoder_events != NULL)
212 AppLayerDecoderEventsFreeEvents(&pstate->decoder_events);
213 SCFree(pstate);
214
215 SCReturn;
216 }
217
218 bool g_config_http1keywords_http2traffic = false;
219
AppLayerParserSetup(void)220 int AppLayerParserSetup(void)
221 {
222 SCEnter();
223 memset(&alp_ctx, 0, sizeof(alp_ctx));
224 int value = 0;
225 if (ConfGetBool("app-layer.protocols.http2.http1-rules", &value) == 1 && value == 1) {
226 g_config_http1keywords_http2traffic = true;
227 }
228 SCReturnInt(0);
229 }
230
AppLayerParserPostStreamSetup(void)231 void AppLayerParserPostStreamSetup(void)
232 {
233 AppProto alproto = 0;
234 int flow_proto = 0;
235
236 /* lets set a default value for stream_depth */
237 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
238 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
239 if (!(alp_ctx.ctxs[flow_proto][alproto].internal_flags &
240 APP_LAYER_PARSER_INT_STREAM_DEPTH_SET)) {
241 alp_ctx.ctxs[flow_proto][alproto].stream_depth =
242 stream_config.reassembly_depth;
243 }
244 }
245 }
246 }
247
AppLayerParserDeSetup(void)248 int AppLayerParserDeSetup(void)
249 {
250 SCEnter();
251
252 FTPParserCleanup();
253 SMTPParserCleanup();
254
255 SCReturnInt(0);
256 }
257
AppLayerParserThreadCtxAlloc(void)258 AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void)
259 {
260 SCEnter();
261
262 AppProto alproto = 0;
263 int flow_proto = 0;
264 AppLayerParserThreadCtx *tctx;
265
266 tctx = SCMalloc(sizeof(*tctx));
267 if (tctx == NULL)
268 goto end;
269 memset(tctx, 0, sizeof(*tctx));
270
271 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
272 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
273 uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
274
275 tctx->alproto_local_storage[flow_proto][alproto] =
276 AppLayerParserGetProtocolParserLocalStorage(ipproto, alproto);
277 }
278 }
279
280 end:
281 SCReturnPtr(tctx, "void *");
282 }
283
AppLayerParserThreadCtxFree(AppLayerParserThreadCtx * tctx)284 void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
285 {
286 SCEnter();
287
288 AppProto alproto = 0;
289 int flow_proto = 0;
290
291 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
292 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
293 uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
294
295 AppLayerParserDestroyProtocolParserLocalStorage(ipproto, alproto,
296 tctx->alproto_local_storage[flow_proto][alproto]);
297 }
298 }
299
300 SCFree(tctx);
301 SCReturn;
302 }
303
304 /** \brief check if a parser is enabled in the config
305 * Returns enabled always if: were running unittests
306 */
AppLayerParserConfParserEnabled(const char * ipproto,const char * alproto_name)307 int AppLayerParserConfParserEnabled(const char *ipproto,
308 const char *alproto_name)
309 {
310 SCEnter();
311
312 int enabled = 1;
313 char param[100];
314 ConfNode *node;
315 int r;
316
317 if (RunmodeIsUnittests())
318 goto enabled;
319
320 r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.",
321 alproto_name, ".enabled");
322 if (r < 0) {
323 FatalError(SC_ERR_FATAL, "snprintf failure.");
324 } else if (r > (int)sizeof(param)) {
325 FatalError(SC_ERR_FATAL, "buffer not big enough to write param.");
326 }
327
328 node = ConfGetNode(param);
329 if (node == NULL) {
330 SCLogDebug("Entry for %s not found.", param);
331 r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
332 alproto_name, ".", ipproto, ".enabled");
333 if (r < 0) {
334 FatalError(SC_ERR_FATAL, "snprintf failure.");
335 } else if (r > (int)sizeof(param)) {
336 FatalError(SC_ERR_FATAL, "buffer not big enough to write param.");
337 }
338
339 node = ConfGetNode(param);
340 if (node == NULL) {
341 SCLogDebug("Entry for %s not found.", param);
342 goto enabled;
343 }
344 }
345
346 if (ConfValIsTrue(node->val)) {
347 goto enabled;
348 } else if (ConfValIsFalse(node->val)) {
349 goto disabled;
350 } else if (strcasecmp(node->val, "detection-only") == 0) {
351 goto disabled;
352 } else {
353 SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param);
354 exit(EXIT_FAILURE);
355 }
356
357 disabled:
358 enabled = 0;
359 enabled:
360 SCReturnInt(enabled);
361 }
362
363 /***** Parser related registration *****/
364
AppLayerParserRegisterParser(uint8_t ipproto,AppProto alproto,uint8_t direction,AppLayerParserFPtr Parser)365 int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto,
366 uint8_t direction,
367 AppLayerParserFPtr Parser)
368 {
369 SCEnter();
370
371 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
372 Parser[(direction & STREAM_TOSERVER) ? 0 : 1] = Parser;
373
374 SCReturnInt(0);
375 }
376
AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto,AppProto alproto,uint8_t direction)377 void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto,
378 uint8_t direction)
379 {
380 SCEnter();
381
382 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].first_data_dir |=
383 (direction & (STREAM_TOSERVER | STREAM_TOCLIENT));
384
385 SCReturn;
386 }
387
AppLayerParserRegisterOptionFlags(uint8_t ipproto,AppProto alproto,uint32_t flags)388 void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto,
389 uint32_t flags)
390 {
391 SCEnter();
392
393 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].option_flags |= flags;
394
395 SCReturn;
396 }
397
AppLayerParserGetOptionFlags(uint8_t protomap,AppProto alproto)398 uint32_t AppLayerParserGetOptionFlags(uint8_t protomap, AppProto alproto)
399 {
400 SCEnter();
401 SCReturnUInt(alp_ctx.ctxs[protomap][alproto].option_flags);
402 }
403
AppLayerParserRegisterStateFuncs(uint8_t ipproto,AppProto alproto,void * (* StateAlloc)(void *,AppProto),void (* StateFree)(void *))404 void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
405 void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *))
406 {
407 SCEnter();
408
409 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateAlloc =
410 StateAlloc;
411 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateFree =
412 StateFree;
413
414 SCReturn;
415 }
416
AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto,AppProto alproto,void * (* LocalStorageAlloc)(void),void (* LocalStorageFree)(void *))417 void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto alproto,
418 void *(*LocalStorageAlloc)(void),
419 void (*LocalStorageFree)(void *))
420 {
421 SCEnter();
422
423 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageAlloc =
424 LocalStorageAlloc;
425 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageFree =
426 LocalStorageFree;
427
428 SCReturn;
429 }
430
AppLayerParserRegisterGetFilesFunc(uint8_t ipproto,AppProto alproto,FileContainer * (* StateGetFiles)(void *,uint8_t))431 void AppLayerParserRegisterGetFilesFunc(uint8_t ipproto, AppProto alproto,
432 FileContainer *(*StateGetFiles)(void *, uint8_t))
433 {
434 SCEnter();
435
436 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles =
437 StateGetFiles;
438
439 SCReturn;
440 }
441
AppLayerParserRegisterGetEventsFunc(uint8_t ipproto,AppProto alproto,AppLayerDecoderEvents * (* StateGetEvents)(void *))442 void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto,
443 AppLayerDecoderEvents *(*StateGetEvents)(void *))
444 {
445 SCEnter();
446
447 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetEvents =
448 StateGetEvents;
449
450 SCReturn;
451 }
452
AppLayerParserRegisterLoggerBits(uint8_t ipproto,AppProto alproto,LoggerId bits)453 void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits)
454 {
455 SCEnter();
456
457 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger_bits = bits;
458
459 SCReturn;
460 }
461
AppLayerParserRegisterLogger(uint8_t ipproto,AppProto alproto)462 void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
463 {
464 SCEnter();
465
466 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger = true;
467
468 SCReturn;
469 }
470
AppLayerParserRegisterTruncateFunc(uint8_t ipproto,AppProto alproto,void (* Truncate)(void *,uint8_t))471 void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto,
472 void (*Truncate)(void *, uint8_t))
473 {
474 SCEnter();
475
476 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate = Truncate;
477
478 SCReturn;
479 }
480
AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto,AppProto alproto,int (* StateGetProgress)(void * alstate,uint8_t direction))481 void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto,
482 int (*StateGetProgress)(void *alstate, uint8_t direction))
483 {
484 SCEnter();
485
486 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
487 StateGetProgress = StateGetProgress;
488
489 SCReturn;
490 }
491
AppLayerParserRegisterTxFreeFunc(uint8_t ipproto,AppProto alproto,void (* StateTransactionFree)(void *,uint64_t))492 void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto,
493 void (*StateTransactionFree)(void *, uint64_t))
494 {
495 SCEnter();
496
497 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
498 StateTransactionFree = StateTransactionFree;
499
500 SCReturn;
501 }
502
AppLayerParserRegisterGetTxCnt(uint8_t ipproto,AppProto alproto,uint64_t (* StateGetTxCnt)(void * alstate))503 void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto,
504 uint64_t (*StateGetTxCnt)(void *alstate))
505 {
506 SCEnter();
507
508 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
509 StateGetTxCnt = StateGetTxCnt;
510
511 SCReturn;
512 }
513
AppLayerParserRegisterGetTx(uint8_t ipproto,AppProto alproto,void * (StateGetTx)(void * alstate,uint64_t tx_id))514 void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto,
515 void *(StateGetTx)(void *alstate, uint64_t tx_id))
516 {
517 SCEnter();
518
519 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
520 StateGetTx = StateGetTx;
521
522 SCReturn;
523 }
524
AppLayerParserRegisterGetTxIterator(uint8_t ipproto,AppProto alproto,AppLayerGetTxIteratorFunc Func)525 void AppLayerParserRegisterGetTxIterator(uint8_t ipproto, AppProto alproto,
526 AppLayerGetTxIteratorFunc Func)
527 {
528 SCEnter();
529 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTxIterator = Func;
530 SCReturn;
531 }
532
AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto,int (* StateGetProgressCompletionStatus)(uint8_t direction))533 void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto,
534 int (*StateGetProgressCompletionStatus)(uint8_t direction))
535 {
536 SCEnter();
537
538 alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
539 StateGetProgressCompletionStatus = StateGetProgressCompletionStatus;
540
541 SCReturn;
542 }
543
AppLayerParserRegisterGetEventInfoById(uint8_t ipproto,AppProto alproto,int (* StateGetEventInfoById)(int event_id,const char ** event_name,AppLayerEventType * event_type))544 void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto,
545 int (*StateGetEventInfoById)(int event_id, const char **event_name,
546 AppLayerEventType *event_type))
547 {
548 SCEnter();
549
550 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
551 StateGetEventInfoById = StateGetEventInfoById;
552
553 SCReturn;
554 }
555
AppLayerParserRegisterGetEventInfo(uint8_t ipproto,AppProto alproto,int (* StateGetEventInfo)(const char * event_name,int * event_id,AppLayerEventType * event_type))556 void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto,
557 int (*StateGetEventInfo)(const char *event_name, int *event_id,
558 AppLayerEventType *event_type))
559 {
560 SCEnter();
561
562 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
563 StateGetEventInfo = StateGetEventInfo;
564
565 SCReturn;
566 }
567
AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto,AppProto alproto,DetectEngineState * (* GetTxDetectState)(void * tx),int (* SetTxDetectState)(void * tx,DetectEngineState *))568 void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto,
569 DetectEngineState *(*GetTxDetectState)(void *tx),
570 int (*SetTxDetectState)(void *tx, DetectEngineState *))
571 {
572 SCEnter();
573
574 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState = GetTxDetectState;
575 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxDetectState = SetTxDetectState;
576
577 SCReturn;
578 }
579
AppLayerParserRegisterTxDataFunc(uint8_t ipproto,AppProto alproto,AppLayerTxData * (* GetTxData)(void * tx))580 void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto,
581 AppLayerTxData *(*GetTxData)(void *tx))
582 {
583 SCEnter();
584
585 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData = GetTxData;
586
587 SCReturn;
588 }
589
AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto,AppProto alproto,bool (* ApplyTxConfig)(void * state,void * tx,int mode,AppLayerTxConfig))590 void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto,
591 bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig))
592 {
593 SCEnter();
594
595 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig = ApplyTxConfig;
596
597 SCReturn;
598 }
599
AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto,AppProto alproto,void (* SetStreamDepthFlag)(void * tx,uint8_t flags))600 void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto,
601 void (*SetStreamDepthFlag)(void *tx, uint8_t flags))
602 {
603 SCEnter();
604
605 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag = SetStreamDepthFlag;
606
607 SCReturn;
608 }
609
610 /***** Get and transaction functions *****/
611
AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto,AppProto alproto)612 void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto)
613 {
614 SCEnter();
615 void * r = NULL;
616
617 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
618 LocalStorageAlloc != NULL)
619 {
620 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
621 LocalStorageAlloc();
622 }
623
624 SCReturnPtr(r, "void *");
625 }
626
AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto,AppProto alproto,void * local_data)627 void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto,
628 void *local_data)
629 {
630 SCEnter();
631
632 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
633 LocalStorageFree != NULL)
634 {
635 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
636 LocalStorageFree(local_data);
637 }
638
639 SCReturn;
640 }
641
642 /** \brief default tx iterator
643 *
644 * Used if the app layer parser doesn't register its own iterator.
645 * Simply walks the tx_id space until it finds a tx. Uses 'state' to
646 * keep track of where it left off.
647 *
648 * \retval txptr or NULL if no more txs in list
649 */
AppLayerDefaultGetTxIterator(const uint8_t ipproto,const AppProto alproto,void * alstate,uint64_t min_tx_id,uint64_t max_tx_id,AppLayerGetTxIterState * state)650 static AppLayerGetTxIterTuple AppLayerDefaultGetTxIterator(
651 const uint8_t ipproto, const AppProto alproto,
652 void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
653 AppLayerGetTxIterState *state)
654 {
655 uint64_t ustate = *(uint64_t *)state;
656 uint64_t tx_id = MAX(min_tx_id, ustate);
657 for ( ; tx_id < max_tx_id; tx_id++) {
658 void *tx_ptr = AppLayerParserGetTx(ipproto, alproto, alstate, tx_id);
659 if (tx_ptr != NULL) {
660 ustate = tx_id + 1;
661 *state = *(AppLayerGetTxIterState *)&ustate;
662 AppLayerGetTxIterTuple tuple = {
663 .tx_ptr = tx_ptr,
664 .tx_id = tx_id,
665 .has_next = (tx_id + 1 < max_tx_id),
666 };
667 SCLogDebug("tuple: %p/%"PRIu64"/%s", tuple.tx_ptr, tuple.tx_id,
668 tuple.has_next ? "true" : "false");
669 return tuple;
670 }
671 }
672
673 AppLayerGetTxIterTuple no_tuple = { NULL, 0, false };
674 return no_tuple;
675 }
676
AppLayerGetTxIterator(const uint8_t ipproto,const AppProto alproto)677 AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto,
678 const AppProto alproto)
679 {
680 AppLayerGetTxIteratorFunc Func =
681 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTxIterator;
682 return Func ? Func : AppLayerDefaultGetTxIterator;
683 }
684
AppLayerParserGetTransactionLogId(AppLayerParserState * pstate)685 uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate)
686 {
687 SCEnter();
688
689 SCReturnCT((pstate == NULL) ? 0 : pstate->log_id, "uint64_t");
690 }
691
AppLayerParserSetTransactionLogId(AppLayerParserState * pstate,uint64_t tx_id)692 void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id)
693 {
694 SCEnter();
695
696 if (pstate != NULL)
697 pstate->log_id = tx_id;
698
699 SCReturn;
700 }
701
AppLayerParserGetTransactionInspectId(AppLayerParserState * pstate,uint8_t direction)702 uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
703 {
704 SCEnter();
705
706 if (pstate == NULL)
707 SCReturnCT(0ULL, "uint64_t");
708
709 SCReturnCT(pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1], "uint64_t");
710 }
711
GetTxDetectFlags(AppLayerTxData * txd,const uint8_t dir)712 static inline uint64_t GetTxDetectFlags(AppLayerTxData *txd, const uint8_t dir)
713 {
714 uint64_t detect_flags =
715 (dir & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
716 return detect_flags;
717 }
718
SetTxDetectFlags(AppLayerTxData * txd,const uint8_t dir,const uint64_t detect_flags)719 static inline void SetTxDetectFlags(AppLayerTxData *txd, const uint8_t dir, const uint64_t detect_flags)
720 {
721 if (dir & STREAM_TOSERVER) {
722 txd->detect_flags_ts = detect_flags;
723 } else {
724 txd->detect_flags_tc = detect_flags;
725 }
726 }
727
GetTxLogged(AppLayerTxData * txd)728 static inline uint32_t GetTxLogged(AppLayerTxData *txd)
729 {
730 return txd->logged.flags;
731 }
732
AppLayerParserSetTransactionInspectId(const Flow * f,AppLayerParserState * pstate,void * alstate,const uint8_t flags,bool tag_txs_as_inspected)733 void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
734 void *alstate, const uint8_t flags,
735 bool tag_txs_as_inspected)
736 {
737 SCEnter();
738
739 const int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
740 const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
741 uint64_t idx = AppLayerParserGetTransactionInspectId(pstate, flags);
742 const int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(f->alproto, flags);
743 const uint8_t ipproto = f->proto;
744 const AppProto alproto = f->alproto;
745
746 AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
747 AppLayerGetTxIterState state;
748 memset(&state, 0, sizeof(state));
749
750 SCLogDebug("called: %s, tag_txs_as_inspected %s",direction==0?"toserver":"toclient",
751 tag_txs_as_inspected?"true":"false");
752
753 /* mark all txs as inspected if the applayer progress is
754 * at the 'end state'. */
755 while (1) {
756 AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, idx, total_txs, &state);
757 if (ires.tx_ptr == NULL)
758 break;
759
760 void *tx = ires.tx_ptr;
761 idx = ires.tx_id;
762
763 int state_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags);
764 if (state_progress < state_done_progress)
765 break;
766
767 AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
768 if (txd && tag_txs_as_inspected) {
769 uint64_t detect_flags = GetTxDetectFlags(txd, flags);
770 if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
771 detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
772 SetTxDetectFlags(txd, flags, detect_flags);
773 SCLogDebug("%p/%"PRIu64" in-order tx is done for direction %s. Flag %016"PRIx64,
774 tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
775 }
776 }
777 idx++;
778 if (!ires.has_next)
779 break;
780 }
781 pstate->inspect_id[direction] = idx;
782 SCLogDebug("inspect_id now %"PRIu64, pstate->inspect_id[direction]);
783
784 /* if necessary we flag all txs that are complete as 'inspected'
785 * also move inspect_id forward. */
786 if (tag_txs_as_inspected) {
787 /* continue at idx */
788 while (1) {
789 AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, idx, total_txs, &state);
790 if (ires.tx_ptr == NULL)
791 break;
792
793 void *tx = ires.tx_ptr;
794 /* if we got a higher id than the minimum we requested, we
795 * skipped a bunch of 'null-txs'. Lets see if we can up the
796 * inspect tracker */
797 if (ires.tx_id > idx && pstate->inspect_id[direction] == idx) {
798 pstate->inspect_id[direction] = ires.tx_id;
799 }
800 idx = ires.tx_id;
801
802 const int state_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags);
803 if (state_progress < state_done_progress)
804 break;
805
806 /* txd can be NULL for HTTP sessions where the user data alloc failed */
807 AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
808 if (likely(txd)) {
809 uint64_t detect_flags = GetTxDetectFlags(txd, flags);
810 if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
811 detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
812 SetTxDetectFlags(txd, flags, detect_flags);
813 SCLogDebug("%p/%"PRIu64" out of order tx is done for direction %s. Flag %016"PRIx64,
814 tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
815
816 SCLogDebug("%p/%"PRIu64" out of order tx. Update inspect_id? %"PRIu64,
817 tx, idx, pstate->inspect_id[direction]);
818 if (pstate->inspect_id[direction]+1 == idx)
819 pstate->inspect_id[direction] = idx;
820 }
821 } else {
822 if (pstate->inspect_id[direction]+1 == idx)
823 pstate->inspect_id[direction] = idx;
824 }
825 if (!ires.has_next)
826 break;
827 idx++;
828 }
829 }
830
831 SCReturn;
832 }
833
AppLayerParserGetDecoderEvents(AppLayerParserState * pstate)834 AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate)
835 {
836 SCEnter();
837
838 SCReturnPtr(pstate->decoder_events,
839 "AppLayerDecoderEvents *");
840 }
841
AppLayerParserSetDecoderEvents(AppLayerParserState * pstate,AppLayerDecoderEvents * devents)842 void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents)
843 {
844 pstate->decoder_events = devents;
845 }
846
AppLayerParserGetEventsByTx(uint8_t ipproto,AppProto alproto,void * tx)847 AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto,
848 void *tx)
849 {
850 SCEnter();
851
852 AppLayerDecoderEvents *ptr = NULL;
853
854 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
855 StateGetEvents != NULL)
856 {
857 ptr = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
858 StateGetEvents(tx);
859 }
860
861 SCReturnPtr(ptr, "AppLayerDecoderEvents *");
862 }
863
AppLayerParserGetFiles(const Flow * f,const uint8_t direction)864 FileContainer *AppLayerParserGetFiles(const Flow *f, const uint8_t direction)
865 {
866 SCEnter();
867
868 FileContainer *ptr = NULL;
869
870 if (alp_ctx.ctxs[f->protomap][f->alproto].StateGetFiles != NULL)
871 {
872 ptr = alp_ctx.ctxs[f->protomap][f->alproto].
873 StateGetFiles(f->alstate, direction);
874 }
875
876 SCReturnPtr(ptr, "FileContainer *");
877 }
878
879 #define IS_DISRUPTED(flags) ((flags) & (STREAM_DEPTH | STREAM_GAP))
880
881 extern int g_detect_disabled;
882 extern bool g_file_logger_enabled;
883 extern bool g_filedata_logger_enabled;
884
885 /**
886 * \brief remove obsolete (inspected and logged) transactions
887 */
AppLayerParserTransactionsCleanup(Flow * f)888 void AppLayerParserTransactionsCleanup(Flow *f)
889 {
890 SCEnter();
891 DEBUG_ASSERT_FLOW_LOCKED(f);
892
893 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][f->alproto];
894 if (unlikely(p->StateTransactionFree == NULL))
895 SCReturn;
896
897 const bool has_tx_detect_flags = (p->GetTxData != NULL && !g_detect_disabled);
898 const uint8_t ipproto = f->proto;
899 const AppProto alproto = f->alproto;
900 void * const alstate = f->alstate;
901 AppLayerParserState * const alparser = f->alparser;
902
903 if (alstate == NULL || alparser == NULL)
904 SCReturn;
905
906 const uint64_t min = alparser->min_id;
907 const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
908 const LoggerId logger_expectation = AppLayerParserProtocolGetLoggerBits(ipproto, alproto);
909 const int tx_end_state_ts = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOSERVER);
910 const int tx_end_state_tc = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOCLIENT);
911 const uint8_t ts_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOSERVER);
912 const uint8_t tc_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOCLIENT);
913
914 AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
915 AppLayerGetTxIterState state;
916 memset(&state, 0, sizeof(state));
917 uint64_t i = min;
918 uint64_t new_min = min;
919 SCLogDebug("start min %"PRIu64, min);
920 bool skipped = false;
921 const bool is_unidir =
922 AppLayerParserGetOptionFlags(f->protomap, f->alproto) & APP_LAYER_PARSER_OPT_UNIDIR_TXS;
923
924 while (1) {
925 AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, i, total_txs, &state);
926 if (ires.tx_ptr == NULL)
927 break;
928
929 bool tx_skipped = false;
930 void *tx = ires.tx_ptr;
931 i = ires.tx_id; // actual tx id for the tx the IterFunc returned
932
933 SCLogDebug("%p/%"PRIu64" checking", tx, i);
934
935 const int tx_progress_tc =
936 AppLayerParserGetStateProgress(ipproto, alproto, tx, tc_disrupt_flags);
937 if (tx_progress_tc < tx_end_state_tc) {
938 SCLogDebug("%p/%"PRIu64" skipping: tc parser not done", tx, i);
939 skipped = true;
940 goto next;
941 }
942 const int tx_progress_ts =
943 AppLayerParserGetStateProgress(ipproto, alproto, tx, ts_disrupt_flags);
944 if (tx_progress_ts < tx_end_state_ts) {
945 SCLogDebug("%p/%"PRIu64" skipping: ts parser not done", tx, i);
946 skipped = true;
947 goto next;
948 }
949
950 AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
951 bool inspected = false;
952 if (txd && has_tx_detect_flags) {
953 if (!IS_DISRUPTED(ts_disrupt_flags) && f->sgh_toserver != NULL) {
954 uint64_t detect_flags_ts = GetTxDetectFlags(txd, STREAM_TOSERVER);
955 if (!(detect_flags_ts & APP_LAYER_TX_INSPECTED_FLAG)) {
956 SCLogDebug("%p/%"PRIu64" skipping: TS inspect not done: ts:%"PRIx64,
957 tx, i, detect_flags_ts);
958 tx_skipped = true;
959 } else {
960 inspected = true;
961 }
962 }
963 if (!IS_DISRUPTED(tc_disrupt_flags) && f->sgh_toclient != NULL) {
964 uint64_t detect_flags_tc = GetTxDetectFlags(txd, STREAM_TOCLIENT);
965 if (!(detect_flags_tc & APP_LAYER_TX_INSPECTED_FLAG)) {
966 SCLogDebug("%p/%"PRIu64" skipping: TC inspect not done: tc:%"PRIx64,
967 tx, i, detect_flags_tc);
968 tx_skipped = true;
969 } else {
970 inspected = true;
971 }
972 }
973 }
974
975 // If not a unidirectional transaction both sides are required to have
976 // been inspected.
977 if (!is_unidir && tx_skipped) {
978 SCLogDebug("%p/%" PRIu64 " !is_unidir && tx_skipped", tx, i);
979 skipped = true;
980 goto next;
981 }
982
983 // If this is a unidirectional transaction require only one side to be
984 // inspected, which the inspected flag tells us. This is also guarded
985 // with skip to limit this check to transactions that actually had the
986 // tx inspected flag checked.
987 if (is_unidir && tx_skipped && !inspected) {
988 SCLogDebug("%p/%" PRIu64 " is_unidir && tx_skipped && !inspected", tx, i);
989 skipped = true;
990 goto next;
991 }
992
993 if (txd && logger_expectation != 0) {
994 LoggerId tx_logged = GetTxLogged(txd);
995 if (tx_logged != logger_expectation) {
996 SCLogDebug("%p/%"PRIu64" skipping: logging not done: want:%"PRIx32", have:%"PRIx32,
997 tx, i, logger_expectation, tx_logged);
998 skipped = true;
999 goto next;
1000 }
1001 }
1002
1003 /* if file logging is enabled, we keep a tx active while some of the files aren't
1004 * logged yet. */
1005 if (txd && txd->files_opened) {
1006 if (g_file_logger_enabled && txd->files_opened != txd->files_logged) {
1007 skipped = true;
1008 goto next;
1009 }
1010 if (g_filedata_logger_enabled && txd->files_opened != txd->files_stored) {
1011 skipped = true;
1012 goto next;
1013 }
1014 }
1015
1016 /* if we are here, the tx can be freed. */
1017 p->StateTransactionFree(alstate, i);
1018 SCLogDebug("%p/%"PRIu64" freed", tx, i);
1019
1020 /* if we didn't skip any tx so far, up the minimum */
1021 SCLogDebug("skipped? %s i %"PRIu64", new_min %"PRIu64, skipped ? "true" : "false", i, new_min);
1022 if (!skipped)
1023 new_min = i + 1;
1024 SCLogDebug("final i %"PRIu64", new_min %"PRIu64, i, new_min);
1025
1026 next:
1027 if (!ires.has_next) {
1028 /* this was the last tx. See if we skipped any. If not
1029 * we removed all and can update the minimum to the max
1030 * id. */
1031 SCLogDebug("no next: cur tx i %"PRIu64", total %"PRIu64, i, total_txs);
1032 if (!skipped) {
1033 new_min = total_txs;
1034 SCLogDebug("no next: cur tx i %"PRIu64", total %"PRIu64": "
1035 "new_min updated to %"PRIu64, i, total_txs, new_min);
1036 }
1037 break;
1038 }
1039 i++;
1040 }
1041
1042 /* see if we need to bring all trackers up to date. */
1043 SCLogDebug("update f->alparser->min_id? %"PRIu64" vs %"PRIu64, new_min, alparser->min_id);
1044 if (new_min > alparser->min_id) {
1045 const uint64_t next_id = new_min;
1046 alparser->min_id = next_id;
1047 alparser->inspect_id[0] = MAX(alparser->inspect_id[0], next_id);
1048 alparser->inspect_id[1] = MAX(alparser->inspect_id[1], next_id);
1049 alparser->log_id = MAX(alparser->log_id, next_id);
1050 SCLogDebug("updated f->alparser->min_id %"PRIu64, alparser->min_id);
1051 }
1052 SCReturn;
1053 }
1054
1055 /**
1056 * \brief get the progress value for a tx/protocol
1057 *
1058 * If the stream is disrupted, we return the 'completion' value.
1059 */
AppLayerParserGetStateProgress(uint8_t ipproto,AppProto alproto,void * alstate,uint8_t flags)1060 int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto,
1061 void *alstate, uint8_t flags)
1062 {
1063 SCEnter();
1064 int r = 0;
1065 if (unlikely(IS_DISRUPTED(flags))) {
1066 r = alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
1067 StateGetProgressCompletionStatus(flags);
1068 } else {
1069 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1070 StateGetProgress(alstate, flags);
1071 }
1072 SCReturnInt(r);
1073 }
1074
AppLayerParserGetTxCnt(const Flow * f,void * alstate)1075 uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
1076 {
1077 SCEnter();
1078 uint64_t r = 0;
1079 r = alp_ctx.ctxs[f->protomap][f->alproto].
1080 StateGetTxCnt(alstate);
1081 SCReturnCT(r, "uint64_t");
1082 }
1083
AppLayerParserGetTx(uint8_t ipproto,AppProto alproto,void * alstate,uint64_t tx_id)1084 void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
1085 {
1086 SCEnter();
1087 void * r = NULL;
1088 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1089 StateGetTx(alstate, tx_id);
1090 SCReturnPtr(r, "void *");
1091 }
1092
AppLayerParserGetStateProgressCompletionStatus(AppProto alproto,uint8_t direction)1093 int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto,
1094 uint8_t direction)
1095 {
1096 SCEnter();
1097 int r = alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
1098 StateGetProgressCompletionStatus(direction);
1099 SCReturnInt(r);
1100 }
1101
AppLayerParserGetEventInfo(uint8_t ipproto,AppProto alproto,const char * event_name,int * event_id,AppLayerEventType * event_type)1102 int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name,
1103 int *event_id, AppLayerEventType *event_type)
1104 {
1105 SCEnter();
1106 int ipproto_map = FlowGetProtoMapping(ipproto);
1107 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo == NULL) ?
1108 -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo(event_name, event_id, event_type);
1109 SCReturnInt(r);
1110 }
1111
AppLayerParserGetEventInfoById(uint8_t ipproto,AppProto alproto,int event_id,const char ** event_name,AppLayerEventType * event_type)1112 int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, int event_id,
1113 const char **event_name, AppLayerEventType *event_type)
1114 {
1115 SCEnter();
1116 int ipproto_map = FlowGetProtoMapping(ipproto);
1117 *event_name = (const char *)NULL;
1118 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfoById == NULL) ?
1119 -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfoById(event_id, event_name, event_type);
1120 SCReturnInt(r);
1121 }
1122
AppLayerParserGetFirstDataDir(uint8_t ipproto,AppProto alproto)1123 uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
1124 {
1125 SCEnter();
1126 uint8_t r = 0;
1127 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1128 first_data_dir;
1129 SCReturnCT(r, "uint8_t");
1130 }
1131
AppLayerParserGetTransactionActive(const Flow * f,AppLayerParserState * pstate,uint8_t direction)1132 uint64_t AppLayerParserGetTransactionActive(const Flow *f,
1133 AppLayerParserState *pstate, uint8_t direction)
1134 {
1135 SCEnter();
1136
1137 uint64_t active_id;
1138
1139 uint64_t log_id = pstate->log_id;
1140 uint64_t inspect_id = pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1];
1141 if (alp_ctx.ctxs[f->protomap][f->alproto].logger == true) {
1142 active_id = (log_id < inspect_id) ? log_id : inspect_id;
1143 } else {
1144 active_id = inspect_id;
1145 }
1146
1147 SCReturnCT(active_id, "uint64_t");
1148 }
1149
AppLayerParserSupportsFiles(uint8_t ipproto,AppProto alproto)1150 int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
1151 {
1152 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles != NULL)
1153 return TRUE;
1154 return FALSE;
1155 }
1156
AppLayerParserSupportsTxDetectState(uint8_t ipproto,AppProto alproto)1157 int AppLayerParserSupportsTxDetectState(uint8_t ipproto, AppProto alproto)
1158 {
1159 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState != NULL)
1160 return TRUE;
1161 return FALSE;
1162 }
1163
AppLayerParserGetTxDetectState(uint8_t ipproto,AppProto alproto,void * tx)1164 DetectEngineState *AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx)
1165 {
1166 SCEnter();
1167 DetectEngineState *s;
1168 s = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState(tx);
1169 SCReturnPtr(s, "DetectEngineState");
1170 }
1171
AppLayerParserSetTxDetectState(const Flow * f,void * tx,DetectEngineState * s)1172 int AppLayerParserSetTxDetectState(const Flow *f,
1173 void *tx, DetectEngineState *s)
1174 {
1175 int r;
1176 SCEnter();
1177 if ((alp_ctx.ctxs[f->protomap][f->alproto].GetTxDetectState(tx) != NULL))
1178 SCReturnInt(-EBUSY);
1179 r = alp_ctx.ctxs[f->protomap][f->alproto].SetTxDetectState(tx, s);
1180 SCReturnInt(r);
1181 }
1182
AppLayerParserSupportsTxDetectFlags(AppProto alproto)1183 bool AppLayerParserSupportsTxDetectFlags(AppProto alproto)
1184 {
1185 SCEnter();
1186 for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1187 if (alp_ctx.ctxs[p][alproto].GetTxData != NULL) {
1188 SCReturnBool(true);
1189 }
1190 }
1191 SCReturnBool(false);
1192 }
1193
AppLayerParserGetTxData(uint8_t ipproto,AppProto alproto,void * tx)1194 AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
1195 {
1196 SCEnter();
1197 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData) {
1198 AppLayerTxData *d = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData(tx);
1199 SCReturnPtr(d, "AppLayerTxData");
1200 }
1201 SCReturnPtr(NULL, "AppLayerTxData");
1202 }
1203
AppLayerParserApplyTxConfig(uint8_t ipproto,AppProto alproto,void * state,void * tx,enum ConfigAction mode,AppLayerTxConfig config)1204 void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto,
1205 void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig config)
1206 {
1207 SCEnter();
1208 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig) {
1209 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig(state, tx, mode, config);
1210 }
1211 SCReturn;
1212 }
1213
1214 /***** General *****/
1215
SetEOFFlags(AppLayerParserState * pstate,const uint8_t flags)1216 static inline void SetEOFFlags(AppLayerParserState *pstate, const uint8_t flags)
1217 {
1218 if ((flags & (STREAM_EOF|STREAM_TOSERVER)) == (STREAM_EOF|STREAM_TOSERVER)) {
1219 SCLogDebug("setting APP_LAYER_PARSER_EOF_TS");
1220 AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TS);
1221 } else if ((flags & (STREAM_EOF|STREAM_TOCLIENT)) == (STREAM_EOF|STREAM_TOCLIENT)) {
1222 SCLogDebug("setting APP_LAYER_PARSER_EOF_TC");
1223 AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF_TC);
1224 }
1225 }
1226
1227 /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow.
1228 * \retval int 0 ok: we did not update app_progress
1229 * \retval int 1 ok: we updated app_progress */
AppLayerParserParse(ThreadVars * tv,AppLayerParserThreadCtx * alp_tctx,Flow * f,AppProto alproto,uint8_t flags,const uint8_t * input,uint32_t input_len)1230 int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto,
1231 uint8_t flags, const uint8_t *input, uint32_t input_len)
1232 {
1233 SCEnter();
1234 #ifdef DEBUG_VALIDATION
1235 BUG_ON(f->protomap != FlowGetProtoMapping(f->proto));
1236 #endif
1237 AppLayerParserState *pstate = f->alparser;
1238 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto];
1239 void *alstate = NULL;
1240 uint64_t p_tx_cnt = 0;
1241 uint32_t consumed = input_len;
1242 const int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
1243
1244 /* we don't have the parser registered for this protocol */
1245 if (p->StateAlloc == NULL)
1246 goto end;
1247
1248 if (flags & STREAM_GAP) {
1249 if (!(p->option_flags & APP_LAYER_PARSER_OPT_ACCEPT_GAPS)) {
1250 SCLogDebug("app-layer parser does not accept gaps");
1251 if (f->alstate != NULL && !FlowChangeProto(f)) {
1252 AppLayerParserStreamTruncated(f->proto, alproto, f->alstate,
1253 flags);
1254 }
1255 goto error;
1256 }
1257 }
1258
1259 /* Get the parser state (if any) */
1260 if (pstate == NULL) {
1261 f->alparser = pstate = AppLayerParserStateAlloc();
1262 if (pstate == NULL)
1263 goto error;
1264 }
1265
1266 SetEOFFlags(pstate, flags);
1267
1268 alstate = f->alstate;
1269 if (alstate == NULL || FlowChangeProto(f)) {
1270 f->alstate = alstate = p->StateAlloc(alstate, f->alproto_orig);
1271 if (alstate == NULL)
1272 goto error;
1273 SCLogDebug("alloced new app layer state %p (name %s)",
1274 alstate, AppLayerGetProtoName(f->alproto));
1275 } else {
1276 SCLogDebug("using existing app layer state %p (name %s))",
1277 alstate, AppLayerGetProtoName(f->alproto));
1278 }
1279
1280 p_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
1281
1282 /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
1283 if (input_len > 0 || (flags & STREAM_EOF)) {
1284 /* invoke the parser */
1285 AppLayerResult res = p->Parser[direction](f, alstate, pstate,
1286 input, input_len,
1287 alp_tctx->alproto_local_storage[f->protomap][alproto],
1288 flags);
1289 if (res.status < 0) {
1290 goto error;
1291 } else if (res.status > 0) {
1292 DEBUG_VALIDATE_BUG_ON(res.consumed > input_len);
1293 DEBUG_VALIDATE_BUG_ON(res.needed + res.consumed < input_len);
1294 DEBUG_VALIDATE_BUG_ON(res.needed == 0);
1295 /* incomplete is only supported for TCP */
1296 DEBUG_VALIDATE_BUG_ON(f->proto != IPPROTO_TCP);
1297
1298 /* put protocol in error state on improper use of the
1299 * return codes. */
1300 if (res.consumed > input_len || res.needed + res.consumed < input_len) {
1301 goto error;
1302 }
1303
1304 if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1305 TcpSession *ssn = f->protoctx;
1306 SCLogDebug("direction %d/%s", direction,
1307 (flags & STREAM_TOSERVER) ? "toserver" : "toclient");
1308 if (direction == 0) {
1309 /* parser told us how much data it needs on top of what it
1310 * consumed. So we need tell stream engine how much we need
1311 * before the next call */
1312 ssn->client.data_required = res.needed;
1313 SCLogDebug("setting data_required %u", ssn->client.data_required);
1314 } else {
1315 /* parser told us how much data it needs on top of what it
1316 * consumed. So we need tell stream engine how much we need
1317 * before the next call */
1318 ssn->server.data_required = res.needed;
1319 SCLogDebug("setting data_required %u", ssn->server.data_required);
1320 }
1321 }
1322 consumed = res.consumed;
1323 }
1324 }
1325
1326 /* set the packets to no inspection and reassembly if required */
1327 if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) {
1328 AppLayerParserSetEOF(pstate);
1329 FlowSetNoPayloadInspectionFlag(f);
1330
1331 if (f->proto == IPPROTO_TCP) {
1332 StreamTcpDisableAppLayer(f);
1333
1334 /* Set the no reassembly flag for both the stream in this TcpSession */
1335 if (pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
1336 /* Used only if it's TCP */
1337 TcpSession *ssn = f->protoctx;
1338 if (ssn != NULL) {
1339 StreamTcpSetSessionNoReassemblyFlag(ssn, 0);
1340 StreamTcpSetSessionNoReassemblyFlag(ssn, 1);
1341 }
1342 }
1343 /* Set the bypass flag for both the stream in this TcpSession */
1344 if (pstate->flags & APP_LAYER_PARSER_BYPASS_READY) {
1345 /* Used only if it's TCP */
1346 TcpSession *ssn = f->protoctx;
1347 if (ssn != NULL) {
1348 StreamTcpSetSessionBypassFlag(ssn);
1349 }
1350 }
1351 }
1352 }
1353
1354 /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */
1355 if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) {
1356 FlowSetNoPayloadInspectionFlag(f);
1357 /* Set the no reassembly flag for both the stream in this TcpSession */
1358 if (f->proto == IPPROTO_TCP) {
1359 /* Used only if it's TCP */
1360 TcpSession *ssn = f->protoctx;
1361 if (ssn != NULL) {
1362 StreamTcpSetDisableRawReassemblyFlag(ssn, 0);
1363 StreamTcpSetDisableRawReassemblyFlag(ssn, 1);
1364 }
1365 }
1366 }
1367
1368 /* get the diff in tx cnt for stats keeping */
1369 uint64_t cur_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
1370 if (cur_tx_cnt > p_tx_cnt && tv) {
1371 AppLayerIncTxCounter(tv, f, cur_tx_cnt - p_tx_cnt);
1372 }
1373
1374 /* stream truncated, inform app layer */
1375 if (flags & STREAM_DEPTH)
1376 AppLayerParserStreamTruncated(f->proto, alproto, alstate, flags);
1377
1378 end:
1379 /* update app progress */
1380 if (consumed != input_len && f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1381 TcpSession *ssn = f->protoctx;
1382 StreamTcpUpdateAppLayerProgress(ssn, direction, consumed);
1383 SCReturnInt(1);
1384 }
1385
1386 SCReturnInt(0);
1387 error:
1388 /* Set the no app layer inspection flag for both
1389 * the stream in this Flow */
1390 if (f->proto == IPPROTO_TCP) {
1391 StreamTcpDisableAppLayer(f);
1392 }
1393 AppLayerParserSetEOF(pstate);
1394 SCReturnInt(-1);
1395 }
1396
AppLayerParserSetEOF(AppLayerParserState * pstate)1397 void AppLayerParserSetEOF(AppLayerParserState *pstate)
1398 {
1399 SCEnter();
1400
1401 if (pstate == NULL)
1402 goto end;
1403
1404 SCLogDebug("setting APP_LAYER_PARSER_EOF_TC and APP_LAYER_PARSER_EOF_TS");
1405 AppLayerParserStateSetFlag(pstate, (APP_LAYER_PARSER_EOF_TS|APP_LAYER_PARSER_EOF_TC));
1406
1407 end:
1408 SCReturn;
1409 }
1410
1411 /* return true if there are app parser decoder events. These are
1412 * only the ones that are set during protocol detection. */
AppLayerParserHasDecoderEvents(AppLayerParserState * pstate)1413 bool AppLayerParserHasDecoderEvents(AppLayerParserState *pstate)
1414 {
1415 SCEnter();
1416
1417 if (pstate == NULL)
1418 return false;
1419
1420 const AppLayerDecoderEvents *decoder_events = AppLayerParserGetDecoderEvents(pstate);
1421 if (decoder_events && decoder_events->cnt)
1422 return true;
1423
1424 /* if we have reached here, we don't have events */
1425 return false;
1426 }
1427
1428 /** \brief simple way to globally test if a alproto is registered
1429 * and fully enabled in the configuration.
1430 */
AppLayerParserIsEnabled(AppProto alproto)1431 int AppLayerParserIsEnabled(AppProto alproto)
1432 {
1433 return (alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto]
1434 .StateGetProgressCompletionStatus != NULL);
1435 }
1436
AppLayerParserProtocolIsTxEventAware(uint8_t ipproto,AppProto alproto)1437 int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto)
1438 {
1439 SCEnter();
1440 int ipproto_map = FlowGetProtoMapping(ipproto);
1441 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEvents == NULL) ? 0 : 1;
1442 SCReturnInt(r);
1443 }
1444
AppLayerParserProtocolHasLogger(uint8_t ipproto,AppProto alproto)1445 int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
1446 {
1447 SCEnter();
1448 int ipproto_map = FlowGetProtoMapping(ipproto);
1449 int r = (alp_ctx.ctxs[ipproto_map][alproto].logger == false) ? 0 : 1;
1450 SCReturnInt(r);
1451 }
1452
AppLayerParserProtocolGetLoggerBits(uint8_t ipproto,AppProto alproto)1453 LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto)
1454 {
1455 SCEnter();
1456 const int ipproto_map = FlowGetProtoMapping(ipproto);
1457 LoggerId r = alp_ctx.ctxs[ipproto_map][alproto].logger_bits;
1458 SCReturnUInt(r);
1459 }
1460
AppLayerParserTriggerRawStreamReassembly(Flow * f,int direction)1461 void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction)
1462 {
1463 SCEnter();
1464
1465 SCLogDebug("f %p tcp %p direction %d", f, f ? f->protoctx : NULL, direction);
1466 if (f != NULL && f->protoctx != NULL)
1467 StreamTcpReassembleTriggerRawReassembly(f->protoctx, direction);
1468
1469 SCReturn;
1470 }
1471
AppLayerParserSetStreamDepth(uint8_t ipproto,AppProto alproto,uint32_t stream_depth)1472 void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth)
1473 {
1474 SCEnter();
1475
1476 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].stream_depth = stream_depth;
1477 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].internal_flags |=
1478 APP_LAYER_PARSER_INT_STREAM_DEPTH_SET;
1479
1480 SCReturn;
1481 }
1482
AppLayerParserGetStreamDepth(const Flow * f)1483 uint32_t AppLayerParserGetStreamDepth(const Flow *f)
1484 {
1485 SCReturnInt(alp_ctx.ctxs[f->protomap][f->alproto].stream_depth);
1486 }
1487
AppLayerParserSetStreamDepthFlag(uint8_t ipproto,AppProto alproto,void * state,uint64_t tx_id,uint8_t flags)1488 void AppLayerParserSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void *state, uint64_t tx_id, uint8_t flags)
1489 {
1490 SCEnter();
1491 void *tx = NULL;
1492 if (state != NULL) {
1493 if ((tx = AppLayerParserGetTx(ipproto, alproto, state, tx_id)) != NULL) {
1494 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag != NULL) {
1495 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag(tx, flags);
1496 }
1497 }
1498 }
1499 SCReturn;
1500 }
1501
1502 /***** Cleanup *****/
1503
AppLayerParserStateProtoCleanup(uint8_t protomap,AppProto alproto,void * alstate,AppLayerParserState * pstate)1504 void AppLayerParserStateProtoCleanup(
1505 uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
1506 {
1507 SCEnter();
1508
1509 AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[protomap][alproto];
1510
1511 if (ctx->StateFree != NULL && alstate != NULL)
1512 ctx->StateFree(alstate);
1513
1514 /* free the app layer parser api state */
1515 if (pstate != NULL)
1516 AppLayerParserStateFree(pstate);
1517
1518 SCReturn;
1519 }
1520
AppLayerParserStateCleanup(const Flow * f,void * alstate,AppLayerParserState * pstate)1521 void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
1522 {
1523 AppLayerParserStateProtoCleanup(f->protomap, f->alproto, alstate, pstate);
1524 }
1525
ValidateParserProtoDump(AppProto alproto,uint8_t ipproto)1526 static void ValidateParserProtoDump(AppProto alproto, uint8_t ipproto)
1527 {
1528 uint8_t map = FlowGetProtoMapping(ipproto);
1529 const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1530 const AppLayerParserProtoCtx *ctx_def = &alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto];
1531 printf("ERROR: incomplete app-layer registration\n");
1532 printf("AppLayer protocol %s ipproto %u\n", AppProtoToString(alproto), ipproto);
1533 printf("- option flags %"PRIx32"\n", ctx->option_flags);
1534 printf("- first_data_dir %"PRIx8"\n", ctx->first_data_dir);
1535 printf("Mandatory:\n");
1536 printf("- Parser[0] %p Parser[1] %p\n", ctx->Parser[0], ctx->Parser[1]);
1537 printf("- StateAlloc %p StateFree %p\n", ctx->StateAlloc, ctx->StateFree);
1538 printf("- StateGetTx %p StateGetTxCnt %p StateTransactionFree %p\n",
1539 ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree);
1540 printf("- GetTxData %p\n", ctx->GetTxData);
1541 printf("- StateGetProgress %p StateGetProgressCompletionStatus %p\n", ctx->StateGetProgress, ctx_def->StateGetProgressCompletionStatus);
1542 printf("- GetTxDetectState %p SetTxDetectState %p\n", ctx->GetTxDetectState, ctx->SetTxDetectState);
1543 printf("Optional:\n");
1544 printf("- LocalStorageAlloc %p LocalStorageFree %p\n", ctx->LocalStorageAlloc, ctx->LocalStorageFree);
1545 printf("- StateGetEvents %p StateGetEventInfo %p StateGetEventInfoById %p\n", ctx->StateGetEvents, ctx->StateGetEventInfo,
1546 ctx->StateGetEventInfoById);
1547 }
1548
1549 #define BOTH_SET(a, b) ((a) != NULL && (b) != NULL)
1550 #define BOTH_SET_OR_BOTH_UNSET(a, b) (((a) == NULL && (b) == NULL) || ((a) != NULL && (b) != NULL))
1551 #define THREE_SET_OR_THREE_UNSET(a, b, c) (((a) == NULL && (b) == NULL && (c) == NULL) || ((a) != NULL && (b) != NULL && (c) != NULL))
1552 #define THREE_SET(a, b, c) ((a) != NULL && (b) != NULL && (c) != NULL)
1553
ValidateParserProto(AppProto alproto,uint8_t ipproto)1554 static void ValidateParserProto(AppProto alproto, uint8_t ipproto)
1555 {
1556 uint8_t map = FlowGetProtoMapping(ipproto);
1557 const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1558 const AppLayerParserProtoCtx *ctx_def = &alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto];
1559
1560 if (ctx->Parser[0] == NULL && ctx->Parser[1] == NULL)
1561 return;
1562
1563 if (!(BOTH_SET(ctx->Parser[0], ctx->Parser[1]))) {
1564 goto bad;
1565 }
1566 if (!(BOTH_SET(ctx->StateFree, ctx->StateAlloc))) {
1567 goto bad;
1568 }
1569 if (!(THREE_SET(ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree))) {
1570 goto bad;
1571 }
1572 /* special case: StateGetProgressCompletionStatus is used from 'default'. */
1573 if (!(BOTH_SET(ctx->StateGetProgress, ctx_def->StateGetProgressCompletionStatus))) {
1574 goto bad;
1575 }
1576 /* local storage is optional, but needs both set if used */
1577 if (!(BOTH_SET_OR_BOTH_UNSET(ctx->LocalStorageAlloc, ctx->LocalStorageFree))) {
1578 goto bad;
1579 }
1580 if (!(BOTH_SET(ctx->GetTxDetectState, ctx->SetTxDetectState))) {
1581 goto bad;
1582 }
1583 if (!(BOTH_SET_OR_BOTH_UNSET(ctx->GetTxDetectState, ctx->SetTxDetectState))) {
1584 goto bad;
1585 }
1586 if (ctx->GetTxData == NULL) {
1587 goto bad;
1588 }
1589 return;
1590 bad:
1591 ValidateParserProtoDump(alproto, ipproto);
1592 exit(EXIT_FAILURE);
1593 }
1594 #undef BOTH_SET
1595 #undef BOTH_SET_OR_BOTH_UNSET
1596 #undef THREE_SET_OR_THREE_UNSET
1597 #undef THREE_SET
1598
ValidateParser(AppProto alproto)1599 static void ValidateParser(AppProto alproto)
1600 {
1601 ValidateParserProto(alproto, IPPROTO_TCP);
1602 ValidateParserProto(alproto, IPPROTO_UDP);
1603 }
1604
ValidateParsers(void)1605 static void ValidateParsers(void)
1606 {
1607 AppProto p = 0;
1608 for ( ; p < ALPROTO_MAX; p++) {
1609 ValidateParser(p);
1610 }
1611 }
1612
AppLayerParserRegisterProtocolParsers(void)1613 void AppLayerParserRegisterProtocolParsers(void)
1614 {
1615 SCEnter();
1616
1617 RegisterHTPParsers();
1618 RegisterSSLParsers();
1619 RegisterDCERPCParsers();
1620 RegisterDCERPCUDPParsers();
1621 RegisterSMBParsers();
1622 RegisterFTPParsers();
1623 RegisterSSHParsers();
1624 RegisterSMTPParsers();
1625 rs_dns_udp_register_parser();
1626 rs_dns_tcp_register_parser();
1627 RegisterModbusParsers();
1628 RegisterENIPUDPParsers();
1629 RegisterENIPTCPParsers();
1630 RegisterDNP3Parsers();
1631 RegisterNFSTCPParsers();
1632 RegisterNFSUDPParsers();
1633 RegisterNTPParsers();
1634 RegisterTFTPParsers();
1635 RegisterIKEV2Parsers();
1636 RegisterKRB5Parsers();
1637 rs_dhcp_register_parser();
1638 RegisterSNMPParsers();
1639 RegisterSIPParsers();
1640 RegisterTemplateRustParsers();
1641 RegisterRFBParsers();
1642 RegisterMQTTParsers();
1643 RegisterTemplateParsers();
1644 RegisterRdpParsers();
1645 RegisterHTTP2Parsers();
1646
1647 /** IMAP */
1648 AppLayerProtoDetectRegisterProtocol(ALPROTO_IMAP, "imap");
1649 if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "imap")) {
1650 if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_IMAP,
1651 "1|20|capability", 12, 0, STREAM_TOSERVER) < 0)
1652 {
1653 SCLogInfo("imap proto registration failure");
1654 exit(EXIT_FAILURE);
1655 }
1656 } else {
1657 SCLogInfo("Protocol detection and parser disabled for %s protocol.",
1658 "imap");
1659 }
1660
1661 ValidateParsers();
1662 return;
1663 }
1664
1665
1666 /* coccinelle: AppLayerParserStateSetFlag():2,2:APP_LAYER_PARSER_ */
AppLayerParserStateSetFlag(AppLayerParserState * pstate,uint8_t flag)1667 void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint8_t flag)
1668 {
1669 SCEnter();
1670 pstate->flags |= flag;
1671 SCReturn;
1672 }
1673
1674 /* coccinelle: AppLayerParserStateIssetFlag():2,2:APP_LAYER_PARSER_ */
AppLayerParserStateIssetFlag(AppLayerParserState * pstate,uint8_t flag)1675 int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
1676 {
1677 SCEnter();
1678 SCReturnInt(pstate->flags & flag);
1679 }
1680
1681
AppLayerParserStreamTruncated(uint8_t ipproto,AppProto alproto,void * alstate,uint8_t direction)1682 void AppLayerParserStreamTruncated(uint8_t ipproto, AppProto alproto, void *alstate,
1683 uint8_t direction)
1684 {
1685 SCEnter();
1686
1687 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate != NULL)
1688 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate(alstate, direction);
1689
1690 SCReturn;
1691 }
1692
1693 #ifdef DEBUG
AppLayerParserStatePrintDetails(AppLayerParserState * pstate)1694 void AppLayerParserStatePrintDetails(AppLayerParserState *pstate)
1695 {
1696 SCEnter();
1697
1698 if (pstate == NULL)
1699 SCReturn;
1700
1701 AppLayerParserState *p = pstate;
1702 SCLogDebug("AppLayerParser parser state information for parser state p(%p). "
1703 "p->inspect_id[0](%"PRIu64"), "
1704 "p->inspect_id[1](%"PRIu64"), "
1705 "p->log_id(%"PRIu64"), "
1706 "p->decoder_events(%p).",
1707 pstate, p->inspect_id[0], p->inspect_id[1], p->log_id,
1708 p->decoder_events);
1709
1710 SCReturn;
1711 }
1712 #endif
1713
1714 /***** Unittests *****/
1715
1716 #ifdef UNITTESTS
1717
1718 static AppLayerParserCtx alp_ctx_backup_unittest;
1719
1720 typedef struct TestState_ {
1721 uint8_t test;
1722 } TestState;
1723
1724 /**
1725 * \brief Test parser function to test the memory deallocation of app layer
1726 * parser of occurence of an error.
1727 */
TestProtocolParser(Flow * f,void * test_state,AppLayerParserState * pstate,const uint8_t * input,uint32_t input_len,void * local_data,const uint8_t flags)1728 static AppLayerResult TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
1729 const uint8_t *input, uint32_t input_len,
1730 void *local_data, const uint8_t flags)
1731 {
1732 SCEnter();
1733 SCReturnStruct(APP_LAYER_ERROR);
1734 }
1735
1736 /** \brief Function to allocates the Test protocol state memory
1737 */
TestProtocolStateAlloc(void * orig_state,AppProto proto_orig)1738 static void *TestProtocolStateAlloc(void *orig_state, AppProto proto_orig)
1739 {
1740 SCEnter();
1741 void *s = SCMalloc(sizeof(TestState));
1742 if (unlikely(s == NULL))
1743 goto end;
1744 memset(s, 0, sizeof(TestState));
1745 end:
1746 SCReturnPtr(s, "TestState");
1747 }
1748
1749 /** \brief Function to free the Test Protocol state memory
1750 */
TestProtocolStateFree(void * s)1751 static void TestProtocolStateFree(void *s)
1752 {
1753 SCFree(s);
1754 }
1755
TestGetTxCnt(void * state)1756 static uint64_t TestGetTxCnt(void *state)
1757 {
1758 /* single tx */
1759 return 1;
1760 }
1761
TestStateTransactionFree(void * state,uint64_t tx_id)1762 static void TestStateTransactionFree(void *state, uint64_t tx_id)
1763 {
1764 /* do nothing */
1765 }
1766
TestGetTx(void * state,uint64_t tx_id)1767 static void *TestGetTx(void *state, uint64_t tx_id)
1768 {
1769 TestState *test_state = (TestState *)state;
1770 return test_state;
1771 }
1772
AppLayerParserRegisterProtocolUnittests(uint8_t ipproto,AppProto alproto,void (* RegisterUnittests)(void))1773 void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto,
1774 void (*RegisterUnittests)(void))
1775 {
1776 SCEnter();
1777 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1778 RegisterUnittests = RegisterUnittests;
1779 SCReturn;
1780 }
1781
AppLayerParserBackupParserTable(void)1782 void AppLayerParserBackupParserTable(void)
1783 {
1784 SCEnter();
1785 alp_ctx_backup_unittest = alp_ctx;
1786 memset(&alp_ctx, 0, sizeof(alp_ctx));
1787 SCReturn;
1788 }
1789
AppLayerParserRestoreParserTable(void)1790 void AppLayerParserRestoreParserTable(void)
1791 {
1792 SCEnter();
1793 alp_ctx = alp_ctx_backup_unittest;
1794 memset(&alp_ctx_backup_unittest, 0, sizeof(alp_ctx_backup_unittest));
1795 SCReturn;
1796 }
1797
1798 /**
1799 * \test Test the deallocation of app layer parser memory on occurance of
1800 * error in the parsing process.
1801 */
AppLayerParserTest01(void)1802 static int AppLayerParserTest01(void)
1803 {
1804 AppLayerParserBackupParserTable();
1805
1806 int result = 0;
1807 Flow *f = NULL;
1808 uint8_t testbuf[] = { 0x11 };
1809 uint32_t testlen = sizeof(testbuf);
1810 TcpSession ssn;
1811 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1812
1813 memset(&ssn, 0, sizeof(ssn));
1814
1815 /* Register the Test protocol state and parser functions */
1816 AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER,
1817 TestProtocolParser);
1818 AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST,
1819 TestProtocolStateAlloc, TestProtocolStateFree);
1820 AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_TEST, TestStateTransactionFree);
1821 AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_TEST, TestGetTx);
1822 AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_TEST, TestGetTxCnt);
1823
1824 f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
1825 if (f == NULL)
1826 goto end;
1827 f->protoctx = &ssn;
1828 f->alproto = ALPROTO_TEST;
1829 f->proto = IPPROTO_TCP;
1830
1831 StreamTcpInitConfig(TRUE);
1832
1833 FLOWLOCK_WRLOCK(f);
1834 int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
1835 STREAM_TOSERVER | STREAM_EOF, testbuf,
1836 testlen);
1837 if (r != -1) {
1838 printf("returned %" PRId32 ", expected -1: ", r);
1839 FLOWLOCK_UNLOCK(f);
1840 goto end;
1841 }
1842 FLOWLOCK_UNLOCK(f);
1843
1844 if (!(ssn.flags & STREAMTCP_FLAG_APP_LAYER_DISABLED)) {
1845 printf("flag should have been set, but is not: ");
1846 goto end;
1847 }
1848
1849 result = 1;
1850 end:
1851 AppLayerParserRestoreParserTable();
1852 StreamTcpFreeConfig(TRUE);
1853
1854 UTHFreeFlow(f);
1855 return result;
1856 }
1857
1858 /**
1859 * \test Test the deallocation of app layer parser memory on occurance of
1860 * error in the parsing process for UDP.
1861 */
AppLayerParserTest02(void)1862 static int AppLayerParserTest02(void)
1863 {
1864 AppLayerParserBackupParserTable();
1865
1866 int result = 1;
1867 Flow *f = NULL;
1868 uint8_t testbuf[] = { 0x11 };
1869 uint32_t testlen = sizeof(testbuf);
1870 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1871
1872 /* Register the Test protocol state and parser functions */
1873 AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TEST, STREAM_TOSERVER,
1874 TestProtocolParser);
1875 AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_TEST,
1876 TestProtocolStateAlloc, TestProtocolStateFree);
1877 AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_TEST, TestStateTransactionFree);
1878 AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_TEST, TestGetTx);
1879 AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_TEST, TestGetTxCnt);
1880
1881 f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
1882 if (f == NULL)
1883 goto end;
1884 f->alproto = ALPROTO_TEST;
1885 f->proto = IPPROTO_UDP;
1886 f->protomap = FlowGetProtoMapping(f->proto);
1887
1888 StreamTcpInitConfig(TRUE);
1889
1890 FLOWLOCK_WRLOCK(f);
1891 int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
1892 STREAM_TOSERVER | STREAM_EOF, testbuf,
1893 testlen);
1894 if (r != -1) {
1895 printf("returned %" PRId32 ", expected -1: \n", r);
1896 result = 0;
1897 FLOWLOCK_UNLOCK(f);
1898 goto end;
1899 }
1900 FLOWLOCK_UNLOCK(f);
1901
1902 end:
1903 AppLayerParserRestoreParserTable();
1904 StreamTcpFreeConfig(TRUE);
1905 UTHFreeFlow(f);
1906 return result;
1907 }
1908
1909
AppLayerParserRegisterUnittests(void)1910 void AppLayerParserRegisterUnittests(void)
1911 {
1912 SCEnter();
1913
1914 int ip;
1915 AppProto alproto;
1916 AppLayerParserProtoCtx *ctx;
1917
1918 for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) {
1919 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1920 ctx = &alp_ctx.ctxs[ip][alproto];
1921 if (ctx->RegisterUnittests == NULL)
1922 continue;
1923 ctx->RegisterUnittests();
1924 }
1925 }
1926
1927 UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01);
1928 UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02);
1929
1930 SCReturn;
1931 }
1932
1933 #endif
1934