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