1 /*
2  * Argus Software
3  * Copyright (c) 2000-2016 QoSient, LLC
4  * All rights reserved.
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 as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  *
21  * $Id: //depot/argus/clients/examples/rapolicy/rapolicy.c#17 $
22  * $DateTime: 2016/06/01 15:17:28 $
23  * $Change: 3148 $
24  */
25 
26 /*
27  * rapolicy.c  - match input argus records against
28  *    a Cisco access control policy.
29  *
30  * written by Carter Bullard and Dave Edelman
31  * QoSient, LLC
32  *
33  */
34 
35 #ifdef HAVE_CONFIG_H
36 #include "argus_config.h"
37 #endif
38 
39 #if defined(CYGWIN)
40 #define USE_IPV6
41 #endif
42 
43 #define RA_POLICY_C
44 
45 #include <unistd.h>
46 #include <stdlib.h>
47 #include <errno.h>
48 #include <signal.h>
49 #include <ctype.h>
50 #include <stdio.h>
51 #include <arpa/inet.h>
52 
53 #include <argus_compat.h>
54 
55 #include <argus_util.h>
56 #include <argus_client.h>
57 #include <argus_main.h>
58 #include <argus_filter.h>
59 
60 
61 #include <rapolicy.h>
62 
63 struct RaPolicyPolicyStruct *RaPolicy = NULL;
64 struct RaPolicyPolicyStruct *RaGlobalPolicy = NULL;
65 
66 int RaPolicyParseResourceFile (struct ArgusParserStruct *, char *, struct RaPolicyPolicyStruct **);
67 int RaReadPolicy (struct ArgusParserStruct *, struct RaPolicyPolicyStruct **, char *);
68 int RaParsePolicy (struct ArgusParserStruct *, struct RaPolicyPolicyStruct **, char *);
69 int RaCheckPolicy (struct ArgusParserStruct *, struct ArgusRecordStruct *, struct RaPolicyPolicyStruct *);
70 int RaMeetsPolicyCriteria (struct ArgusParserStruct *, struct ArgusRecordStruct *, struct RaPolicyPolicyStruct *);
71 void RaDumpPolicy (struct ArgusParserStruct *, struct RaPolicyPolicyStruct *);
72 void RaDumpCounters (struct RaPolicyPolicyStruct *);
73 int RaDoNotification (struct ArgusRecordStruct *, struct RaPolicyPolicyStruct *);
74 
75 
76 void
ArgusClientInit(struct ArgusParserStruct * parser)77 ArgusClientInit (struct ArgusParserStruct *parser)
78 {
79    parser->RaWriteOut = 1;
80 
81    if (!(parser->RaInitialized)) {
82       (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
83 
84       parser->RaInitialized++;
85       parser->RaWriteOut = 0;
86 
87       if (parser->ArgusFlowModelFile != NULL) {
88          RaPolicyParseResourceFile (parser, parser->ArgusFlowModelFile, &RaPolicy);
89       } else {
90          if (!(parser->Xflag)) {
91             RaPolicyParseResourceFile (parser, "/usr/local/etc/rapolicy.conf", &RaPolicy);
92          }
93       }
94    }
95 }
96 
RaArgusInputComplete(struct ArgusInput * input)97 void RaArgusInputComplete (struct ArgusInput *input) { return; }
98 
99 
100 void
RaParseComplete(int sig)101 RaParseComplete (int sig)
102 {
103    if (sig >= 0) {
104       if (!ArgusParser->RaParseCompleting++) {
105 #ifdef ARGUSDEBUG
106          ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
107 #endif
108          switch (sig) {
109             case SIGHUP:
110             case SIGINT:
111             case SIGTERM:
112             case SIGQUIT: {
113                struct ArgusWfileStruct *wfile = NULL;
114 
115                if (ArgusParser->Aflag) {
116                       RaDumpCounters(RaPolicy);
117                   }
118 
119                ArgusShutDown(sig);
120 
121                if (ArgusParser->ArgusWfileList != NULL) {
122                   struct ArgusListObjectStruct *lobj = NULL;
123                   int i, count = ArgusParser->ArgusWfileList->count;
124 
125                   if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
126                      for (i = 0; i < count; i++) {
127                         if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
128                            if (wfile->fd != NULL) {
129 #ifdef ARGUSDEBUG
130                               ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
131 #endif
132                               fflush (wfile->fd);
133                               fclose (wfile->fd);
134                               wfile->fd = NULL;
135                            }
136                         }
137                         lobj = lobj->nxt;
138                      }
139                   }
140                }
141                exit(0);
142                break;
143             }
144          }
145       }
146    }
147 }
148 
149 
150 void
ArgusClientTimeout()151 ArgusClientTimeout ()
152 {
153 #ifdef ARGUSDEBUG
154    ArgusDebug (6, "ArgusClientTimeout()\n");
155 #endif
156 }
157 
158 void
parse_arg(int argc,char ** argv)159 parse_arg (int argc, char**argv)
160 {}
161 
162 void
usage()163 usage ()
164 {
165    extern char version[];
166 
167    fprintf (stdout, "Rapolicy Version %s\n", version);
168    fprintf (stdout, "usage: %s -f rapolicy.conf [ra-options]\n", ArgusParser->ArgusProgramName);
169 
170    fprintf (stdout, "options: -f rapolicy.conf file.\n");
171    fflush (stdout);
172 
173    exit(1);
174 }
175 
176 void
RaDumpCounters(struct RaPolicyPolicyStruct * policy)177 RaDumpCounters (struct RaPolicyPolicyStruct *policy)
178 {
179        printf("\nHit Rates [flows  packets   bytes]\n");
180        while (policy) {
181 	if(policy->hitCount != 0) {
182          printf("[%10lld %15lld %20lld]\tACL %s Line %ld: %s\n",
183            policy->hitCount, policy->hitPkts, policy->hitBytes,
184            policy->policyID, policy->line,  policy->str);
185 	}
186          policy = policy->nxt;
187        }
188 }
189 
190 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)191 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
192 {
193    struct ArgusFlow *flow = (struct ArgusFlow *) argus->dsrs[ARGUS_FLOW_INDEX];
194    int process= 0;
195 
196    switch (argus->hdr.type & 0xF0) {
197       case ARGUS_MAR:
198       case ARGUS_EVENT: {
199          break;
200       }
201 
202       case ARGUS_NETFLOW:
203       case ARGUS_FAR: {
204          if (flow) {
205             switch (flow->hdr.subtype & 0x3F) {
206                case ARGUS_FLOW_CLASSIC5TUPLE: {
207                   switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
208                      case ARGUS_TYPE_IPV4:
209                         switch (flow->ip_flow.ip_p) {
210                            case IPPROTO_TCP:
211                            default:
212                            case IPPROTO_UDP: {
213                               process++;
214                               break;
215                            }
216                         }
217                         break;
218 
219                      case ARGUS_TYPE_IPV6: {
220                         switch (flow->ipv6_flow.ip_p) {
221                            case IPPROTO_TCP:
222                            case IPPROTO_UDP: {
223 // not quite ready for IPv6                              process++;
224                               break;
225                            }
226                         }
227                         break;
228                      }
229                   }
230                   break;
231                }
232             }
233 
234             if (process){
235                struct ArgusRecordStruct *ns = ArgusCopyRecordStruct(argus);
236                if ((RaCheckPolicy (parser, ns, RaPolicy) || (parser->RaPolicyStatus & ARGUS_POLICY_JUST_LABEL)))
237                   RaSendArgusRecord (ns);
238 
239                ArgusDeleteRecordStruct(parser, ns);
240             }
241 
242             if ( (!process) && (parser->RaPolicyStatus & ARGUS_POLICY_PERMIT_OTHERS))
243                RaSendArgusRecord (argus);
244          }
245       }
246    }
247 
248 #ifdef ARGUSDEBUG
249    ArgusDebug (6, "RaProcessRecord () returning\n");
250 #endif
251 }
252 
253 int
RaSendArgusRecord(struct ArgusRecordStruct * ns)254 RaSendArgusRecord(struct ArgusRecordStruct *ns)
255 {
256    char buf[0x10000];
257    int retn = 1;
258 
259    if (ns->status & ARGUS_RECORD_WRITTEN)
260       return (retn);
261 
262    if ((ArgusParser->ArgusWfileList != NULL) && (!(ArgusListEmpty(ArgusParser->ArgusWfileList)))) {
263       struct ArgusWfileStruct *wfile = NULL;
264       struct ArgusListObjectStruct *lobj = NULL;
265       int i, count = ArgusParser->ArgusWfileList->count;
266 
267       if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
268          for (i = 0; i < count; i++) {
269             if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
270                int pass = 1;
271                if (wfile->filterstr) {
272                      struct nff_insn *wfcode = wfile->filter.bf_insns;
273                      pass = ArgusFilterRecord (wfcode, ns);
274                }
275 
276                if (pass != 0) {
277                   if ((ArgusParser->exceptfile == NULL) || strcmp(wfile->filename, ArgusParser->exceptfile)) {
278                      struct ArgusRecord *argusrec = NULL;
279                      if ((argusrec = ArgusGenerateRecord (ns, 0L, buf)) != NULL) {
280 #ifdef _LITTLE_ENDIAN
281                         ArgusHtoN(argusrec);
282 #endif
283                         ArgusWriteNewLogfile (ArgusParser, ns->input, wfile, argusrec);
284                      }
285                   }
286                }
287             }
288             lobj = lobj->nxt;
289          }
290       }
291 
292    } else {
293       if (!ArgusParser->qflag) {
294          if (ArgusParser->Lflag) {
295             if (ArgusParser->RaLabel == NULL)
296                ArgusParser->RaLabel = ArgusGenerateLabel(ArgusParser, ns);
297 
298             if (!(ArgusParser->RaLabelCounter++ % ArgusParser->Lflag))
299                printf ("%s\n", ArgusParser->RaLabel);
300 
301             if (ArgusParser->Lflag < 0)
302                ArgusParser->Lflag = 0;
303          }
304 
305          *(int *)&buf = 0;
306          ArgusPrintRecord(ArgusParser, buf, ns, MAXSTRLEN);
307          if (fprintf (stdout, "%s\n", buf) < 0)
308             RaParseComplete(SIGQUIT);
309          fflush(stdout);
310       }
311    }
312 
313    ns->status |= ARGUS_RECORD_WRITTEN;
314    return (retn);
315 }
316 
317 void ArgusWindowClose(void);
318 
ArgusWindowClose(void)319 void ArgusWindowClose(void) {
320 #ifdef ARGUSDEBUG
321    ArgusDebug (6, "ArgusWindowClose () returning\n");
322 #endif
323 }
324 
325 #define RAPOLICY_RCITEMS			8
326 
327 #define RA_POLICY_SHOW_WHICH			0
328 #define RA_POLICY_LABEL_ALL			1
329 #define RA_POLICY_LABEL_LOG			2
330 #define RA_POLICY_PERMIT_OTHERS			3
331 #define RA_POLICY_DUMP_POLICY			4
332 #define RA_POLICY_LABEL_IMPLICIT		5
333 #define RA_POLICY_JUST_LABEL			6
334 #define RA_POLICY_ACL_FILE                      7
335 
336 char *RaPolicyResourceFileStr [] = {
337    "RA_POLICY_SHOW_WHICH=",
338    "RA_POLICY_LABEL_ALL=",
339    "RA_POLICY_LABEL_LOG=",
340    "RA_POLICY_PERMIT_OTHERS=",
341    "RA_POLICY_DUMP_POLICY=",
342    "RA_POLICY_LABEL_IMPLICIT=",
343    "RA_POLICY_JUST_LABEL=",
344    "RA_POLICY_ACL_FILE=",
345 };
346 
347 
348 int RaInitialState = 0;
349 int RaParseError = 0;
350 
351 char *RaParseErrorStr [POLICYERRORNUM] = {
352    "access-list identifier not found",
353    "policy id number not found",
354    "permit/deny indication not found",
355    "protocol indentifier not found",
356    "no source address defined",
357    "no source address mask defined",
358    "wrong source port operator",
359    "wrong source port specification"
360    "no destination address defined",
361    "no destination address mask defined",
362    "wrong destination port operator",
363    "wrong destination port specification",
364    "access violation notification not found",
365 };
366 
367 int
RaPolicyParseResourceFile(struct ArgusParserStruct * parser,char * file,struct RaPolicyPolicyStruct ** policy)368 RaPolicyParseResourceFile (struct ArgusParserStruct *parser, char *file, struct RaPolicyPolicyStruct **policy)
369 {
370    int retn = 0;
371    int i, len, done = 0, linenum = 0;
372    struct RaPolicyPolicyStruct *pol;
373    char strbuf[MAXSTRLEN], *str = strbuf, *optarg;
374    FILE *fd;
375 
376    if (file) {
377       if ((fd = fopen (file, "r")) != NULL) {
378          while ((fgets(str, MAXSTRLEN, fd)) != NULL)  {
379             done = 0;  linenum++;
380             while (*str && isspace((int)*str))
381                 str++;
382 
383             if (*str && (*str != '#') && (*str != '\n') && (*str != '!')) {
384                for (i = 0; i < RAPOLICY_RCITEMS && !done; i++) {
385                   len = strlen(RaPolicyResourceFileStr[i]);
386                   if (!(strncmp (str, RaPolicyResourceFileStr[i], len))) {
387                      optarg = &str[len];
388                      if (*optarg == '\"') { optarg++; }
389                      if (optarg[strlen(optarg) - 1] == '\n')
390                         optarg[strlen(optarg) - 1] = '\0';
391                      if (optarg[strlen(optarg) - 1] == '\"')
392                         optarg[strlen(optarg) - 1] = '\0';
393 
394                      switch (i) {
395                         case RA_POLICY_SHOW_WHICH: {
396                            if (!(strncasecmp(optarg, "deny", 4)))
397                               parser->RaPolicyStatus |= ARGUS_POLICY_SHOW_DENY;
398                            else
399                               parser->RaPolicyStatus &= ~ARGUS_POLICY_SHOW_DENY;
400                            break;
401                         }
402                         case RA_POLICY_LABEL_ALL: {
403                            if (!(strncasecmp(optarg, "yes", 3)))
404                               parser->RaPolicyStatus |= ARGUS_POLICY_LABEL_ALL;
405                            else
406                               parser->RaPolicyStatus &= ~ARGUS_POLICY_LABEL_ALL;
407                            break;
408                         }
409                         case RA_POLICY_LABEL_LOG: {
410                            if (!(strncasecmp(optarg, "yes", 3)))
411                               parser->RaPolicyStatus |= ARGUS_POLICY_LABEL_LOG;
412                            else
413                               parser->RaPolicyStatus &= ~ARGUS_POLICY_LABEL_LOG;
414                            break;
415                         }
416                         case RA_POLICY_PERMIT_OTHERS: {
417                            if (!(strncasecmp(optarg, "yes", 3)))
418                               parser->RaPolicyStatus |= ARGUS_POLICY_PERMIT_OTHERS;
419                            else
420                               parser->RaPolicyStatus &= ~ARGUS_POLICY_PERMIT_OTHERS;
421                            break;
422                         }
423                         case RA_POLICY_DUMP_POLICY: {
424                            if (!(strncasecmp(optarg, "yes", 3)))
425                               parser->RaPolicyStatus |= ARGUS_POLICY_DUMP_POLICY;
426                            else
427                               parser->RaPolicyStatus &= ~ARGUS_POLICY_DUMP_POLICY;
428                            break;
429                         }
430                         case RA_POLICY_LABEL_IMPLICIT: {
431                            if (!(strncasecmp(optarg, "yes", 3)))
432                               parser->RaPolicyStatus |= ARGUS_POLICY_LABEL_IMPLICIT;
433                            else
434                               parser->RaPolicyStatus &= ~ARGUS_POLICY_LABEL_IMPLICIT;
435                            break;
436                         }
437                         case RA_POLICY_JUST_LABEL: {
438                            if (!(strncasecmp(optarg, "yes", 3)))
439                               parser->RaPolicyStatus |= ARGUS_POLICY_JUST_LABEL;
440                            else
441                               parser->RaPolicyStatus &= ~ARGUS_POLICY_JUST_LABEL;
442                            break;
443                         }
444                        case RA_POLICY_ACL_FILE: {
445                           if (!(RaReadPolicy(parser, policy, optarg) > 0) ){
446                              ArgusLog (LOG_ERR, "RaPolicy: RaReadPolicy Error");
447                              exit(0);
448                           }
449                           if (parser->RaPolicyStatus & ARGUS_POLICY_DUMP_POLICY) {
450                              pol = *policy;
451                              while (pol) {
452                                 RaDumpPolicy(parser, pol);
453                                 pol = pol->nxt;
454                              }
455                              exit(1);
456                           }
457                           break;
458                        }
459                      }
460                   }
461                }
462             }
463          }
464          fclose(fd);
465       }
466    }
467 
468 #ifdef ARGUSDEBUG
469    ArgusDebug (2, "RaPolicyParseResourceFile (%p, %s, %p) returning %d\n", parser, file, policy, retn);
470 #endif
471 
472    return (retn);
473 }
474 
475 int
RaReadPolicy(struct ArgusParserStruct * parser,struct RaPolicyPolicyStruct ** policy,char * file)476 RaReadPolicy (struct ArgusParserStruct *parser, struct RaPolicyPolicyStruct **policy, char *file)
477 {
478    int retn = 1, linenum = 0;
479    struct RaPolicyPolicyStruct *pol, *policyLast = NULL;
480    char buffer [1024];
481    FILE *fd;
482 
483    if (file) {
484       if ((fd = fopen (file, "r")) != NULL) {
485          while (fgets (buffer, 1024, fd)) {
486             linenum++;
487             pol = NULL;
488             if ((*buffer != '#') && (*buffer != '\n') && (*buffer != '!')) {
489                if ((retn = RaParsePolicy (parser, &pol, buffer)) > 0) {
490                   if (policyLast)  {
491                      policyLast->nxt = pol;
492                      pol->prv = policyLast;
493                      pol->line = linenum;
494                      pol->policyID = policyLast->policyID;
495                      policyLast = pol;
496                   } else {
497                      *policy = policyLast = pol;
498                      pol->line = linenum;
499                     }
500                   if (retn < 0)
501                      ArgusLog (LOG_ERR, "RaReadPolicy: line %d: %s\n", linenum, RaParseErrorStr [RaParseError]);
502                }
503                      sprintf (buffer, "ACL=%s_%s_Line_%4.4d",
504                            pol->flags & RA_PERMIT ? "Permit" : "Deny",
505                            pol->policyID,
506                            (int) pol->line
507                      );
508                      pol->labelStr = strdup(buffer);
509                      if(pol->str[strlen(pol->str)-1] == '\n') pol->str[strlen(pol->str)-1] = '\0';
510             }
511          }
512          fclose (fd);
513          retn = 1;
514 
515       } else {
516          retn = 0;
517          ArgusLog (LOG_ERR, "RaReadPolicy: fopen %s %s\n", file,  strerror(errno));
518       }
519    }
520 
521 #if defined(ARGUSDEBUG)
522    ArgusDebug (2, "RaReadPolicy (0x%x, %s) returning %d\n", policy, file, retn);
523 #endif
524    return (retn);
525 }
526 
527 
528 void
RaDumpPolicy(struct ArgusParserStruct * parser,struct RaPolicyPolicyStruct * policy)529 RaDumpPolicy (struct ArgusParserStruct *parser, struct RaPolicyPolicyStruct *policy)
530 {
531 struct protoent *proto;
532 arg_uint32 host, any, low, high;
533 
534 host = ntohl(inet_addr("0.0.0.0"));
535 any = ntohl(inet_addr("255.255.255.255"));
536 
537     printf("%s Line %4.4ld %s\n",
538            policy->policyID, policy->line, policy->str);
539 
540 
541     printf("\tThe pointer to the previous policy is %s, to the next policy is %s\n",
542            policy->prv == NULL ? "empty (this is the first entry)" : "defined",
543            policy->nxt == NULL ? "empty (this is the final entry)" : "defined" );
544 
545     if(!((policy->flags & RA_PERMIT) || (policy->flags & RA_DENY))){
546        return ;
547    }
548 
549     printf("\tIn the case of a match, the flow will be %s%s\n",
550            (policy->flags & RA_PERMIT) ? "permitted" : "",
551            (policy->flags & RA_DENY) ? "denied" : "");
552 
553     if (policy->proto == 0) {
554        printf("\tThe policy will be applied to flows matching any IP based protocol\n");
555     }  else {
556         proto = getprotobynumber((int) policy->proto);
557         printf("\tThe policy will be applied to flows matching the %s (%d) protocol\n",
558            proto->p_name, policy->proto );
559     }
560     printf("\tThe policy flag value is %lx, which means that a match has these requirements:\n",
561            policy->flags);
562 
563     if (policy->flags & RA_SRC_SET) {
564         printf("\tThe source address will be evaluated:\n");
565         printf("\t\tThe source address is %lx (%s) and the source wildcard is %lx (%s)\n",
566            policy->src.addr, ArgusGetName(parser, (u_char *) &policy->src.addr),
567            policy->src.mask, ArgusGetName(parser, (u_char *) &policy->src.mask));
568         if((policy->src.addr == host) && (policy->src.mask == any)) {
569            printf("\t\tThe source may be any IP address\n");
570         } else {
571           if (policy->src.mask == any) {
572               printf("\t\tThe specific host IP address much match\n");
573           } else {
574             low = policy->src.addr & ~policy->src.mask;
575             high = low + policy->src.mask;
576             printf("\t\tThe source may be any IP address in the range %s - %s (with possible gaps)\n",
577                ArgusGetName(parser, (u_char *)  &low),
578                ArgusGetName(parser, (u_char *) &high));
579             }
580        }
581     } else {
582         printf("\tThe source address will not be evaluated to determine a match\n");
583       }
584 
585 
586     if (policy->flags & RA_DST_SET) {
587         printf("\tThe destination address will be evaluated:\n");
588         printf("\t\tThe destination address is %lx (%s) and the destination wildcard is %lx (%s)\n",
589            policy->dst.addr, ArgusGetName(parser, (u_char *) &policy->dst.addr),
590            policy->dst.mask, ArgusGetName(parser, (u_char *) &policy->dst.mask));
591         if((policy->dst.addr == host) && (policy->dst.mask == any)) {
592            printf("\t\tThe destination may be any IP address\n");
593         } else {
594           if (policy->dst.mask == any) {
595               printf("\t\tThe specific host IP address much match\n");
596           } else {
597             low = policy->dst.addr & ~policy->dst.mask;
598             high = low + policy->dst.mask;
599             printf("\t\tThe destination may be any IP address in the range %s - %s (with possible gaps)\n",
600                ArgusGetName(parser, (u_char *) &low),
601                ArgusGetName(parser, (u_char *) &high));
602             }
603        }
604     } else {
605         printf("\tThe destination address will not be evaluated to determine a match\n");
606       }
607 
608      if (policy->flags & RA_SRCPORT_SET) {
609        printf("\tThe source port will be evaluated and must ");
610        switch (policy->src_action){
611           case (RA_EQ):
612              printf("be equal to %d\n", policy->src_port_low);
613              break;
614           case (RA_LT):
615              printf("be less than %d\n", policy->src_port_low);
616              break;
617           case (RA_GT):
618              printf("be greater than %d\n", policy->src_port_low);
619              break;
620           case (RA_NEQ):
621              printf("not be equal to %d\n", policy->src_port_low);
622              break;
623           case (RA_RANGE):
624              printf("be between %d and  %d\n", policy->src_port_low, policy->src_port_hi);
625              break;
626       }
627     } else {
628        printf("\tThe source port will not be evaluated to determine a match\n");
629     }
630      if (policy->flags & RA_DSTPORT_SET) {
631        printf("\tThe destination port will be evaluated and must ");
632        switch (policy->dst_action){
633           case (RA_EQ):
634              printf("be equal to %d\n", policy->dst_port_low);
635              break;
636           case (RA_LT):
637              printf("be less than %d\n", policy->dst_port_low);
638              break;
639           case (RA_GT):
640              printf("be greater than %d\n", policy->dst_port_low);
641              break;
642           case (RA_NEQ):
643              printf("not be equal to %d\n", policy->dst_port_low);
644              break;
645           case (RA_RANGE):
646              printf("be between %d and  %d\n", policy->dst_port_low, policy->dst_port_hi);
647              break;
648       }
649     } else {
650        printf("\tThe destination port will not be evaluated to determine a match\n");
651     }
652    if (policy->flags & RA_TCPFLG_SET) {
653       printf("\tThe set of TCP flags from the source will be evaluated and must include:\n\t");
654       if (policy->TCPflags & RA_FIN) printf(" FIN ");
655       if (policy->TCPflags & RA_SYN) printf(" SYN ");
656       if (policy->TCPflags & RA_RST) printf(" RST ");
657       if (policy->TCPflags & RA_PSH) printf(" PSH ");
658       if (policy->TCPflags & RA_ACK) printf(" ACK ");
659       if (policy->TCPflags & RA_URG) printf(" URG ");
660       if (policy->TCPflags & RA_ECE) printf(" ECE ");
661       if (policy->TCPflags & RA_CWR) printf(" CWR ");
662       if (policy->TCPflags & RA_NS) printf(" NS ");
663       if (policy->flags & RA_EST_SET) printf(" the TCP session must be established (have the ACK or RST flag set) ");
664       printf("\n");
665   }
666   if (policy->flags & RA_TOS_SET) {
667      printf("\tThe TOS must be equal to %d\n", policy->tos);
668   }
669   if (policy->flags & RA_ICMP_SET) {
670      printf("\tThe ICMP message type must be %d ", policy->ICMPtype);
671      if (policy->ICMPcode < ICMPCodeAny) {
672         printf("and the ICMP message code must be %d\n", policy->ICMPcode);
673      } else {
674         printf("with any valid ICMP code value\n");
675      }
676   }
677  return ;
678 }
679 
680 
681 #include <string.h>
682 #include <sys/socket.h>
683 #include <netinet/in.h>
684 #include <arpa/inet.h>
685 
686 #include <ctype.h>
687 
688 
689 // Terminating Error
690 
691 events_t
terror(struct RaPolicyPolicyStruct * policy,char * token)692 terror (struct RaPolicyPolicyStruct *policy, char *token)
693 {
694 #ifdef ARGUSDEBUG
695    ArgusDebug (3, "terror word is %s [%d]\n", token, strlen(token));
696 #endif
697 
698    printf ("The ACL parser encountered a problem with \"%s\" set debug to 3 for more information\n", token);
699    exit (1);
700 }
701 
702 events_t
initACL(struct RaPolicyPolicyStruct * policy,char * token)703 initACL (struct RaPolicyPolicyStruct *policy, char *token)
704 {
705 #ifdef ARGUSDEBUG
706    ArgusDebug (3, "initACL the word is %s\n", token);
707 #endif
708 
709    policy->type = RA_IPACCESSLIST;
710    return E_NULL;
711 }
712 
713 events_t
initEXT(struct RaPolicyPolicyStruct * policy,char * token)714 initEXT (struct RaPolicyPolicyStruct *policy, char *token)
715 {
716 #ifdef ARGUSDEBUG
717    ArgusDebug (3, "initEXT the word is %s\n", token);
718 #endif
719 
720    policy->type = RA_IPACCESSLIST;
721    return E_NULL;
722 }
723 
724 events_t
procACLnum(struct RaPolicyPolicyStruct * policy,char * token)725 procACLnum (struct RaPolicyPolicyStruct *policy, char *token)
726 {
727    int acl = atoi(token);
728 
729 #ifdef ARGUSDEBUG
730    ArgusDebug (3, "procACLnum the word is %s\n", token);
731 #endif
732 
733    policy->policyID = strdup(token);
734 
735 //
736 // The ACL numbers indicate the type of access control list
737 //
738 //    1 -   99   Standard IP access list
739 //  100 -  199   Extended IP access list
740 //  200 -  299   Ethernet Type Code access list
741 //  700 -  799   Ethernet Address access control list
742 // 1300 - 1999   Standard IP access list
743 // 2000 - 2699   Extended IP access list
744 //
745 // There were other ranges defined but DECnet, IPX, XNS, Vines AppleTalk seem to have fallen out of favor
746 //
747    if (acl > 0 && acl < 100)
748       return E_STD;
749 
750    if (acl > 1299 && acl < 2000)
751       return E_STD;
752 
753    if (acl > 99 && acl < 200)
754       return E_EXT;
755 
756    if (acl > 1999 && acl < 2700)
757       return E_EXT;
758 
759    if (acl > 199 && acl < 300)
760       return E_IGNORE;
761 
762    if (acl > 699 && acl < 800)
763       return E_IGNORE;
764 
765    return E_NULL;
766 }
767 
768 events_t
saveName(struct RaPolicyPolicyStruct * policy,char * token)769 saveName (struct RaPolicyPolicyStruct *policy, char *token)
770 {
771 #ifdef ARGUSDEBUG
772    ArgusDebug (3, "saveName the word is %s\n", token);
773 #endif
774 
775    policy->policyID = strdup(token);
776    return E_NULL;
777 }
778 
779 events_t
notYet(struct RaPolicyPolicyStruct * policy,char * token)780 notYet (struct RaPolicyPolicyStruct *policy, char *token)
781 {
782 #ifdef ARGUSDEBUG
783    ArgusDebug  (3, "this capability is not yet available the word is %s\n", token);
784 #endif
785 
786    return E_NULL;
787 }
788 
789 events_t
setAction(struct RaPolicyPolicyStruct * policy,char * token)790 setAction (struct RaPolicyPolicyStruct *policy, char *token)
791 {
792 #ifdef ARGUSDEBUG
793    ArgusDebug (3, "setAction the word is %s\n", token);
794 #endif
795 
796    if ( !strcasecmp("permit", token))
797       policy->flags |= RA_PERMIT;
798    if ( !strcasecmp("deny", token))
799       policy->flags |= RA_DENY;
800    return E_NULL;
801 }
802 
803 // Set Source Address
804 events_t
setsAddr(struct RaPolicyPolicyStruct * policy,char * token)805 setsAddr (struct RaPolicyPolicyStruct *policy, char *token)
806 {
807 #ifdef ARGUSDEBUG
808    ArgusDebug (3, "setsAddr the word is %s\n", token);
809 #endif
810 
811    policy->src.addr = ntohl(inet_addr(token));
812    policy->flags |= RA_SRC_SET;
813    return E_NULL;
814 }
815 
816 // Set Source wildcard
817 events_t
setswc(struct RaPolicyPolicyStruct * policy,char * token)818 setswc (struct RaPolicyPolicyStruct *policy, char *token)
819 {
820 #ifdef ARGUSDEBUG
821    ArgusDebug (3, "3, setswc the word is %s\n", token);
822 #endif
823 
824    policy->src.mask = ntohl(inet_addr(token));
825    policy->flags |= RA_SRC_SET;
826    return E_NULL;
827 }
828 
829 // Set a source ANY address
830 events_t
setsany(struct RaPolicyPolicyStruct * policy,char * token)831 setsany (struct RaPolicyPolicyStruct *policy, char *token)
832 {
833 #ifdef ARGUSDEBUG
834    ArgusDebug (3, "3, setsany the word is %s\n", token);
835 #endif
836 
837    policy->src.addr = ntohl(inet_addr("0.0.0.0"));
838    policy->src.mask = ntohl(inet_addr("255.255.255.255"));
839    policy->flags |= RA_SRC_SET;
840    return E_NULL;
841 }
842 
843 events_t
finished(struct RaPolicyPolicyStruct * policy,char * token)844 finished (struct RaPolicyPolicyStruct *policy, char *token)
845 {
846 #ifdef ARGUSDEBUG
847    ArgusDebug (3, "finished the word is %s\n", token);
848 #endif
849 
850    return E_NULL;
851 }
852 
853 events_t
getSeq(struct RaPolicyPolicyStruct * policy,char * token)854 getSeq (struct RaPolicyPolicyStruct *policy, char *token)
855 {
856 #ifdef ARGUSDEBUG
857    ArgusDebug (3, "getSeq the word is %s\n", token);
858 #endif
859 
860    policy->seq = atoi(token);
861    return E_NULL;
862 }
863 
864 events_t
setdAddr(struct RaPolicyPolicyStruct * policy,char * token)865 setdAddr (struct RaPolicyPolicyStruct *policy, char *token)
866 {
867 #ifdef ARGUSDEBUG
868    ArgusDebug (3, "setdAddr the word is %s\n", token);
869 #endif
870 
871    policy->dst.addr = ntohl(inet_addr(token));
872    policy->flags |= RA_DST_SET;
873    return E_NULL;
874 }
875 
876 events_t
setdwc(struct RaPolicyPolicyStruct * policy,char * token)877 setdwc (struct RaPolicyPolicyStruct *policy, char *token)
878 {
879 #ifdef ARGUSDEBUG
880    ArgusDebug (3, "setdwc the word is %s\n", token);
881 #endif
882 
883    policy->dst.mask = ntohl(inet_addr(token));
884    policy->flags |= RA_DST_SET;
885    return E_NULL;
886 }
887 
888 events_t
setdany(struct RaPolicyPolicyStruct * policy,char * token)889 setdany (struct RaPolicyPolicyStruct *policy, char *token)
890 {
891 #ifdef ARGUSDEBUG
892    ArgusDebug (3, "setdany the word is %s\n", token);
893 #endif
894 
895    policy->dst.addr = ntohl(inet_addr("0.0.0.0"));
896    policy->dst.mask = ntohl(inet_addr("255.255.255.255"));
897    policy->flags |= RA_DST_SET;
898    return E_NULL;
899 }
900 
901 events_t
setsrel(struct RaPolicyPolicyStruct * policy,char * token)902 setsrel (struct RaPolicyPolicyStruct *policy, char *token)
903 {
904 #ifdef ARGUSDEBUG
905    ArgusDebug (3, "setsrel the word is %s\n", token);
906 #endif
907 
908    if (!strcasecmp("eq", token))
909       policy->src_action = RA_EQ;
910    if (!strcasecmp("ne", token))
911       policy->src_action = RA_NEQ;
912    if (!strcasecmp("lt", token))
913       policy->src_action = RA_LT;
914    if (!strcasecmp("gt", token))
915       policy->src_action = RA_GT;
916    if (!strcasecmp("range", token))
917       policy->src_action = RA_RANGE;
918    return E_NULL;
919 }
920 
921 events_t
setdrel(struct RaPolicyPolicyStruct * policy,char * token)922 setdrel (struct RaPolicyPolicyStruct *policy, char *token)
923 {
924 #ifdef ARGUSDEBUG
925    ArgusDebug (3, "setdrel the word is %s\n", token);
926 #endif
927 
928    if (!strcasecmp("eq", token))
929       policy->dst_action = RA_EQ;
930    if (!strcasecmp("ne", token))
931       policy->dst_action = RA_NEQ;
932    if (!strcasecmp("lt", token))
933       policy->dst_action = RA_LT;
934    if (!strcasecmp("gt", token))
935       policy->dst_action = RA_GT;
936    if (!strcasecmp("range", token))
937       policy->dst_action = RA_RANGE;
938    return E_NULL;
939 }
940 
941 events_t
setProto(struct RaPolicyPolicyStruct * policy,char * token)942 setProto(struct RaPolicyPolicyStruct *policy, char *token)
943 {
944 #ifdef ARGUSDEBUG
945    ArgusDebug (3, "setProto the word is %s\n", token);
946 #endif
947 
948    if (isdigit(token[0])) {
949       policy->proto = atoi(token);
950    } else {
951       struct protoent *proto;
952       if ((proto = getprotobyname(token)) != NULL)
953          policy->proto = proto->p_proto;
954    }
955 #ifdef ARGUSDEBUG
956    ArgusDebug (3, "setProto %s is %d\n", token,  policy->proto);
957 #endif
958 
959    policy->flags |= RA_PROTO_SET;
960    return E_NULL;
961 }
962 
963 events_t
setsport(struct RaPolicyPolicyStruct * policy,char * token)964 setsport(struct RaPolicyPolicyStruct *policy, char *token)
965 {
966 #ifdef ARGUSDEBUG
967    ArgusDebug (3, "setsport the word is %s\n", token);
968 #endif
969 
970    policy->src_port_low = (arg_uint16) atoi(token);
971    policy->flags |= RA_SRCPORT_SET;
972    return E_NULL;
973 }
974 
975 events_t
setdport(struct RaPolicyPolicyStruct * policy,char * token)976 setdport(struct RaPolicyPolicyStruct *policy, char *token)
977 {
978 #ifdef ARGUSDEBUG
979    ArgusDebug (3, "sdport the word is %s\n", token);
980 #endif
981 
982    policy->dst_port_low = (arg_uint16) atoi(token);
983    policy->flags |= RA_DSTPORT_SET;
984    return E_NULL;
985 }
986 
987 events_t
setsport2(struct RaPolicyPolicyStruct * policy,char * token)988 setsport2(struct RaPolicyPolicyStruct *policy, char *token)
989 {
990 #ifdef ARGUSDEBUG
991    ArgusDebug (3, "setsport2 the word is %s\n", token);
992 #endif
993 
994    policy->src_port_hi = (arg_uint16) atoi(token);
995    policy->flags |= RA_SRCPORT_SET;
996    return E_NULL;
997 }
998 
999 events_t
setdport2(struct RaPolicyPolicyStruct * policy,char * token)1000 setdport2(struct RaPolicyPolicyStruct *policy, char *token)
1001 {
1002 #ifdef ARGUSDEBUG
1003    ArgusDebug (3, "setsport2 the word is %s\n", token);
1004 #endif
1005 
1006    policy->dst_port_hi = (arg_uint16) atoi(token);
1007    policy->flags |= RA_DSTPORT_SET;
1008    return E_NULL;
1009 }
1010 
1011 events_t
setsportname(struct RaPolicyPolicyStruct * policy,char * token)1012 setsportname(struct RaPolicyPolicyStruct *policy, char *token)
1013 {
1014    int port, proto;
1015 
1016 
1017    proto = (policy->proto) ?  policy->proto : 17 ;
1018    argus_nametoport(token, &port, &proto);
1019 #ifdef ARGUSDEBUG
1020    ArgusDebug (3, "setsportname the word is %s the proto is %d  the port is %d\n", token, proto, port);
1021 #endif
1022    policy->src_port_low = port;
1023    policy->flags |= RA_SRCPORT_SET;
1024    return E_NULL;
1025 }
1026 
1027 events_t
setdportname(struct RaPolicyPolicyStruct * policy,char * token)1028 setdportname(struct RaPolicyPolicyStruct *policy, char *token)
1029 {
1030    int port, proto;
1031 
1032 
1033    proto = (policy->proto) ?  policy->proto : 17 ; // Or your favorite manifest constant
1034    argus_nametoport(token, &port, &proto);
1035 #ifdef ARGUSDEBUG
1036    ArgusDebug (3, "setsportname the word is %s the proto is %d  the port is %d\n", token, proto, port);
1037 #endif
1038    policy->dst_port_low = port;
1039    policy->flags |= RA_DSTPORT_SET;
1040    return E_NULL;
1041 }
1042 
1043 events_t
flagLog(struct RaPolicyPolicyStruct * policy,char * token)1044 flagLog(struct RaPolicyPolicyStruct *policy, char *token)
1045 {
1046 #ifdef ARGUSDEBUG
1047    ArgusDebug (3, "flagLog the word is %s\n", token);
1048 #endif
1049 
1050    policy->flags |= RA_LOG_SET;
1051    return E_NULL;
1052 }
1053 
1054 events_t
setIGMP(struct RaPolicyPolicyStruct * policy,char * token)1055 setIGMP(struct RaPolicyPolicyStruct *policy, char *token)
1056 {
1057    int i;
1058 
1059    for ( i = 0; igmpmap[i].len > 0; i++) {
1060       if (!strncasecmp(igmpmap[i].name, token, igmpmap[i].len)) {
1061          policy->IGMPtype = igmpmap[i].value;
1062 #ifdef ARGUSDEBUG
1063          ArgusDebug (3, "setIGMP the word is %s\n", token);
1064 #endif
1065 
1066          policy->flags |= RA_IGMP_SET;
1067          return E_NULL;
1068       }
1069    }
1070 
1071    // The IGMP type can be expressed as a number
1072    if (isdigit(token[0])) {
1073       i = atoi(token);
1074       if (( i > 0) && (i < 256) ) {
1075          policy->IGMPtype = i;
1076 #ifdef ARGUSDEBUG
1077          ArgusDebug( 3, "setIGMP the IGMP type is %d\n", i);
1078 #endif
1079 
1080          policy->flags |= RA_IGMP_SET;
1081          return E_NULL;
1082       }
1083    }
1084 #ifdef ARGUSDEBUG
1085    ArgusDebug (3, "%s is not a valid IGMP type\n", token);
1086 #endif
1087 
1088    return E_NULL;
1089 }
1090 
1091 events_t
setICMPmsg(struct RaPolicyPolicyStruct * policy,char * token)1092 setICMPmsg(struct RaPolicyPolicyStruct *policy, char *token)
1093 {
1094    int i;
1095 #ifdef ARGUSDEBUG
1096    ArgusDebug (3, "setICMPmsg the word is %s\n", token);
1097 #endif
1098 
1099 
1100    for ( i = 0; icmpmap[i].len > 0; i++) {
1101       if (!strncasecmp(icmpmap[i].name, token, icmpmap[i].len)) {
1102          policy->ICMPtype = icmpmap[i].value1;
1103          policy->ICMPcode = icmpmap[i].value2;
1104          policy->flags |= RA_ICMP_SET;
1105          return E_NULL;
1106       }
1107    }
1108 
1109 #ifdef ARGUSDEBUG
1110    ArgusDebug (3, "setICMPmsg no text match, checking for an integer\n");
1111 #endif
1112 
1113 
1114    // The ICMP type can be expressed as an integer as well
1115 
1116    if ( isdigit (token[0])) {
1117       i = atoi(token);
1118       if (( i >= 0) && (i < 256) ) {
1119          policy->ICMPtype = i;
1120          policy->flags |= RA_ICMP_SET;
1121 #ifdef ARGUSDEBUG
1122          ArgusDebug (3, "setICMPmsg found an integer %d\n", i);
1123 #endif
1124 
1125          i = -1 * ( (int) E_ICMPCODE);
1126 #ifdef ARGUSDEBUG
1127          ArgusDebug (3, "setICMPmsg injecting event  %d\n", i);
1128 #endif
1129 
1130          return (events_t) i;
1131       }
1132    }
1133 #ifdef ARGUSDEBUG
1134    ArgusDebug (3, "%s is not a valid value for ICMP\n", token);
1135 #endif
1136 
1137    return E_NULL;
1138 }
1139 
1140 events_t
setICMPcode(struct RaPolicyPolicyStruct * policy,char * token)1141 setICMPcode(struct RaPolicyPolicyStruct *policy, char *token)
1142 {
1143    int i;
1144 #ifdef ARGUSDEBUG
1145    ArgusDebug (3, "setICMPcode the word is %s\n", token);
1146 #endif
1147 
1148 
1149    // this can only be an integer value for the ICMP code
1150 
1151    if ( isdigit (token[0])) {
1152       i = atoi(token);
1153       if (( i >= 0) && (i < 256) ) {
1154          policy->ICMPcode = i;
1155          return E_NULL;
1156       }
1157    }
1158 
1159 #ifdef ARGUSDEBUG
1160    ArgusDebug (3, "%s is not a valid value for ICMP\n", token);
1161 #endif
1162 
1163    return E_NULL;
1164 }
1165 
1166 events_t
setEst(struct RaPolicyPolicyStruct * policy,char * token)1167 setEst (struct RaPolicyPolicyStruct *policy, char *token)
1168 {
1169 #ifdef ARGUSDEBUG
1170    ArgusDebug (3, "setEst the word is %s\n", token);
1171 #endif
1172 
1173    policy->flags |= RA_EST_SET;
1174    return E_NULL;
1175 }
1176 
1177 events_t
setTCPflag(struct RaPolicyPolicyStruct * policy,char * token)1178 setTCPflag (struct RaPolicyPolicyStruct *policy, char *token)
1179 {
1180 #ifdef ARGUSDEBUG
1181    ArgusDebug (3, "setTCPflag the word is %s\n", token);
1182 #endif
1183 
1184    policy->flags |= RA_TCPFLG_SET;
1185    if ( !strcasecmp("fin", token)) {
1186       policy->TCPflags |=  RA_FIN;
1187       policy->flags |= RA_TCPFLG_SET;
1188       return E_NULL;
1189    }
1190    if ( !strcasecmp("syn", token)) {
1191       policy->TCPflags |=  RA_SYN;
1192       policy->flags |= RA_TCPFLG_SET;
1193       return E_NULL;
1194    }
1195    if ( !strcasecmp("rst", token)) {
1196       policy->TCPflags |=  RA_RST;
1197       policy->flags |= RA_TCPFLG_SET;
1198       return E_NULL;
1199    }
1200    if ( !strcasecmp("psh", token)) {
1201       policy->TCPflags |=  RA_PSH  ;
1202        policy->flags |= RA_TCPFLG_SET;
1203        return E_NULL;
1204    }
1205    if ( !strcasecmp("ack", token)) {
1206       policy->TCPflags |=  RA_ACK  ;
1207        policy->flags |= RA_TCPFLG_SET;
1208        return E_NULL;
1209    }
1210    if ( !strcasecmp("urg", token)) {
1211       policy->TCPflags |=  RA_URG  ;
1212        policy->flags |= RA_TCPFLG_SET;
1213        return E_NULL;
1214    }
1215    if ( !strcasecmp("ece", token)) {
1216       policy->TCPflags |=  RA_ECE  ;
1217        policy->flags |= RA_TCPFLG_SET;
1218        return E_NULL;
1219    }
1220    if ( !strcasecmp("cwr", token)) {
1221      policy->TCPflags |=  RA_CWR  ;
1222      policy->flags |= RA_TCPFLG_SET;
1223      return E_NULL;
1224    }
1225    if ( !strcasecmp("ns",  token)) {
1226       policy->TCPflags |=  RA_NS;
1227       policy->flags |= RA_TCPFLG_SET;
1228       return E_NULL;
1229    }
1230 #ifdef ARGUSDEBUG
1231    ArgusDebug (3, "setTCPflag %s is not a valid TCP flag name\n", token);
1232 #endif
1233 
1234    return E_NULL;
1235 }
1236 
1237 events_t
idle(struct RaPolicyPolicyStruct * policy,char * token)1238 idle (struct RaPolicyPolicyStruct *policy, char *token)
1239 {
1240 #ifdef ARGUSDEBUG
1241    ArgusDebug (3, "idle the word is %s\n", token);
1242 #endif
1243 
1244    return E_NULL;
1245 }
1246 
1247 events_t
getRemark(struct RaPolicyPolicyStruct * policy,char * token)1248 getRemark (struct RaPolicyPolicyStruct *policy, char *token)
1249 {
1250 #ifdef ARGUSDEBUG
1251    ArgusDebug (3, "getRemark the word is %s\n", token);
1252 #endif
1253 
1254    policy->flags = RA_COMMENT;
1255    return E_NULL;
1256 }
1257 
1258 events_t
flagTOS(struct RaPolicyPolicyStruct * policy,char * token)1259 flagTOS(struct RaPolicyPolicyStruct *policy, char *token)
1260 {
1261 #ifdef ARGUSDEBUG
1262    ArgusDebug (3, "flagTOS the word is %s\n", token);
1263 #endif
1264 
1265    policy->flags |= RA_TOS_SET;
1266 
1267 // The next token must contain the value for the TOS comparison
1268 // force the token to advance and inject the E_TOSVAL event
1269 
1270    return (events_t) (-1 * (int) E_TOSVAL);
1271 }
1272 
1273 events_t
flagPrecedence(struct RaPolicyPolicyStruct * policy,char * token)1274 flagPrecedence (struct RaPolicyPolicyStruct *policy, char *token)
1275 {
1276 #ifdef ARGUSDEBUG
1277    ArgusDebug (3, "flagPrecedence the word is %s\n", token);
1278 #endif
1279 
1280    policy->flags |= RA_PREC_SET;
1281 // The next token must contain the value for the precedence comparison
1282 // force the token to advance and inject the E_PRECEDENCE event
1283 
1284    return (events_t) (-1 * (int) E_PRECEDENCE);
1285 }
1286 
1287 events_t
setPrecValue(struct RaPolicyPolicyStruct * policy,char * token)1288 setPrecValue(struct RaPolicyPolicyStruct *policy, char *token)
1289 {
1290    int i;
1291 
1292 #ifdef ARGUSDEBUG
1293    ArgusDebug (3, "setPrecValue the word is %s\n", token);
1294 #endif
1295 
1296    for ( i = 0; precmap[i].len > 0; i++) {
1297       if (!strncasecmp(precmap[i].name, token, precmap[i].len)) {
1298          policy->precedence = precmap[i].value;
1299          return E_NULL;
1300       }
1301    }
1302 #ifdef ARGUSDEBUG
1303    ArgusDebug (3, "%s is not a valid value for precedence\n", token);
1304 #endif
1305 
1306    return E_NULL;
1307 }
1308 
1309 events_t
setTOSvalue(struct RaPolicyPolicyStruct * policy,char * token)1310 setTOSvalue(struct RaPolicyPolicyStruct *policy, char *token)
1311 {
1312    int i;
1313 
1314 #ifdef ARGUSDEBUG
1315    ArgusDebug (3, "setTOSvalue the word is %s\n", token);
1316 #endif
1317 
1318    for ( i = 0; tosmap[i].len > 0; i++) {
1319       if (!strncasecmp(tosmap[i].name, token, tosmap[i].len)) {
1320          policy->tos = tosmap[i].value;
1321          return E_NULL;
1322       }
1323    }
1324 #ifdef ARGUSDEBUG
1325    ArgusDebug (3, "%s is not a valid value for tos\n", token);
1326 #endif
1327 
1328    return E_NULL;
1329 }
1330 
1331 events_t
flagDSCP(struct RaPolicyPolicyStruct * policy,char * token)1332 flagDSCP (struct RaPolicyPolicyStruct *policy, char *token)
1333 {
1334 #ifdef ARGUSDEBUG
1335    ArgusDebug (3, "flagDSCP the word is %s\n", token);
1336 #endif
1337 
1338    policy->flags |= RA_DSCP_SET;
1339 
1340 // The next token must contain the value for the DSCP code point
1341 // force the token to advance and inject the E_DSCPVAL event
1342 
1343    return (events_t) (-1 * (int) E_DSCPVAL);
1344 }
1345 
1346 events_t
setDSCPvalue(struct RaPolicyPolicyStruct * policy,char * token)1347 setDSCPvalue(struct RaPolicyPolicyStruct *policy, char *token)
1348 {
1349    int i;
1350 
1351 #ifdef ARGUSDEBUG
1352    ArgusDebug (3, "setDSCPvalue the word is %s\n", token);
1353 #endif
1354 
1355    for ( i = 0; DSCPmap[i].len > 0; i++) {
1356       if (!strncasecmp(DSCPmap[i].name, token, DSCPmap[i].len)) {
1357          policy->dscp = DSCPmap[i].value ;
1358          return E_NULL;
1359       }
1360    }
1361 #ifdef ARGUSDEBUG
1362    ArgusDebug (3, "%s is not a valid DSCP code point name\n", token);
1363 #endif
1364 
1365    return E_NULL;
1366 }
1367 
1368 events_t
setProtoParameter(struct RaPolicyPolicyStruct * policy,char * token)1369 setProtoParameter(struct RaPolicyPolicyStruct *policy, char *token)
1370 {
1371    // There are two instances where naked integers show up at the end of an ACL entry
1372    // both the ICMP and IGMP protocols can have a type parameter expressed as an integer
1373    // at this point the token is an integer and we need to determine what it represents
1374 
1375 #ifdef ARGUSDEBUG
1376    ArgusDebug (3, "setProtoParameters the word is %s the protocol is %d\n", token, policy->proto);
1377 #endif
1378 
1379    switch (policy->proto) {
1380       case 1: return E_ICMPMSG;
1381       case 2: return E_IGMPTYPE;
1382       default:
1383 #ifdef ARGUSDEBUG
1384          ArgusDebug (3, "The raw value %s is not appropriate except for protocols ICMP and IGMP\n", token);
1385 #endif
1386 
1387 
1388       return E_NULL;
1389    }
1390 }
1391 
1392 events_t
tokenize(char * word)1393 tokenize (char * word)
1394 {
1395    int i;
1396 
1397    if ( word[0] == '\n')
1398       return E_EOL;
1399 
1400    if (isdigit(word[0])) {
1401       if (strpbrk ( word, ".") == NULL)
1402          return E_INTEGER;
1403 
1404       return E_QUAD;
1405 
1406    } else {
1407       for (i = 0; strings[i].token != E_NULL; i++) {
1408          if (!strncasecmp(strings[i].symbol, word, strings[i].len) && (strlen(word) == strings[i].len))
1409             return strings[i].token;
1410       }
1411    }
1412 
1413    return E_RAWTEXT;
1414 }
1415 
1416 int
RaParsePolicy(struct ArgusParserStruct * parser,struct RaPolicyPolicyStruct ** pol,char * buf)1417 RaParsePolicy (struct ArgusParserStruct *parser, struct RaPolicyPolicyStruct **pol, char *buf)
1418 {
1419    char *str = strdup(buf);
1420    struct RaPolicyPolicyStruct tpolicy;
1421    char *word = NULL;
1422    states_t theState, opState;
1423    events_t event;
1424 
1425    bzero ((char *)&tpolicy, sizeof(tpolicy));
1426 
1427    char labelStr[1024];
1428 #ifdef ARGUSDEBUG
1429    ArgusDebug (3, "\n Parsing ACL entry: %s\n", buf);
1430 #endif
1431 
1432    theState = S_START;
1433    word = strtok(str, " \t\n\r");
1434    while (word != NULL) {
1435       event = tokenize(word);
1436       while ( event != E_NULL) {
1437          opState = theState;
1438          // E_LOCAL indicates that the next state is the same as the current state
1439          theState = stateTable[opState][event].nextState == S_LOCAL ? opState : stateTable[opState][event].nextState;
1440          if (theState < S_FINAL)
1441 #ifdef ARGUSDEBUG
1442             ArgusDebug (3, "entering state machine state = %d [%s] next = %d [%s] event = %d [%s] word = %s (%d)\n",
1443                opState, stateNames[opState], theState, stateNames[theState], event, eventNames[event], word, strlen(word));
1444 #endif
1445          event = (stateTable[opState][event].fn)(&tpolicy, word);
1446          if (theState == S_NONE) exit (1);
1447          // the processing of the event may have resulted in a new event being injected
1448          // if so, that event either expects the next token or expects the token to remain
1449          // at its current value. We will use the convention that an event number less than
1450          // zero indicates the need to advance the token and pass the absolute value of the
1451          // injected event into the event loop. An positive event number not equal to
1452          // E_NULL will result in the event being injected without advancing the token. And
1453          // an event of E_NULL will tokenize the next token and put the results on the event loop
1454          // First we handle the simple case of no special action, just get the next token and
1455          // inject the next event based on the next token.
1456          if (event == E_NULL) {
1457             if((word = strtok(NULL, " \t\n\r")) != NULL)
1458                event = tokenize(word);
1459          }
1460          // Otherwise we need to deal with an injected event so check if we need to advance the token
1461          // without actually tokenizing the result and make the event a non negative value
1462          if ( (int) event < 0) {
1463 #ifdef ARGUSDEBUG
1464             ArgusDebug (3, "Found an injected state requiring a new token %d\n", event);
1465 #endif
1466 
1467             event  = (events_t) (-1 * (int) event);
1468             word = strtok(NULL, " \t\n\r");
1469          }
1470          // Otherwise leave the token where it is and just inject the event as is
1471 #ifdef ARGUSDEBUG
1472             ArgusDebug (3, "Found an injected state NOT requiring a new token %d\n", event);
1473 #endif
1474 
1475       } // the inner while loop handles functions that inject events aka initiates local actions
1476    }
1477 
1478    if (str) free (str);
1479 
1480    if ((*pol = (struct RaPolicyPolicyStruct *) ArgusCalloc (1, sizeof (**pol))) != NULL) {
1481       bcopy ((char *)&tpolicy, (char *)*pol, sizeof(**pol));
1482       (*pol)->str = strdup(buf);
1483       if (RaGlobalPolicy != NULL){
1484          (*pol)->policyID = strdup(RaGlobalPolicy->policyID);
1485          labelStr[0] = 0;
1486          sprintf (labelStr, "ACL=%s_%s_Line_%4.4d", RaPolicy->flags & RA_PERMIT ? "Permit" : "Deny",
1487               RaPolicy->policyID, (int) RaPolicy->line);
1488 
1489          (*pol)->labelStr = strdup(labelStr);
1490       }
1491    }
1492 
1493    return 1;
1494 }
1495 
1496 int
RaCheckPolicy(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,struct RaPolicyPolicyStruct * policy)1497 RaCheckPolicy (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, struct RaPolicyPolicyStruct *policy)
1498 {
1499    int retn = 0;
1500    char buffer[1024];
1501    struct RaPolicyPolicyStruct *base = policy;
1502 
1503 //   scan through a doubly linked list of RaPolicyPolicyStruct
1504 //   comparing the criteria to the contents of the current flow
1505 //      if this is not a protocol controlled by this policy then send the flow
1506 //      if there is a match on a permit entry, then send the flow
1507 //      if there is a match on a deny entry, then drop the flow
1508 //      if there is no match, advance to the next item in the list
1509 //      if there is no next item, drop the flow because of the implicit deny rule
1510 //      Make the appropriate adjustments based on what you are displaying (deny or permit)
1511 
1512    if (policy) {
1513       while (policy) {
1514          if ((retn = RaMeetsPolicyCriteria (parser, argus, policy))) {
1515             if (retn == 1) { return 1;}  //do the permit stuff
1516             if (retn == 2) { return 0;}  //do the deny stuff
1517          }
1518          policy = policy->nxt;
1519       }
1520    }
1521 
1522 // There is an implicit deny for all unmatched flows, deal with it as if it were an explicit deny
1523 
1524    if (parser->RaPolicyStatus & ARGUS_POLICY_LABEL_IMPLICIT) {
1525       policy = base;
1526       sprintf (buffer, "ACL=ImplicitDeny_%s", policy->policyID);
1527       ArgusAddToRecordLabel (parser, argus, buffer);
1528    }
1529 
1530    return((parser->RaPolicyStatus &  ARGUS_POLICY_SHOW_DENY) ? 1 : 0);
1531 }
1532 
1533 
1534 int
RaMeetsPolicyCriteria(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus,struct RaPolicyPolicyStruct * policy)1535 RaMeetsPolicyCriteria (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, struct RaPolicyPolicyStruct *policy)
1536 {
1537 
1538 //   There are three possible outcomes:
1539 //      There is a match for a permit ACL entry - send the packet = 1
1540 //      There is a match for a deny ACL entry - drop the packet = 2
1541 //      There is no match for a permit or a deny ACL entry - check the next entry = 0
1542 //
1543 
1544    struct ArgusFlow *flow = (void *)argus->dsrs[ARGUS_FLOW_INDEX];
1545 
1546    if (flow != NULL) {
1547       arg_uint32 saddr = 0, daddr = 0;
1548       arg_uint16 sport = 0, dport = 0;
1549       u_char proto = flow->ip_flow.ip_p;
1550       saddr = flow->ip_flow.ip_src;
1551       daddr = flow->ip_flow.ip_dst;
1552       sport = flow->ip_flow.sport;
1553       dport = flow->ip_flow.dport;
1554 
1555 #ifdef ARGUSDEBUG
1556       ArgusDebug (3, "RaMeetsPolicyCriteria for %s line %d: %s\n",
1557          policy->policyID, policy->line, policy->str);
1558 #endif
1559 
1560       if (policy->flags & (RA_COMMENT))
1561          return 0;
1562 
1563       if (policy->flags & (RA_PROTO_SET)) {
1564          if (policy->proto)
1565             if (proto != (u_char) policy->proto)
1566                return 0;
1567       }
1568 
1569       if (policy->flags & (RA_SRC_SET)) {
1570          if ((saddr & ~policy->src.mask) != policy->src.addr)
1571             return 0;
1572       }
1573 
1574       if (policy->flags & (RA_DST_SET)) {
1575          if ((daddr & ~policy->dst.mask) != policy->dst.addr)
1576             return 0;
1577       }
1578 
1579       if (policy->flags & (RA_SRCPORT_SET)) {
1580          switch (policy->src_action) {
1581             case  RA_EQ:
1582                if (sport != policy->src_port_low)
1583                   return 0;
1584                break;
1585 
1586             case  RA_LT:
1587                if (!(sport < policy->src_port_low))
1588                   return 0;
1589                break;
1590 
1591             case  RA_GT:
1592                if (!(sport > policy->src_port_low))
1593                   return 0;
1594                break;
1595 
1596             case RA_NEQ:
1597                if (sport == policy->src_port_low)
1598                   return 0;
1599                break;
1600 
1601             case RA_RANGE:
1602                if (((sport < policy->src_port_low) || (sport > policy->src_port_hi)))
1603                   return 0;
1604                break;
1605          }
1606       } // end of  if testing for source port
1607 
1608       if (policy->flags & (RA_DSTPORT_SET)) {
1609          switch (policy->dst_action) {
1610             case  RA_EQ:
1611                if (dport != policy->dst_port_low)
1612                   return 0;
1613                break;
1614             case  RA_LT:
1615                if (!(dport < policy->dst_port_low))
1616                   return 0;
1617                break;
1618             case  RA_GT:
1619                if (!(dport > policy->dst_port_low))
1620                   return 0;
1621                break;
1622             case RA_NEQ:
1623                if (dport == policy->dst_port_low)
1624                   return 0;
1625                break;
1626 
1627             case RA_RANGE:
1628                if (((dport < policy->dst_port_low) || (dport > policy->dst_port_hi)))
1629                   return 0;
1630                break;
1631          }
1632       } // end of if testing for destination port
1633 
1634       if (policy->flags & (RA_EST_SET)) {
1635          int status = 0;
1636          struct ArgusNetworkStruct *net = (void *)argus->dsrs[ARGUS_NETWORK_INDEX];
1637 
1638          if (net != NULL) {
1639             switch (net->hdr.subtype) {
1640                case ARGUS_TCP_STATUS: {
1641                   struct ArgusTCPStatus *tcp = (struct ArgusTCPStatus *)&net->net_union.tcpstatus;
1642                   status = tcp->status;
1643                   break;
1644                }
1645                case ARGUS_TCP_PERF: {
1646                   struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
1647                   status = tcp->status;
1648                   break;
1649                }
1650             }
1651 
1652             if (!(status & ARGUS_SAW_SYN_SENT))
1653                return (0);
1654          }
1655       }
1656 
1657       if (policy->flags & (RA_TCPFLG_SET)) {
1658          struct ArgusNetworkStruct *net;
1659          unsigned char sflags;
1660 
1661 //  Checking the state of the TCP header flags
1662 //
1663 //   Since we are looking at flow records rather than individual packets we need to make some accommodations
1664 //   The Cicso ACL checks for the specific flag's status regardless of the state of any other flag so there is
1665 //   no need to check the state of any of the other flags.There is a credible arguement that the combination of
1666 //   the SYN and the ACK flags is a special case that requires them both to be set in the same packet
1667 //   Since we have aggregated flow data we need to check that combination against the special status indicator
1668 //   rather than the summary of flags seen in the flow
1669 //
1670 //   We check for ESTABLISHED at this time as well since that is simply a description of a set of
1671 //   TCP header flags that meet a specific requirement
1672 //
1673          if ((net = (struct ArgusNetworkStruct *)argus->dsrs[ARGUS_NETWORK_INDEX]) != NULL) {
1674             switch (net->hdr.subtype) {
1675                case ARGUS_TCP_INIT:
1676                case ARGUS_TCP_STATUS:
1677                case ARGUS_TCP_PERF: {
1678                   struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)&net->net_union.tcp;
1679                   sflags = tcp->src.flags;
1680                   break;
1681                }
1682             }
1683 
1684 #ifdef ARGUSDEBUG
1685             ArgusDebug (3, "Policy wants TCPflags to be %x they are %x\n", policy->TCPflags, sflags);
1686 #endif
1687 
1688 //   for the Isolationists looking for only the specified flags,  uncomment the next line
1689 //          if ((policy->TCPflags ^ sflags) != 0 ) return 0;
1690             if ((policy->TCPflags & sflags) != (policy->TCPflags))
1691                return 0;
1692          }
1693       }
1694 
1695       if (policy->flags & (RA_ICMP_SET)) {
1696          unsigned char type, code;
1697          type = flow->icmp_flow.type;
1698          code = flow->icmp_flow.code;
1699 
1700          if (policy->ICMPtype !=  type)
1701             return 0;
1702 
1703 // Cisco has created meta values that translate to type x  with any code value, we
1704 // indicate that as a code value of ICMPCodeAny which indicates that a match of the type is
1705 // the only match requirement, othewise we compare the code value
1706 
1707          if ((code < ICMPCodeAny) && (policy->ICMPcode != code))
1708             return 0;
1709       }
1710 //
1711 //   The tos, precedence,  and DSCP code points are closely coupled so we check them against the same
1712 //   Argus value depending on how the ACL specifies the match
1713 //
1714     {
1715          struct ArgusIPAttrStruct *ip1 = (void *)argus->dsrs[ARGUS_IPATTR_INDEX];
1716 
1717          if (ip1) {
1718             if ((policy->flags & (RA_TOS_SET)) && (policy->tos != ((ip1->src.tos >> 1) & 0x0f)))
1719                 return 0;
1720 
1721             if ((policy->flags & (RA_DSCP_SET)) && (policy->dscp != (ip1->src.tos >> 2)))
1722                return 0;
1723 
1724 
1725                 if ((policy->flags & (RA_PREC_SET)) && (policy->precedence != (ip1->src.tos >> 5)))
1726                           return(0);
1727        }
1728    }
1729 
1730 
1731       if (policy->flags & (RA_IGMP_SET)) {
1732          unsigned char type;
1733          type = flow->igmp_flow.type;
1734 
1735          if (policy->IGMPtype != type)
1736             return 0;
1737       }
1738 
1739       if (policy->flags & (RA_PREC_SET)) {
1740          // TBD Precedence value comparison
1741       }
1742 
1743       if (policy->flags & (RA_DSCP_SET)) {
1744          // The DSCP Code Point occupies the 6 MSB of the byte. The value in policy->dscp is already
1745          // left shifted to accommodate this.
1746          // TBD - code being tested now
1747       }
1748 
1749       // If we make it to here we have a good match. Update the counts for this entry
1750 
1751       {
1752          struct ArgusMetricStruct *metric = (void *)argus->dsrs[ARGUS_METRIC_INDEX];
1753          policy->hitCount++;
1754 
1755          if (metric != NULL) {
1756             policy->hitPkts  += metric->src.pkts;
1757             policy->hitBytes += metric->src.bytes;
1758          }
1759 
1760          if ((policy->flags & RA_PERMIT) || (policy->flags & RA_DENY)) {
1761             if ((((parser->RaPolicyStatus & ARGUS_POLICY_LABEL_LOG)) && (policy->flags & RA_LOG_SET)) ||
1762                          (parser->RaPolicyStatus & ARGUS_POLICY_LABEL_ALL))
1763             ArgusAddToRecordLabel ( parser, argus, policy->labelStr);
1764          }
1765 
1766          if (policy->flags & (RA_PERMIT))
1767             return((parser->RaPolicyStatus &  ARGUS_POLICY_SHOW_DENY) ? 2 : 1);
1768 
1769          if (policy->flags & (RA_DENY))
1770             return((parser->RaPolicyStatus &  ARGUS_POLICY_SHOW_DENY) ? 1 : 2);
1771       }
1772    }
1773 
1774    return 0;
1775 }
1776