1 /* $Id$ */
2 /*
3  ** Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
4  ** Copyright (C) 2010-2013 Sourcefire, Inc.
5  **
6  ** This program is free software; you can redistribute it and/or modify
7  ** it under the terms of the GNU General Public License Version 2 as
8  ** published by the Free Software Foundation.  You may not use, modify or
9  ** distribute this program under any other version of the GNU General
10  ** Public License.
11  **
12  ** This program is distributed in the hope that it will be useful,
13  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  ** GNU General Public License for more details.
16  **
17  ** You should have received a copy of the GNU General Public License
18  ** along with this program; if not, write to the Free Software
19  ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21 
22 #ifdef NORMALIZER
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #include "active.h"
28 #include "mstring.h"
29 #include "normalize.h"
30 #include "parser.h"
31 #include "plugbase.h"
32 #include "profiler.h"
33 #include "sf_types.h"
34 #include "sfPolicy.h"
35 #include "snort.h"
36 #include "spp_normalize.h"
37 #include "snort_stream_tcp.h"
38 
39 // Priority for Normalize preproc
40 #define PP_NORMALIZE_PRIORITY PRIORITY_CORE + PP_CORE_ORDER_NORML
41 
42 static tSfPolicyUserContextId base_set = NULL;
43 
44 #ifdef PERF_PROFILING
45 PreprocStats norm_perf_stats;
46 #endif
47 
48 static void Preproc_Execute(Packet* , void*);
49 static void Preproc_CleanExit(int, void*);
50 static void Preproc_Reset(int, void*);
51 static void Preproc_PostConfigInit(struct _SnortConfig *, void*);
52 static int Preproc_CheckConfig (struct _SnortConfig *);
53 static void Preproc_ResetStats(int, void*);
54 static void Preproc_PrintStats(int);
55 static void Preproc_Install(struct _SnortConfig *);
56 
57 static void Init_IP4(struct _SnortConfig *, char*);
58 static void Init_ICMP4(struct _SnortConfig *, char*);
59 static void Init_IP6(struct _SnortConfig *, char*);
60 static void Init_ICMP6(struct _SnortConfig *, char*);
61 static void Init_TCP(struct _SnortConfig *, char*);
62 
63 static void Parse_IP4(struct _SnortConfig *, NormalizerContext*, char*);
64 static void Parse_ICMP4(NormalizerContext*, char*);
65 static void Parse_IP6(struct _SnortConfig *, NormalizerContext*, char*);
66 static void Parse_ICMP6(NormalizerContext*, char*);
67 static void Parse_TCP(NormalizerContext*, char*);
68 
69 static void Print_IP4(struct _SnortConfig *, const NormalizerContext*);
70 static void Print_ICMP4(const NormalizerContext*);
71 static void Print_IP6(struct _SnortConfig *, const NormalizerContext*);
72 static void Print_ICMP6(const NormalizerContext*);
73 static void Print_TCP(const NormalizerContext*);
74 
75 #ifdef SNORT_RELOAD
76 static void Reload_IP4(struct _SnortConfig *, char*, void **);
77 static void Reload_ICMP4(struct _SnortConfig *, char*, void **);
78 static void Reload_IP6(struct _SnortConfig *, char*, void **);
79 static void Reload_ICMP6(struct _SnortConfig *, char*, void **);
80 static void Reload_TCP(struct _SnortConfig *, char*, void **);
81 
82 static int Reload_Verify(struct _SnortConfig *, void *);
83 static void* Reload_Swap(struct _SnortConfig *, void *);
84 static void Reload_Free(void*);
85 #endif
86 
87 #ifdef SNORT_RELOAD
88 #define NORM_FUNCS(p) Init_ ## p, Reload_ ## p, Reload_Verify, Reload_Swap, Reload_Free
89 #else
90 #define NORM_FUNCS(p) Init_ ## p
91 #endif
92 
SetupNormalizer(void)93 void SetupNormalizer (void)
94 {
95     RegisterPreprocessor("normalize_ip4", NORM_FUNCS(IP4));
96     RegisterPreprocessor("normalize_icmp4", NORM_FUNCS(ICMP4));
97     RegisterPreprocessor("normalize_ip6", NORM_FUNCS(IP6));
98     RegisterPreprocessor("normalize_icmp6", NORM_FUNCS(ICMP6));
99     RegisterPreprocessor("normalize_tcp", NORM_FUNCS(TCP));
100 }
101 
102 //-------------------------------------------------------------------------
103 // basic initialization stuff
104 //-------------------------------------------------------------------------
105 
106 #define PROTO_BITS (PROTO_BIT__IP|PROTO_BIT__ICMP|PROTO_BIT__TCP)
107 
Init_GetContext(struct _SnortConfig * sc)108 static NormalizerContext* Init_GetContext (struct _SnortConfig *sc)
109 {
110     NormalizerContext* pc = NULL;
111     tSfPolicyId policy_id = getParserPolicy(sc);
112 
113     if ( ScNapPassiveModeNewConf(sc) )
114         return NULL;
115 
116     if ( !base_set )
117     {
118         base_set = sfPolicyConfigCreate();
119         Preproc_Install(sc);
120     }
121 
122     sc->normalizer_set  = true;
123 
124     sfPolicyUserPolicySet(base_set, policy_id);
125     pc = sfPolicyUserDataGetCurrent(base_set);
126 
127     if ( !pc )
128     {
129         pc = (NormalizerContext* )SnortAlloc(sizeof(NormalizerContext));
130         sfPolicyUserDataSetCurrent(base_set, pc);
131         if( pc->regFunc != reload)
132         {
133             AddFuncToPreprocList( sc, Preproc_Execute, PP_NORMALIZE_PRIORITY,  PP_NORMALIZE, PROTO_BITS);
134             pc->regFunc = init;
135         }
136         session_api->enable_preproc_all_ports( sc, PP_NORMALIZE, PROTO_BITS );
137     }
138     pc->normMode = ScNapInlineTestModeNewConf(sc) ? NORM_MODE_WOULDA : NORM_MODE_ON;
139 
140     return pc;
141 }
142 
143 #define NOT_INLINE "WARNING: %s normalizations disabled because not inline.\n"
144 
Init_IP4(struct _SnortConfig * sc,char * args)145 static void Init_IP4 (struct _SnortConfig *sc, char* args)
146 {
147     NormalizerContext* pc = Init_GetContext(sc);
148 
149     if ( pc )
150         Parse_IP4(sc, pc, args);
151     else
152         LogMessage(NOT_INLINE, "ip4");
153 }
154 
Init_ICMP4(struct _SnortConfig * sc,char * args)155 static void Init_ICMP4 (struct _SnortConfig *sc, char* args)
156 {
157     NormalizerContext* pc = Init_GetContext(sc);
158 
159     if ( pc )
160         Parse_ICMP4(pc, args);
161     else
162         LogMessage(NOT_INLINE, "icmp4");
163 }
164 
Init_IP6(struct _SnortConfig * sc,char * args)165 static void Init_IP6 (struct _SnortConfig *sc, char* args)
166 {
167     NormalizerContext* pc = Init_GetContext(sc);
168 
169     if ( pc )
170         Parse_IP6(sc, pc, args);
171     else
172         LogMessage(NOT_INLINE, "ip6");
173 }
174 
Init_ICMP6(struct _SnortConfig * sc,char * args)175 static void Init_ICMP6 (struct _SnortConfig *sc, char* args)
176 {
177     NormalizerContext* pc = Init_GetContext(sc);
178 
179     if ( pc )
180         Parse_ICMP6(pc, args);
181     else
182         LogMessage(NOT_INLINE, "icmp6");
183 }
184 
Init_TCP(struct _SnortConfig * sc,char * args)185 static void Init_TCP (struct _SnortConfig *sc, char* args)
186 {
187     NormalizerContext* pc = Init_GetContext(sc);
188 
189     if ( pc )
190         Parse_TCP(pc, args);
191     else
192         LogMessage(NOT_INLINE, "tcp");
193 }
194 
195 //-------------------------------------------------------------------------
196 // parsing stuff
197 //-------------------------------------------------------------------------
198 
199 // options may appear in any order separated by ',':
200 // preprocessor normalize_ip4: [id] [df] [rf] [tos] [trim]
Parse_IP4(struct _SnortConfig * sc,NormalizerContext * pc,char * args)201 static void Parse_IP4 (struct _SnortConfig *sc, NormalizerContext* pc, char* args)
202 {
203     char** toks;
204     int num_toks;
205     int i;
206 
207     Norm_Enable(pc, NORM_IP4);
208 
209     if ( !args )
210         args = "";
211 
212     toks = mSplit(args, ", ", 0, &num_toks, 0);
213 
214     for (i = 0; i < num_toks; i++)
215     {
216 #if 0
217         if ( !strcasecmp(toks[i], "id") )
218         {
219             Norm_Enable(pc, NORM_IP4_ID);
220         }
221         else
222 #endif
223         if ( !strcasecmp(toks[i], "df") )
224         {
225             Norm_Enable(pc, NORM_IP4_DF);
226         }
227         else if ( !strcasecmp(toks[i], "rf") )
228         {
229             Norm_Enable(pc, NORM_IP4_RF);
230         }
231         else if ( !strcasecmp(toks[i], "tos") )
232         {
233             Norm_Enable(pc, NORM_IP4_TOS);
234         }
235         else if ( !strcasecmp(toks[i], "trim") )
236         {
237             Norm_Enable(pc, NORM_IP4_TRIM);
238         }
239         else
240         {
241             ParseError("Invalid preprocessor normalize_ip4 option '%s'", toks[i]);
242         }
243     }
244     {
245         tSfPolicyId pid = getParserPolicy(sc);
246         SnortPolicy* policy = sc->targeted_policies[pid];
247 
248         if ( (policy->new_ttl > 1) && (policy->new_ttl >= policy->min_ttl) )
249         {
250             Norm_Enable(pc, NORM_IP4_TTL);
251         }
252     }
253     mSplitFree(&toks, num_toks);
254     Print_IP4(sc, pc);
255 }
256 
257 // preprocessor normalize_icmp4
Parse_ICMP4(NormalizerContext * pc,char * args)258 static void Parse_ICMP4 (NormalizerContext* pc, char* args)
259 {
260     Norm_Enable(pc, NORM_ICMP4);
261     Print_ICMP4(pc);
262 }
263 
264 // preprocessor normalize_ip6
Parse_IP6(struct _SnortConfig * sc,NormalizerContext * pc,char * args)265 static void Parse_IP6 (struct _SnortConfig *sc, NormalizerContext* pc, char* args)
266 {
267     Norm_Enable(pc, NORM_IP6);
268     {
269         tSfPolicyId pid = getParserPolicy(sc);
270         SnortPolicy* policy = sc->targeted_policies[pid];
271 
272         if ( (policy->new_ttl > 1) && (policy->new_ttl >= policy->min_ttl) )
273         {
274             Norm_Enable(pc, NORM_IP6_TTL);
275         }
276     }
277     Print_IP6(sc, pc);
278 }
279 
280 // preprocessor normalize_icmp6
Parse_ICMP6(NormalizerContext * pc,char * args)281 static void Parse_ICMP6 (NormalizerContext* pc, char* args)
282 {
283     Norm_Enable(pc, NORM_ICMP6);
284     Print_ICMP6(pc);
285 }
286 
287 // options may appear in any order separated by ',':
288 // preprocessor normalize_tcp: [ecn packet|stream] [urp] [opts] [allow <opt>+]
289 //
290 // <opt> ::= sack|echo|partial_order|alt_checksum|md5|#
291 // where 2 <= # <= 255.
Parse_TCP(NormalizerContext * pc,char * args)292 static void Parse_TCP (NormalizerContext* pc, char* args)
293 {
294     char **toks;
295     int num_toks;
296     int i, state = 0, opts = 0;
297 
298     if ( !args ) args = "";
299     toks = mSplit(args, ", ", 0, &num_toks, 0);
300 
301     for (i = 0; i < num_toks; i++)
302     {
303         switch ( state ) {
304         case 0:
305             if ( !strcasecmp(toks[i], "ecn") )
306             {
307                 state = 1;
308             }
309             else if ( !strcasecmp(toks[i], "block") )
310             {
311                 Norm_Enable(pc, NORM_TCP_BLOCK);
312             }
313             else if ( !strcasecmp(toks[i], "rsv") )
314             {
315                 Norm_Enable(pc, NORM_TCP_RSV);
316             }
317             else if ( !strcasecmp(toks[i], "pad") )
318             {
319                 Norm_Enable(pc, NORM_TCP_PAD);
320             }
321             else if ( !strcasecmp(toks[i], "req_urg") )
322             {
323                 Norm_Enable(pc, NORM_TCP_REQ_URG);
324             }
325             else if ( !strcasecmp(toks[i], "req_pay") )
326             {
327                 Norm_Enable(pc, NORM_TCP_REQ_PAY);
328             }
329             else if ( !strcasecmp(toks[i], "req_urp") )
330             {
331                 Norm_Enable(pc, NORM_TCP_URP);
332             }
333             else if ( !strcasecmp(toks[i], "urp") )
334             {
335                 Norm_Enable(pc, NORM_TCP_URP);
336             }
337             else if ( !strcasecmp(toks[i], "opts") )
338             {
339                 Norm_Enable(pc, NORM_TCP_OPT);
340             }
341             else if ( !strcasecmp(toks[i], "allow") )
342             {
343                 state = 2;
344                 opts = 0;
345             }
346             else if ( !strcasecmp(toks[i], "ips") )
347             {
348                 Norm_Enable(pc, NORM_TCP_IPS);
349             }
350             else if ( !strcasecmp(toks[i], "trim_syn") )
351             {
352                 Norm_Enable(pc, NORM_TCP_TRIM_SYN);
353             }
354             else if ( !strcasecmp(toks[i], "trim_rst") )
355             {
356                 Norm_Enable(pc, NORM_TCP_TRIM_RST);
357             }
358             else if ( !strcasecmp(toks[i], "trim_win") )
359             {
360                 Norm_Enable(pc, NORM_TCP_TRIM_WIN);
361             }
362             else if ( !strcasecmp(toks[i], "trim_mss") )
363             {
364                 Norm_Enable(pc, NORM_TCP_TRIM_MSS);
365             }
366             else if ( !strcasecmp(toks[i], "trim") )
367             {
368                 //Catch-all / backwards compatible
369                 Norm_Enable(pc, NORM_TCP_TRIM_SYN);
370                 Norm_Enable(pc, NORM_TCP_TRIM_RST);
371                 Norm_Enable(pc, NORM_TCP_TRIM_WIN);
372                 Norm_Enable(pc, NORM_TCP_TRIM_MSS);
373             }
374             else
375             {
376                 ParseError("Invalid preprocessor normalize_tcp option '%s'", toks[i]);
377             }
378             break;
379 
380         case 1:
381             if ( !strcasecmp(toks[i], "stream") )
382             {
383                 Norm_Enable(pc, NORM_TCP_ECN_STR);
384                 state = 0;
385             }
386             else if ( !strcasecmp(toks[i], "packet") )
387             {
388                 Norm_Enable(pc, NORM_TCP_ECN_PKT);
389                 state = 0;
390             }
391             else
392             {
393                 ParseError("Unknown ecn argument '%s'"
394                     " Need packet|stream", toks[i]);
395             }
396             break;
397 
398         case 2:
399             if ( !strcasecmp(toks[i], "sack") )
400             {
401                 Norm_TcpPassOption(pc, 4);
402                 Norm_TcpPassOption(pc, 5);
403                 opts++;
404             }
405             else if ( !strcasecmp(toks[i], "echo") )
406             {
407                 Norm_TcpPassOption(pc, 6);
408                 Norm_TcpPassOption(pc, 7);
409                 opts++;
410             }
411             else if ( !strcasecmp(toks[i], "partial_order") )
412             {
413                 Norm_TcpPassOption(pc, 9);
414                 Norm_TcpPassOption(pc, 10);
415                 opts++;
416             }
417             else if ( !strcasecmp(toks[i], "conn_count") )
418             {
419                 Norm_TcpPassOption(pc, 11);
420                 Norm_TcpPassOption(pc, 12);
421                 Norm_TcpPassOption(pc, 13);
422                 opts++;
423             }
424             else if ( !strcasecmp(toks[i], "alt_checksum") )
425             {
426                 Norm_TcpPassOption(pc, 14);
427                 Norm_TcpPassOption(pc, 15);
428                 opts++;
429             }
430             else if ( !strcasecmp(toks[i], "md5") )
431             {
432                 Norm_TcpPassOption(pc, 19);
433                 opts++;
434             }
435             else if ( isdigit(*toks[i]) )
436             {
437                 int opt = atoi(toks[i]);
438                 if ( 1 < opt && opt < 256 )
439                 {
440                     Norm_TcpPassOption(pc, (uint8_t)opt);
441                     opts++;
442                 }
443                 else
444                 {
445                     ParseError("Bad TCP option number '%s'; must be"
446                         " between 2 and 255 inclusive", toks[i]);
447                 }
448             }
449             else if ( opts > 0 )
450             {
451                 i--;
452                 state = 0;
453             }
454             else
455             {
456                 ParseError("Bad TCP option '%s'; must be"
457                     " sack|echo|partial_order|conn_count|alt_checksum|md5|#", toks[i]);
458             }
459             break;
460         }
461     }
462     if ( state == 1 )
463     {
464         ParseError("Missing argument for '%s'", toks[i-1]);
465     }
466     mSplitFree(&toks, num_toks);
467     Print_TCP(pc);
468 }
469 
470 //-------------------------------------------------------------------------
471 // printing stuff
472 //-------------------------------------------------------------------------
473 
474 #define ON "on"
475 #define OFF "off"
476 
LogConf(const char * p,const char * s)477 static inline void LogConf (const char* p, const char* s)
478 {
479     LogMessage("%12s: %s\n", p, s);
480 }
481 
LogFlag(const char * p,const NormalizerContext * nc,NormFlags nf)482 static inline void LogFlag (
483     const char* p, const NormalizerContext* nc, NormFlags nf)
484 {
485     const char* s = Norm_IsEnabled(nc, nf) ? ON : OFF;
486     LogConf(p, s);
487 }
488 
Print_IP4(struct _SnortConfig * sc,const NormalizerContext * nc)489 static void Print_IP4 (struct _SnortConfig *sc, const NormalizerContext* nc)
490 {
491     LogMessage("Normalizer config:\n");
492     LogFlag("ip4", nc, NORM_IP4);
493 
494     if ( Norm_IsEnabled(nc, NORM_IP4) )
495     {
496         //LogFlag("ip4::id", nc, NORM_IP4_ID);
497         LogFlag("ip4::df", nc, NORM_IP4_DF);
498         LogFlag("ip4::rf", nc, NORM_IP4_RF);
499         LogFlag("ip4::tos", nc, NORM_IP4_TOS);
500         LogFlag("ip4::trim", nc, NORM_IP4_TRIM);
501 
502         if ( Norm_IsEnabled(nc, NORM_IP4_TTL) )
503         {
504             tSfPolicyId pid = getParserPolicy(sc);
505             int min = sc->targeted_policies[pid]->min_ttl;
506             int new = sc->targeted_policies[pid]->new_ttl;
507             LogMessage("%12s: %s (min=%d, new=%d)\n", "ip4::ttl", ON, min, new);
508         }
509         else
510             LogConf("ip4::ttl", OFF);
511     }
512 }
513 
Print_ICMP4(const NormalizerContext * nc)514 static void Print_ICMP4 (const NormalizerContext* nc)
515 {
516     LogMessage("Normalizer config:\n");
517     LogFlag("icmp4", nc, NORM_ICMP4);
518 }
519 
Print_IP6(struct _SnortConfig * sc,const NormalizerContext * nc)520 static void Print_IP6 (struct _SnortConfig *sc, const NormalizerContext* nc)
521 {
522     LogMessage("Normalizer config:\n");
523     LogFlag("ip6", nc, NORM_IP6);
524 
525     if ( Norm_IsEnabled(nc, NORM_IP6) )
526     {
527         if ( Norm_IsEnabled(nc, NORM_IP6_TTL) )
528         {
529             tSfPolicyId pid = getParserPolicy(sc);
530             int min = sc->targeted_policies[pid]->min_ttl;
531             int new = sc->targeted_policies[pid]->new_ttl;
532             LogMessage("%12s: %s (min=%d, new=%d)\n", "ip6::hops", ON, min, new);
533         }
534         else
535             LogConf("ip6::hops", OFF);
536     }
537 }
538 
Print_ICMP6(const NormalizerContext * nc)539 static void Print_ICMP6 (const NormalizerContext* nc)
540 {
541     LogMessage("Normalizer config:\n");
542     LogFlag("icmp6", nc, NORM_ICMP6);
543 }
544 
Print_TCP(const NormalizerContext * nc)545 static void Print_TCP (const NormalizerContext* nc)
546 {
547     LogMessage("Normalizer config:\n");
548     LogFlag("tcp", nc, NORM_TCP);
549 
550     if ( Norm_IsEnabled(nc, NORM_TCP) )
551     {
552         const char* s;
553 
554         if ( Norm_IsEnabled(nc, NORM_TCP_ECN_PKT) )
555             s = "packet";
556         else if ( Norm_IsEnabled(nc, NORM_TCP_ECN_STR) )
557             s = "stream";
558         else
559             s = OFF;
560 
561         LogConf("tcp::ecn", s);
562         LogFlag("tcp::block", nc, NORM_TCP_BLOCK);
563         LogFlag("tcp::rsv", nc, NORM_TCP_RSV);
564         LogFlag("tcp::pad", nc, NORM_TCP_PAD);
565         LogFlag("tcp::req_urg", nc, NORM_TCP_REQ_URG);
566         LogFlag("tcp::req_pay", nc, NORM_TCP_REQ_PAY);
567         LogFlag("tcp::req_urp", nc, NORM_TCP_REQ_URP);
568         LogFlag("tcp::urp", nc, NORM_TCP_URP);
569 
570         if ( Norm_IsEnabled(nc, NORM_TCP_OPT) )
571         {
572             char buf[1024] = "";
573             char* p = buf;
574             int opt;
575             size_t min;
576 
577             p += snprintf(p, buf+sizeof(buf)-p, "%s", "(allow ");
578             min = strlen(buf);
579 
580             // TBD translate options to keywords allowed by parser
581             for ( opt = 2; opt < 256; opt++ )
582             {
583                 const char* fmt = (strlen(buf) > min) ? ",%d" : "%d";
584                 if ( Norm_TcpIsOptional(nc, opt) )
585                     p += snprintf(p, buf+sizeof(buf)-p, fmt, opt);
586             }
587             if ( strlen(buf) > min )
588             {
589                 snprintf(p, buf+sizeof(buf)-p, "%c", ')');
590                 buf[sizeof(buf)-1] = '\0';
591             }
592             LogMessage("%12s: %s %s\n", "tcp::opt", ON, buf);
593         }
594         else
595             LogConf("tcp::opt", OFF);
596 
597         LogFlag("tcp::ips", nc, NORM_TCP_IPS);
598         LogFlag("tcp::trim_syn", nc, NORM_TCP_TRIM_SYN);
599         LogFlag("tcp::trim_rst", nc, NORM_TCP_TRIM_RST);
600         LogFlag("tcp::trim_win", nc, NORM_TCP_TRIM_WIN);
601         LogFlag("tcp::trim_mss", nc, NORM_TCP_TRIM_MSS);
602     }
603 }
604 
605 //-------------------------------------------------------------------------
606 // preproc (main) stuff
607 //-------------------------------------------------------------------------
608 
Preproc_Install(struct _SnortConfig * sc)609 static void Preproc_Install (struct _SnortConfig *sc)
610 {
611 #ifdef PERF_PROFILING
612     RegisterPreprocessorProfile(
613         "normalize", &norm_perf_stats, 0, &totalPerfStats, NULL);
614 #endif
615     AddFuncToPreprocCleanExitList(
616         Preproc_CleanExit, NULL, PRIORITY_LAST, PP_NORMALIZE);
617 
618     AddFuncToPreprocResetList(
619         Preproc_Reset, NULL, PP_NORMALIZE_PRIORITY, PP_NORMALIZE);
620 
621     AddFuncToPreprocResetStatsList(
622         Preproc_ResetStats, NULL, PP_NORMALIZE_PRIORITY, PP_NORMALIZE);
623 
624     AddFuncToConfigCheckList(sc, Preproc_CheckConfig);
625     AddFuncToPreprocPostConfigList(sc, Preproc_PostConfigInit, NULL);
626     RegisterPreprocStats("normalize", Preproc_PrintStats);
627 }
628 
629 //-------------------------------------------------------------------------
630 
Preproc_CheckPolicy(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)631 static int Preproc_CheckPolicy (
632     struct _SnortConfig *sc,
633     tSfPolicyUserContextId set,
634     tSfPolicyId pid,
635     void* pv)
636 {
637     //NormalizerContext* pc = (NormalizerContext*)pv;
638     return 0;
639 }
640 
Preproc_CheckConfig(struct _SnortConfig * sc)641 static int Preproc_CheckConfig (struct _SnortConfig *sc)
642 {
643     int rval;
644 
645     if ( !base_set )
646         return 0;
647 
648     if ((rval = sfPolicyUserDataIterate(sc, base_set, Preproc_CheckPolicy)))
649         return rval;
650 
651     return 0;
652 }
653 
Preproc_PostInit(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)654 static int Preproc_PostInit (
655     struct _SnortConfig *sc,
656     tSfPolicyUserContextId set,
657     tSfPolicyId pid,
658     void* pv)
659 {
660     NormalizerContext *pc = (NormalizerContext *)pv;
661     SnortPolicy* policy = sc->targeted_policies[pid];
662 
663     if ( policy->new_ttl && policy->new_ttl < policy->min_ttl )
664     {
665         policy->new_ttl = policy->min_ttl;
666     }
667     Norm_SetConfig(pc);
668     return 0;
669 }
670 
Preproc_PostConfigInit(struct _SnortConfig * sc,void * pv)671 static void Preproc_PostConfigInit (struct _SnortConfig *sc, void* pv)
672 {
673     sfPolicyUserDataIterate(sc, base_set, Preproc_PostInit);
674 }
675 
676 //-------------------------------------------------------------------------
677 
Preproc_Execute(Packet * p,void * context)678 static void Preproc_Execute (Packet *p, void *context)
679 {
680     tSfPolicyId pid = getNapRuntimePolicy();
681     NormalizerContext* pc = (NormalizerContext*)sfPolicyUserDataGet(base_set, pid);
682     PROFILE_VARS;
683 
684     if ( !pc )
685         return;
686 
687     PREPROC_PROFILE_START(norm_perf_stats);
688 
689     if ( DAQ_GetInterfaceMode(p->pkth) == DAQ_MODE_INLINE )
690         if ( !Active_PacketWasDropped() )
691             if ( pc->normMode == NORM_MODE_ON || pc->normMode == NORM_MODE_WOULDA )
692                 Norm_Packet(pc, p);
693 
694     PREPROC_PROFILE_END(norm_perf_stats);
695     return;
696 }
697 
698 //-------------------------------------------------------------------------
699 
Preproc_FreeContext(NormalizerContext * pc)700 static void Preproc_FreeContext (NormalizerContext* pc)
701 {
702     if ( pc )
703         free(pc);
704 }
705 
Preproc_FreePolicy(tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)706 static int Preproc_FreePolicy(
707         tSfPolicyUserContextId set,
708         tSfPolicyId pid,
709         void* pv
710         )
711 {
712     NormalizerContext* pc = (NormalizerContext*)pv;
713 
714     sfPolicyUserDataClear(set, pid);
715     Preproc_FreeContext(pc);
716 
717     return 0;
718 }
719 
Preproc_FreeSet(tSfPolicyUserContextId set)720 static void Preproc_FreeSet (tSfPolicyUserContextId set)
721 {
722     if ( !set )
723         return;
724 
725     sfPolicyUserDataFreeIterate(set, Preproc_FreePolicy);
726     sfPolicyConfigDelete(set);
727 }
728 
729 //-------------------------------------------------------------------------
730 
Preproc_CleanExit(int signal,void * foo)731 static void Preproc_CleanExit (int signal, void *foo)
732 {
733     Preproc_FreeSet(base_set);
734 }
735 
Preproc_Reset(int signal,void * foo)736 static void Preproc_Reset (int signal, void *foo) { }
737 
Preproc_PrintStats(int exiting)738 static void Preproc_PrintStats(int exiting)
739 {
740     if(!ScNapPassiveMode())
741     {
742         Norm_PrintStats();
743         Stream_PrintNormalizationStats();
744     }
745 }
746 
Preproc_ResetStats(int signal,void * foo)747 static void Preproc_ResetStats (int signal, void *foo)
748 {
749     Norm_ResetStats();
750     Stream_ResetNormalizationStats();
751 }
752 
753 //-------------------------------------------------------------------------
754 // reload stuff
755 //-------------------------------------------------------------------------
756 
757 #ifdef SNORT_RELOAD
Reload_GetContext(struct _SnortConfig * sc,void ** new_config)758 static NormalizerContext* Reload_GetContext (struct _SnortConfig *sc, void **new_config)
759 {
760     tSfPolicyUserContextId swap_set;
761     NormalizerContext* pc = NULL;
762     tSfPolicyId policy_id = getParserPolicy(sc);
763 
764     if ( ScNapPassiveModeNewConf(sc) )
765         return NULL;
766 
767     if (!(swap_set = (tSfPolicyUserContextId)*new_config))
768         if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_ip4")))
769             if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_ip6")))
770                 if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_tcp")))
771                     if (!(swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_icmp4")))
772                         swap_set = (tSfPolicyUserContextId)GetRelatedReloadData(sc, "normalize_icmp6");
773 
774     if ( !swap_set )
775     {
776         swap_set = sfPolicyConfigCreate();
777         *new_config = (void *)swap_set;
778     }
779 
780     sc->normalizer_set  = true;
781 
782     sfPolicyUserPolicySet(swap_set, policy_id);
783     pc = sfPolicyUserDataGetCurrent(swap_set);
784 
785     if ( !pc )
786     {
787         pc = (NormalizerContext* )SnortAlloc(sizeof(NormalizerContext));
788         sfPolicyUserDataSetCurrent(swap_set, pc);
789 
790         if( pc->regFunc != init)
791         {
792             AddFuncToPreprocList(
793                 sc, Preproc_Execute, PP_NORMALIZE_PRIORITY, PP_NORMALIZE, PROTO_BITS);
794             pc->regFunc = reload;
795         }
796         session_api->enable_preproc_all_ports( sc, PP_NORMALIZE, PROTO_BITS );
797 
798     }
799     if ( sc->targeted_policies[policy_id]->nap_policy_mode == POLICY_MODE__INLINE_TEST )
800         pc->normMode = NORM_MODE_WOULDA;
801     else
802         pc->normMode = NORM_MODE_ON;
803     return pc;
804 }
805 
Reload_IP4(struct _SnortConfig * sc,char * args,void ** new_config)806 static void Reload_IP4 (struct _SnortConfig *sc, char* args, void **new_config)
807 {
808     NormalizerContext* pc = Reload_GetContext(sc, new_config);
809 
810     if ( pc )
811         Parse_IP4(sc, pc, args);
812     else
813         LogMessage(NOT_INLINE, "ip4");
814 }
815 
Reload_ICMP4(struct _SnortConfig * sc,char * args,void ** new_config)816 static void Reload_ICMP4 (struct _SnortConfig *sc, char* args, void **new_config)
817 {
818     NormalizerContext* pc = Reload_GetContext(sc, new_config);
819 
820     if ( pc )
821         Parse_ICMP4(pc, args);
822     else
823         LogMessage(NOT_INLINE, "icmp4");
824 }
825 
Reload_IP6(struct _SnortConfig * sc,char * args,void ** new_config)826 static void Reload_IP6 (struct _SnortConfig *sc, char* args, void **new_config)
827 {
828     NormalizerContext* pc = Reload_GetContext(sc, new_config);
829 
830     if ( pc )
831         Parse_IP6(sc, pc, args);
832     else
833         LogMessage(NOT_INLINE, "ip6");
834 }
835 
Reload_ICMP6(struct _SnortConfig * sc,char * args,void ** new_config)836 static void Reload_ICMP6 (struct _SnortConfig *sc, char* args, void **new_config)
837 {
838     NormalizerContext* pc = Reload_GetContext(sc, new_config);
839 
840     if ( pc )
841         Parse_ICMP6(pc, args);
842     else
843         LogMessage(NOT_INLINE, "icmp6");
844 }
845 
Reload_TCP(struct _SnortConfig * sc,char * args,void ** new_config)846 static void Reload_TCP (struct _SnortConfig *sc, char* args, void **new_config)
847 {
848     NormalizerContext* pc = Reload_GetContext(sc, new_config);
849 
850     if ( pc )
851         Parse_TCP(pc, args);
852     else
853         LogMessage(NOT_INLINE, "tcp");
854 }
855 
856 //-------------------------------------------------------------------------
857 
Reload_VerifyPolicy(struct _SnortConfig * sc,tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)858 static int Reload_VerifyPolicy (
859     struct _SnortConfig *sc,
860     tSfPolicyUserContextId set,
861     tSfPolicyId pid,
862     void* pv
863 ) {
864     //NormalizerContext* pc = (NormalizerContext*)pv;
865     SnortPolicy* policy = sc->targeted_policies[pid];
866     if ( policy->new_ttl && policy->new_ttl < policy->min_ttl )
867     {
868         policy->new_ttl = policy->min_ttl;
869     }
870     return 0;
871 }
872 
Reload_Verify(struct _SnortConfig * sc,void * swap_config)873 static int Reload_Verify(struct _SnortConfig *sc, void *swap_config)
874 {
875     int rval;
876     tSfPolicyUserContextId swap_set = (tSfPolicyUserContextId)swap_config;
877 
878     if ( !swap_set )
879         return -1;
880 
881     if ((rval = sfPolicyUserDataIterate (sc, swap_set, Reload_VerifyPolicy)))
882         return rval;
883 
884     return 0;
885 }
886 
887 //-------------------------------------------------------------------------
888 
Reload_SwapPolicy(tSfPolicyUserContextId set,tSfPolicyId pid,void * pv)889 static int Reload_SwapPolicy (
890     tSfPolicyUserContextId set,
891     tSfPolicyId pid,
892     void* pv)
893 {
894     NormalizerContext* pc = (NormalizerContext*)pv;
895 
896     sfPolicyUserDataClear(set, pid);
897     Preproc_FreeContext(pc);
898 
899     return 0;
900 }
901 
Reload_Swap(struct _SnortConfig * sc,void * swap_config)902 static void* Reload_Swap (struct _SnortConfig *sc, void *swap_config)
903 {
904     tSfPolicyUserContextId swap_set = (tSfPolicyUserContextId)swap_config;
905     tSfPolicyUserContextId old_set = base_set;
906 
907     if ( !swap_set )
908         return NULL;
909 
910     base_set = swap_set;
911 
912     sfPolicyUserDataIterate(sc, base_set, Preproc_PostInit);
913 
914     if ( old_set )
915     {
916         sfPolicyUserDataFreeIterate(old_set, Reload_SwapPolicy);
917 
918         if ( !sfPolicyUserPolicyGetActive(old_set) )
919             return (void*)old_set;
920     }
921     return NULL;
922 }
923 
924 //-------------------------------------------------------------------------
925 
Reload_Free(void * pv)926 static void Reload_Free (void* pv)
927 {
928     if ( !pv )
929         return;
930 
931     Preproc_FreeSet((tSfPolicyUserContextId)pv);
932 }
933 #endif
934 
935 //-------------------------------------------------------------------------
936 // public methods
937 //-------------------------------------------------------------------------
938 
Normalize_GetMode(const SnortConfig * sc,NormFlags nf)939 NormMode Normalize_GetMode (const SnortConfig* sc, NormFlags nf)
940 {
941     tSfPolicyId pid;
942     NormalizerContext* pc;
943 
944     if ( !base_set )
945         return NORM_MODE_OFF;
946 
947     if (!sc->normalizer_set)
948         return NORM_MODE_OFF;
949 
950     pid = getNapRuntimePolicy();
951     pc = sfPolicyUserDataGet(base_set, pid);
952 
953     if ( !pc )
954          return NORM_MODE_OFF;
955 
956     if ( Norm_IsEnabled(pc, nf) )
957         return pc->normMode;
958     return NORM_MODE_OFF;
959 }
960 
961 #endif  // NORMALIZER
962 
963