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