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
22 /*
23 * $Id: //depot/argus/clients/clients/radium.c#16 $
24 * $DateTime: 2016/06/01 15:17:28 $
25 * $Change: 3148 $
26 */
27
28 /*
29 * radium.c - this is the argus record distribtion node.
30 * Acting just like a ra* program, supporting all the options
31 * and functions of ra(), and providing access to data, like
32 * argus, supporting remote filtering, and MAR record generation.
33 * This is an important workhorse for the argus architecture.
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "argus_config.h"
38 #endif
39
40 #include <unistd.h>
41 #include <stdlib.h>
42 #include <grp.h>
43 #include <pwd.h>
44
45 #if defined(HAVE_SYS_VFS_H)
46 #include <sys/vfs.h>
47 #else
48 #include <sys/param.h>
49 #include <sys/mount.h>
50 #endif
51
52 #include <argus_compat.h>
53 #include <argus_output.h>
54
55 #include <rabins.h>
56
57 int RaRealTime = 0;
58 float RaUpdateRate = 1.0;
59
60 struct timeval ArgusLastRealTime = {0, 0};
61 struct timeval ArgusLastTime = {0, 0};
62 struct timeval ArgusThisTime = {0, 0};
63
64 struct timeval dLastTime = {0, 0};
65 struct timeval dRealTime = {0, 0};
66 struct timeval dThisTime = {0, 0};
67 struct timeval dTime = {0, 0};
68
69 long long thisUsec = 0;
70
71 void RadiumSendFile (struct ArgusOutputStruct *, struct ArgusClientData *, char *, int);
72
73 extern char *chroot_dir;
74 extern uid_t new_uid;
75 extern gid_t new_gid;
76
77 void ArgusSetChroot(char *);
78
79 void
ArgusClientInit(struct ArgusParserStruct * parser)80 ArgusClientInit (struct ArgusParserStruct *parser)
81 {
82 struct ArgusModeStruct *mode;
83 FILE *tmpfile = NULL;
84 struct timeval *tvp;
85 int pid, dflag;
86 #if defined(ARGUS_THREADS)
87 sigset_t blocked_signals;
88 int thread = 0;
89
90 thread++;
91 #endif /* ARGUS_THREADS */
92
93 /*
94 if (thread == 0)
95 ArgusLog (LOG_ERR, "not compiled with pthread support. exiting");
96 */
97 parser->RaWriteOut = 1;
98 parser->ArgusReverse = 1;
99
100 if (!(parser->RaInitialized)) {
101 if ((mode = parser->ArgusModeList) != NULL) {
102 while (mode) {
103 if (!(strncasecmp (mode->mode, "rtime", 5)) ||
104 (!(strncasecmp (mode->mode, "realtime", 8)))) {
105 char *ptr = NULL;
106 RaRealTime++;
107 if ((ptr = strchr(mode->mode, ':')) != NULL) {
108 double value = 0.0;
109 char *endptr = NULL;
110 ptr++;
111 value = strtod(ptr, &endptr);
112 if (ptr != endptr) {
113 RaUpdateRate = value;
114 }
115 }
116 } else
117 if (isdigit(*optarg))
118 setArgusMarReportInterval (ArgusParser, optarg);
119
120 mode = mode->nxt;
121 }
122 }
123
124 dflag = parser->dflag;
125 parser->dflag = 0;
126
127 if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL, ARGUS_RECORD_AGGREGATOR)) == NULL)
128 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");
129
130 if (parser->ArgusFlowModelFile != NULL) {
131 RadiumParseResourceFile (parser, parser->ArgusFlowModelFile);
132 } else {
133 if (!(parser->Xflag)) {
134 RadiumParseResourceFile (parser, "/usr/local/etc/radium.conf");
135 }
136 }
137
138 parser->dflag = (parser->dflag) ? (dflag ? 0 : 1) : dflag;
139
140 if (parser->dflag) {
141 pid_t parent = getppid();
142
143 if (parent != 1) {
144 if ((pid = fork ()) < 0) {
145 ArgusLog (LOG_ERR, "Can't fork daemon %s", strerror(errno));
146 } else {
147 if (pid) {
148 struct timespec ts = {0, 500000000};
149 int status;
150
151 nanosleep(&ts, NULL);
152 waitpid(pid, &status, WNOHANG);
153 if (kill(pid, 0) < 0) {
154 exit (1);
155 } else
156 exit (0);
157
158 } else {
159 if (chdir ("/") < 0)
160 ArgusLog (LOG_ERR, "Can't chdir to / %s", strerror(errno));
161
162 if ((parser->ArgusSessionId = setsid()) < 0)
163 ArgusLog (LOG_ERR, "setsid error %s", strerror(errno));
164
165 umask(0);
166
167 ArgusLog(LOG_WARNING, "started");
168
169 if ((tmpfile = freopen ("/dev/null", "r", stdin)) == NULL)
170 ArgusLog (LOG_ERR, "Cannot map stdout to /dev/null");
171
172 if ((tmpfile = freopen ("/dev/null", "a+", stdout)) == NULL)
173 ArgusLog (LOG_ERR, "Cannot map stdout to /dev/null");
174
175 if ((tmpfile = freopen ("/dev/null", "a+", stderr)) == NULL)
176 ArgusLog (LOG_ERR, "Cannot map stderr to /dev/null");
177 }
178 }
179 }
180 }
181
182 if (parser->ArgusPortNum != 0) {
183 if (ArgusEstablishListen (parser, parser->ArgusPortNum, parser->ArgusBindAddr) < 0)
184 ArgusLog (LOG_ERR, "setArgusPortNum: ArgusEstablishListen returned %s", strerror(errno));
185 }
186
187 if (chroot_dir != NULL)
188 ArgusSetChroot(chroot_dir);
189
190 if (new_gid > 0) {
191 if (setgid(new_gid) < 0)
192 ArgusLog (LOG_ERR, "ArgusInitOutput: setgid error %s", strerror(errno));
193 }
194
195 if (new_uid > 0) {
196 if (setuid(new_uid) < 0)
197 ArgusLog (LOG_ERR, "ArgusInitOutput: setuid error %s", strerror(errno));
198 }
199 /*
200 This is the basic new argus() strategy for processing output
201 records. The thread will do two basic things:
202 1) it will grab stuff off the queue, and then do the basic
203 processing that this radium will do, such as time
204 adjustment, aggregation, correction, and anonymization, etc...
205
206 2) it will manage the listen, to deal without remote client
207 requests. radium() can write its records to a file, and
208 any number of remote clients, so ......
209
210 The ArgusClientTimeout() routine will drive all the maintenance
211 and so it should be run, probably 4x a second, just for good
212 measure.
213 */
214
215 parser->ArgusReliableConnection++;
216 parser->RaInitialized++;
217
218 parser->ArgusOutput = ArgusNewOutput (parser);
219 ArgusInitOutput (parser->ArgusOutput);
220
221 tvp = getArgusMarReportInterval(ArgusParser);
222 if ((tvp->tv_sec == 0) && (tvp->tv_usec == 0)) {
223 setArgusMarReportInterval (ArgusParser, "60s");
224 }
225
226 #if defined(ARGUS_THREADS)
227 sigemptyset(&blocked_signals);
228 pthread_sigmask(SIG_BLOCK, &blocked_signals, NULL);
229 #endif
230 (void) signal (SIGHUP, (void (*)(int)) ArgusShutDown);
231 (void) signal (SIGTERM, (void (*)(int)) ArgusShutDown);
232 (void) signal (SIGQUIT, (void (*)(int)) ArgusShutDown);
233 (void) signal (SIGINT, (void (*)(int)) ArgusShutDown);
234
235 (void) signal (SIGPIPE, SIG_IGN);
236 (void) signal (SIGTSTP, SIG_IGN);
237 (void) signal (SIGTTOU, SIG_IGN);
238 (void) signal (SIGTTIN, SIG_IGN);
239 }
240 }
241
RaArgusInputComplete(struct ArgusInput * input)242 void RaArgusInputComplete (struct ArgusInput *input)
243 {
244
245 };
246
247 void
RaParseComplete(int sig)248 RaParseComplete (int sig)
249 {
250 struct ArgusRecordStruct *rec = NULL;
251
252 #ifdef ARGUSDEBUG
253 ArgusDebug (2, "RaParseComplete(%d) Starting\n", sig);
254 #endif
255
256 if (!ArgusParser->RaParseCompleting) {
257 ArgusParser->RaParseCompleting++;
258 ArgusParser->RaParseDone++;
259
260 if (ArgusParser->ArgusActiveHosts != NULL) {
261 struct ArgusQueueStruct *queue = ArgusParser->ArgusActiveHosts;
262 struct ArgusInput *input = NULL;
263
264 while (queue->count > 0) {
265 if ((input = (struct ArgusInput *) ArgusPopQueue(queue, ARGUS_LOCK)) != NULL) {
266 ArgusCloseInput(ArgusParser, input);
267 if (input->hostname != NULL)
268 free (input->hostname);
269 if (input->filename != NULL)
270 free (input->filename);
271 #if defined(HAVE_GETADDRINFO)
272 if (input->host != NULL)
273 freeaddrinfo (input->host);
274 #endif
275 ArgusFree(input);
276 }
277 }
278 ArgusDeleteQueue(queue);
279 ArgusParser->ArgusActiveHosts = NULL;
280 }
281
282 if (ArgusParser->ArgusOutput) {
283 if ((rec = ArgusGenerateStatusMarRecord(ArgusParser->ArgusOutput, ARGUS_SHUTDOWN)) != NULL)
284 ArgusPushBackList(ArgusParser->ArgusOutput->ArgusOutputList, (struct ArgusListRecord *)rec, ARGUS_LOCK);
285
286 ArgusCloseOutput(ArgusParser->ArgusOutput);
287 ArgusDeleteOutput(ArgusParser, ArgusParser->ArgusOutput);
288 ArgusParser->ArgusOutput = NULL;
289 }
290
291 if (sig >= 0) {
292 #ifdef ARGUSDEBUG
293 ArgusDebug (2, "RaParseComplete(caught signal $d)\n", sig);
294 #endif
295
296 switch (sig) {
297 case SIGHUP:
298 case SIGINT:
299 case SIGTERM:
300 case SIGQUIT: {
301 struct ArgusWfileStruct *wfile = NULL;
302
303 ArgusShutDown(sig);
304
305 if (ArgusParser->ArgusWfileList != NULL) {
306 struct ArgusListObjectStruct *lobj = NULL;
307 int i, count = ArgusParser->ArgusWfileList->count;
308
309 if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
310 for (i = 0; i < count; i++) {
311 if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
312 if (wfile->fd != NULL) {
313 #ifdef ARGUSDEBUG
314 ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
315 #endif
316 fflush (wfile->fd);
317 fclose (wfile->fd);
318 wfile->fd = NULL;
319 }
320 }
321 lobj = lobj->nxt;
322 }
323 }
324 }
325 #if defined(ARGUS_THREADS)
326 pthread_exit(0);
327 #else
328 exit(0);
329 #endif /* ARGUS_THREADS */
330 break;
331 }
332 }
333 }
334 }
335
336 #ifdef ARGUSDEBUG
337 ArgusDebug (2, "RaParseComplete(%d) returning\n", sig);
338 #endif
339 }
340
341
342 void
ArgusClientTimeout()343 ArgusClientTimeout ()
344 {
345 gettimeofday(&ArgusParser->ArgusRealTime, 0);
346
347 if (RaRealTime) { /* establish value for time comparison */
348 if (ArgusLastTime.tv_sec != 0) {
349 if (ArgusLastRealTime.tv_sec > 0) {
350 RaDiffTime(&ArgusParser->ArgusRealTime, &ArgusLastRealTime, &dRealTime);
351 thisUsec = ((dRealTime.tv_sec * 1000000) + dRealTime.tv_usec) * RaUpdateRate;
352 dRealTime.tv_sec = thisUsec / 1000000;
353 dRealTime.tv_usec = thisUsec % 1000000;
354
355 ArgusLastTime.tv_sec += dRealTime.tv_sec;
356 ArgusLastTime.tv_usec += dRealTime.tv_usec;
357
358 if (ArgusLastTime.tv_usec > 1000000) {
359 ArgusLastTime.tv_sec++;
360 ArgusLastTime.tv_usec -= 1000000;
361 }
362 }
363
364 ArgusLastRealTime = ArgusParser->ArgusRealTime;
365 }
366 }
367
368 #ifdef ARGUSDEBUG
369 ArgusDebug (6, "ArgusClientTimeout()\n");
370 #endif
371 }
372
373 void
parse_arg(int argc,char ** argv)374 parse_arg (int argc, char**argv)
375 {}
376
377 void
usage()378 usage ()
379 {
380 extern char version[];
381
382 fprintf (stdout, "Radium Version %s\n", version);
383 fprintf (stdout, "usage: %s [radiumoptions] [raoptions]\n", ArgusParser->ArgusProgramName);
384
385 fprintf (stdout, "options: -c <dir> daemon chroot directory.\n");
386 fprintf (stdout, " -d run as a daemon.\n");
387 fprintf (stdout, " -f conf.file read %s configure file.\n", ArgusParser->ArgusProgramName);
388 fprintf (stdout, " -u <userid> specify user id for daemon.\n");
389 fprintf (stdout, " -g <groupid> specify group id for daemon.\n");
390 #if defined (ARGUSDEBUG)
391 fprintf (stdout, " -D <level> specify debug level\n");
392 #endif
393 #ifdef ARGUS_SASL
394 fprintf (stdout, " -U <user/auth> specify <user/auth> authentication information.\n");
395 #endif
396 fflush (stdout);
397 exit(1);
398 }
399
400
401 #define RADIUM_MAX_ANALYTICS 128
402 struct ArgusRecordStruct *(*RadiumAnalyticAlgorithmTable[RADIUM_MAX_ANALYTICS])(struct ArgusParserStruct *, struct ArgusRecordStruct *) = {
403 NULL, NULL, NULL
404 };
405
406
407
408 void
RaProcessRecord(struct ArgusParserStruct * parser,struct ArgusRecordStruct * argus)409 RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
410 {
411 struct ArgusRecordStruct *ns;
412
413 switch (argus->hdr.type & 0xF0) {
414 case ARGUS_MAR: {
415 struct ArgusRecord *rec = (struct ArgusRecord *)argus->dsrs[0];
416 if (rec && parser->ArgusAdjustTime) {
417 struct timeval drift;
418
419 drift.tv_sec = parser->ArgusRealTime.tv_sec - ntohl(rec->argus_mar.now.tv_sec);
420 drift.tv_usec = parser->ArgusRealTime.tv_usec - ntohl(rec->argus_mar.now.tv_usec);
421 argus->input->ArgusTimeDrift = drift.tv_sec * 1000000;
422 argus->input->ArgusTimeDrift += drift.tv_usec;
423 rec->argus_mar.drift = argus->input->ArgusTimeDrift;
424 #ifdef ARGUSDEBUG
425 #if defined(__APPLE_CC__) || defined(__APPLE__)
426 ArgusDebug (3, "RaProcessRecord: ArgusInput 0x%x drift %lld\n",
427 argus->input, argus->input->ArgusTimeDrift);
428 #else
429 ArgusDebug (3, "RaProcessRecord: ArgusInput 0x%x drift %Ld\n",
430 argus->input, argus->input->ArgusTimeDrift);
431 #endif
432 #endif
433 }
434 break;
435 }
436
437 case ARGUS_EVENT:
438 case ARGUS_NETFLOW:
439 case ARGUS_FAR: {
440 struct ArgusTimeObject *time = (void *)argus->dsrs[ARGUS_TIME_INDEX];
441
442 if (time != NULL) {
443 if (parser->ArgusAdjustTime) {
444 long long ArgusDriftLevel = parser->ArgusAdjustTime * 1000000;
445
446 if (time && ((argus->input->ArgusTimeDrift > ArgusDriftLevel) ||
447 (argus->input->ArgusTimeDrift < -ArgusDriftLevel))) {
448 int secs = argus->input->ArgusTimeDrift / 1000000;
449 int usecs = argus->input->ArgusTimeDrift % 1000000;
450
451 struct timeval startbuf, *start = &startbuf;
452 struct timeval endbuf, *end = &endbuf;
453
454 start->tv_sec = time->src.start.tv_sec;
455 start->tv_usec = time->src.start.tv_usec;
456
457 end->tv_sec = time->src.end.tv_sec;
458 end->tv_usec = time->src.end.tv_usec;
459
460 #ifdef ARGUSDEBUG
461 ArgusDebug (4, "RaProcessRecord() ArgusInput 0x%x adjusting timestamps by %d secs and %d usecs\n", argus->input, secs, usecs);
462 #endif
463 time->hdr.argus_dsrvl8.qual |= ARGUS_TIMEADJUST;
464 start->tv_sec += secs;
465 start->tv_usec += usecs;
466 if (start->tv_usec < 0) {
467 start->tv_sec--; start->tv_usec += 1000000;
468 }
469 if (start->tv_usec > 1000000) {
470 start->tv_sec++; start->tv_usec -= 1000000;
471 }
472
473 end->tv_sec += secs;
474 end->tv_usec += usecs;
475 if (end->tv_usec < 0) {
476 end->tv_sec--; end->tv_usec += 1000000;
477 }
478 if (end->tv_usec > 1000000) {
479 end->tv_sec++; end->tv_usec -= 1000000;
480 }
481 }
482 }
483
484 ArgusThisTime.tv_sec = time->src.start.tv_sec;
485 ArgusThisTime.tv_usec = time->src.start.tv_usec;
486
487 if (RaRealTime) {
488 if (ArgusLastTime.tv_sec == 0)
489 ArgusLastTime = ArgusThisTime;
490
491 if (!((ArgusLastTime.tv_sec > ArgusThisTime.tv_sec) ||
492 ((ArgusLastTime.tv_sec == ArgusThisTime.tv_sec) &&
493 (ArgusLastTime.tv_usec > ArgusThisTime.tv_usec)))) {
494
495 while ((ArgusThisTime.tv_sec > ArgusLastTime.tv_sec) ||
496 ((ArgusThisTime.tv_sec == ArgusLastTime.tv_sec) &&
497 (ArgusThisTime.tv_usec > ArgusLastTime.tv_usec))) {
498 struct timespec ts = {0, 0};
499 int thisRate;
500
501 RaDiffTime(&ArgusThisTime, &ArgusLastTime, &dThisTime);
502 thisRate = ((dThisTime.tv_sec * 1000000) + dThisTime.tv_usec)/RaUpdateRate;
503 thisRate = (thisRate > 100000) ? 100000 : thisRate;
504
505 ts.tv_nsec = thisRate * 1000;
506 nanosleep (&ts, NULL);
507 ArgusClientTimeout ();
508
509 gettimeofday(&parser->ArgusRealTime, 0);
510
511 if (ArgusLastRealTime.tv_sec > 0) {
512 RaDiffTime(&parser->ArgusRealTime, &ArgusLastRealTime, &dRealTime);
513 thisUsec = ((dRealTime.tv_sec * 1000000) + dRealTime.tv_usec) * RaUpdateRate;
514 dRealTime.tv_sec = thisUsec / 1000000;
515 dRealTime.tv_usec = thisUsec % 1000000;
516
517 ArgusLastTime.tv_sec += dRealTime.tv_sec;
518 ArgusLastTime.tv_usec += dRealTime.tv_usec;
519 if (ArgusLastTime.tv_usec > 1000000) {
520 ArgusLastTime.tv_sec++;
521 ArgusLastTime.tv_usec -= 1000000;
522 }
523 }
524
525 ArgusLastRealTime = parser->ArgusRealTime;
526 }
527 }
528
529 } else
530 ArgusLastTime = parser->ArgusRealTime;
531
532 }
533 break;
534 }
535 }
536
537 if ((ns = ArgusCopyRecordStruct(argus)) != NULL) {
538 int i;
539 for (i = 0; i < RADIUM_MAX_ANALYTICS; i++) {
540 if (RadiumAnalyticAlgorithmTable[i] != NULL) {
541 if ((ns = RadiumAnalyticAlgorithmTable[i](parser, ns)) == NULL)
542 break;
543
544 } else
545 break;
546 }
547
548 if (ns != NULL)
549 ArgusPushBackList(parser->ArgusOutput->ArgusOutputList, (struct ArgusListRecord *) ns, ARGUS_LOCK);
550 }
551
552 #if defined(ARGUS_THREADS)
553 pthread_cond_signal(&parser->ArgusOutput->ArgusOutputList->cond);
554
555 if (parser->ArgusOutput->ArgusOutputList->count > 10000) {
556 struct timespec tsbuf = {0, 10000000}, *ts = &tsbuf;
557 nanosleep (ts, NULL);
558 }
559
560 #else
561 ArgusOutputProcess(parser->ArgusOutput);
562 #endif
563
564 #ifdef ARGUSDEBUG
565 ArgusDebug (4, "RaProcessRecord (0x%x, 0x%x) returning", parser, argus);
566 #endif
567 }
568
RaSendArgusRecord(struct ArgusRecordStruct * argus)569 int RaSendArgusRecord(struct ArgusRecordStruct *argus) {return 0;}
570
571 void ArgusWindowClose(void);
572
ArgusWindowClose(void)573 void ArgusWindowClose(void) {
574 #ifdef ARGUSDEBUG
575 ArgusDebug (6, "ArgusWindowClose () returning\n");
576 #endif
577 }
578
579 #define RADIUM_RCITEMS 22
580
581 #define RADIUM_DAEMON 0
582 #define RADIUM_MONITOR_ID 1
583 #define RADIUM_ARGUS_SERVER 2
584 #define RADIUM_CISCONETFLOW_PORT 3
585 #define RADIUM_ACCESS_PORT 4
586 #define RADIUM_INPUT_FILE 5
587 #define RADIUM_USER_AUTH 6
588 #define RADIUM_AUTH_PASS 7
589 #define RADIUM_OUTPUT_FILE 8
590 #define RADIUM_OUTPUT_STREAM 9
591 #define RADIUM_MAR_STATUS_INTERVAL 10
592 #define RADIUM_DEBUG_LEVEL 11
593 #define RADIUM_FILTER_OPTIMIZER 12
594 #define RADIUM_FILTER_TAG 13
595 #define RADIUM_BIND_IP 14
596 #define RADIUM_MIN_SSF 15
597 #define RADIUM_MAX_SSF 16
598 #define RADIUM_ADJUST_TIME 17
599 #define RADIUM_CHROOT_DIR 18
600 #define RADIUM_SETUSER_ID 19
601 #define RADIUM_SETGROUP_ID 20
602 #define RADIUM_CLASSIFIER_FILE 21
603
604 char *RadiumResourceFileStr [] = {
605 "RADIUM_DAEMON=",
606 "RADIUM_MONITOR_ID=",
607 "RADIUM_ARGUS_SERVER=",
608 "RADIUM_CISCONETFLOW_PORT=",
609 "RADIUM_ACCESS_PORT=",
610 "RADIUM_INPUT_FILE=",
611 "RADIUM_USER_AUTH=",
612 "RADIUM_AUTH_PASS=",
613 "RADIUM_OUTPUT_FILE=",
614 "RADIUM_OUTPUT_STREAM=",
615 "RADIUM_MAR_STATUS_INTERVAL=",
616 "RADIUM_DEBUG_LEVEL=",
617 "RADIUM_FILTER_OPTIMIZER=",
618 "RADIUM_FILTER=",
619 "RADIUM_BIND_IP=",
620 "RADIUM_MIN_SSF=",
621 "RADIUM_MAX_SSF=",
622 "RADIUM_ADJUST_TIME=",
623 "RADIUM_CHROOT_DIR=",
624 "RADIUM_SETUSER_ID=",
625 "RADIUM_SETGROUP_ID=",
626 "RADIUM_CLASSIFIER_FILE=",
627 };
628
629 int
RadiumParseResourceFile(struct ArgusParserStruct * parser,char * file)630 RadiumParseResourceFile (struct ArgusParserStruct *parser, char *file)
631 {
632 int retn = 0;
633 int i, len, done = 0, linenum = 0, Soption = 0, roption = 0, quoted = 0;
634 char strbuf[MAXSTRLEN], *str = strbuf, *optarg;
635 char result[MAXSTRLEN], *ptr;
636 FILE *fd;
637
638 if (file) {
639 if ((fd = fopen (file, "r")) != NULL) {
640 while ((fgets(str, MAXSTRLEN, fd)) != NULL) {
641 done = 0; quoted = 0; linenum++;
642 while (*str && isspace((int)*str))
643 str++;
644
645 if (*str && (*str != '#') && (*str != '\n') && (*str != '!')) {
646 for (i = 0; i < RADIUM_RCITEMS && !done; i++) {
647 len = strlen(RadiumResourceFileStr[i]);
648 if (!(strncmp (str, RadiumResourceFileStr[i], len))) {
649 optarg = &str[len];
650 if (*optarg == '\"') { optarg++; quoted = 1; }
651 if (optarg[strlen(optarg) - 1] == '\n')
652 optarg[strlen(optarg) - 1] = '\0';
653 if (optarg[strlen(optarg) - 1] == '\"')
654 optarg[strlen(optarg) - 1] = '\0';
655
656 switch (i) {
657 case RADIUM_DAEMON: {
658 if (!(strncasecmp(optarg, "yes", 3)))
659 parser->dflag = 1;
660 else
661 if (!(strncasecmp(optarg, "no", 2)))
662 parser->dflag = 0;
663
664 break;
665 }
666
667 case RADIUM_MONITOR_ID:
668 if (optarg && quoted) { // Argus ID is a string. Limit to date is 4 characters.
669 int slen = strlen(optarg);
670 if (slen > 4) optarg[4] = '\0';
671 setArgusID (parser, optarg, ARGUS_IDIS_STRING);
672
673 } else {
674 if (optarg && (*optarg == '`')) {
675 if (optarg[strlen(optarg) - 1] == '`') {
676 FILE *tfd;
677
678 optarg++;
679 optarg[strlen(optarg) - 1] = '\0';
680 if (!(strcmp (optarg, "hostname"))) {
681 if ((tfd = popen("hostname", "r")) != NULL) {
682 if ((ptr = fgets(result, MAXSTRLEN, tfd)) != NULL) {
683 optarg = ptr;
684 optarg[strlen(optarg) - 1] = '\0';
685
686 if ((ptr = strstr(optarg, ".local")) != NULL) {
687 if (strlen(ptr) == strlen(".local"))
688 *ptr = '\0';
689 }
690
691 } else
692 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) `hostname` failed %s.\n", file, strerror(errno));
693
694 pclose(tfd);
695 } else
696 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) System error: popen() %s\n", file, strerror(errno));
697 } else
698 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) unsupported command `%s` at line %d.\n", file, optarg, linenum);
699 } else
700 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) syntax error line %d\n", file, linenum);
701 }
702 if (optarg && isalnum((int)*optarg)) {
703 #if defined(HAVE_GETADDRINFO)
704 struct addrinfo *host;
705 int retn;
706
707 if ((retn = getaddrinfo(optarg, NULL, NULL, &host)) == 0) {
708 struct addrinfo *hptr = host;
709 switch (host->ai_family) {
710 case AF_INET: {
711 struct sockaddr_in *sa = (struct sockaddr_in *) host->ai_addr;
712 unsigned int addr;
713 bcopy ((char *)&sa->sin_addr, (char *)&addr, 4);
714 setArgusID (ArgusParser, &addr, ARGUS_IDIS_IPV4);
715 break;
716 }
717 default:
718 ArgusLog (LOG_ERR, "Probe ID %s not in address family\n", optarg);
719 break;
720 }
721 freeaddrinfo(hptr);
722
723 } else {
724 switch (retn) {
725 case EAI_AGAIN:
726 ArgusLog(LOG_ERR, "dns server not available");
727 break;
728 case EAI_NONAME:
729 ArgusLog(LOG_ERR, "srcid %s unknown", optarg);
730 break;
731 #if defined(EAI_ADDRFAMILY)
732 case EAI_ADDRFAMILY:
733 ArgusLog(LOG_ERR, "srcid %s has no IP address", optarg);
734 break;
735 #endif
736 case EAI_SYSTEM:
737 ArgusLog(LOG_ERR, "srcid %s name server error %s", optarg, strerror(errno));
738 break;
739 }
740 }
741 #else
742 struct hostent *host;
743
744 if ((host = gethostbyname(optarg)) != NULL) {
745 if ((host->h_addrtype == 2) && (host->h_length == 4)) {
746 unsigned int addr;
747 bcopy ((char *) *host->h_addr_list, (char *)&addr, host->h_length);
748 setArgusID (parser, &addr, ARGUS_IDIS_IPV4);
749 } else
750 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) host '%s' error %s\n", file, optarg, strerror(errno));
751 } else
752 if (optarg && isdigit((int)*optarg)) {
753 setArgusID (parser, optarg, ARGUS_IDIS_INT);
754 } else
755 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) syntax error line %d\n", file, linenum);
756
757 #endif
758 } else
759 ArgusLog (LOG_ERR, "RadiumParseResourceFile(%s) syntax error line %d\n", file, linenum);
760 }
761
762 break;
763
764 case RADIUM_ARGUS_SERVER:
765 ++parser->Sflag;
766 if (!Soption++ && (parser->ArgusRemoteHostList != NULL))
767 ArgusDeleteHostList(parser);
768
769 if (!(ArgusAddHostList (parser, optarg, ARGUS_DATA_SOURCE, IPPROTO_TCP)))
770 ArgusLog (LOG_ERR, "%s: host %s unknown\n", optarg);
771 break;
772
773 case RADIUM_CISCONETFLOW_PORT: {
774 ++parser->Sflag; ++parser->Cflag;
775 if (!Soption++ && (parser->ArgusRemoteHostList != NULL))
776 ArgusDeleteHostList(parser);
777
778 if (!(ArgusAddHostList (parser, optarg, ARGUS_CISCO_DATA_SOURCE, IPPROTO_UDP)))
779 ArgusLog (LOG_ERR, "%s: host %s unknown\n", optarg);
780
781 break;
782 }
783
784 case RADIUM_INPUT_FILE:
785 if ((!roption++) && (parser->ArgusInputFileList != NULL))
786 ArgusDeleteFileList(parser);
787
788 if (!(ArgusAddFileList (parser, optarg, (parser->Cflag ? ARGUS_CISCO_DATA_SOURCE : ARGUS_DATA_SOURCE), -1, -1))) {
789 ArgusLog (LOG_ERR, "%s: error: file arg %s\n", optarg);
790 }
791 break;
792
793 case RADIUM_ACCESS_PORT:
794 parser->ArgusPortNum = atoi(optarg);
795 break;
796 /*
797 case RADIUM_USER_AUTH:
798 ustr = strdup(optarg);
799 break;
800
801 case RADIUM_AUTH_PASS:
802 pstr = strdup(optarg);
803 break;
804 */
805 case RADIUM_OUTPUT_FILE:
806 case RADIUM_OUTPUT_STREAM: {
807 char *filter = NULL, *fptr;
808
809 if ((filter = strchr (optarg, ' ')) != NULL) {
810 *filter++ = '\0';
811
812 if ((fptr = strchr (filter, '"')) != NULL) {
813 *fptr++ = '\0';
814 filter = fptr;
815 }
816 }
817
818 setArgusWfile (parser, optarg, filter);
819 break;
820 }
821
822 case RADIUM_MAR_STATUS_INTERVAL:
823 setArgusMarReportInterval (parser, optarg);
824 break;
825
826 case RADIUM_DEBUG_LEVEL:
827 parser->debugflag = atoi(optarg);
828 break;
829
830 case RADIUM_FILTER_OPTIMIZER:
831 if ((strncasecmp(optarg, "yes", 3)))
832 setArgusOflag (parser, 1);
833 else
834 setArgusOflag (parser, 0);
835 break;
836
837 case RADIUM_FILTER_TAG:
838 if ((parser->ArgusRemoteFilter = ArgusCalloc (1, MAXSTRLEN)) != NULL) {
839 struct nff_program filter;
840
841 ptr = parser->ArgusRemoteFilter;
842 str = optarg;
843 while (*str) {
844 if ((*str == '\\') && (str[1] == '\n')) {
845 if (fgets(str, MAXSTRLEN, fd) != NULL)
846 while (*str && (isspace((int)*str) && (str[1] && isspace((int)str[1]))))
847 str++;
848 }
849
850 if ((*str != '\n') && (*str != '"'))
851 *ptr++ = *str++;
852 else
853 str++;
854 }
855
856 if (ArgusFilterCompile (&filter, parser->ArgusRemoteFilter, 0) < 0)
857 ArgusLog (LOG_ERR, "RaParseResourceFile: remote filter syntax error");
858 #ifdef ARGUSDEBUG
859 ArgusDebug (1, "RadiumParseResourceFile: ArgusFilter \"%s\" \n", parser->ArgusRemoteFilter);
860 #endif
861 }
862 break;
863
864 case RADIUM_BIND_IP:
865 if (*optarg != '\0')
866 setArgusBindAddr (parser, optarg);
867 #ifdef ARGUSDEBUG
868 ArgusDebug (1, "RadiumParseResourceFile: ArgusBindAddr \"%s\" \n", parser->ArgusBindAddr);
869 #endif
870 break;
871
872 case RADIUM_MIN_SSF:
873 if (*optarg != '\0') {
874 #ifdef ARGUS_SASL
875 ArgusMinSsf = atoi(optarg);
876 #ifdef ARGUSDEBUG
877 ArgusDebug (1, "RadiumParseResourceFile: ArgusMinSsf \"%s\" \n", ArgusMinSsf);
878 #endif
879 #endif
880 }
881 break;
882
883 case RADIUM_MAX_SSF:
884 if (*optarg != '\0') {
885 #ifdef ARGUS_SASL
886 ArgusMaxSsf = atoi(optarg);
887 #ifdef ARGUSDEBUG
888 ArgusDebug (1, "RadiumParseResourceFile: ArgusMaxSsf \"%s\" \n", ArgusMaxSsf);
889 #endif
890 #endif
891 }
892 break;
893
894 case RADIUM_ADJUST_TIME: {
895 char *ptr;
896 parser->ArgusAdjustTime = strtol(optarg, (char **)&ptr, 10);
897 if (ptr == optarg)
898 ArgusLog (LOG_ERR, "%s syntax error: line %d", file, linenum);
899
900 if (isalpha((int) *ptr)) {
901 switch (*ptr) {
902 case 's': break;
903 case 'm': parser->ArgusAdjustTime *= 60; break;
904 case 'h': parser->ArgusAdjustTime *= 3600; break;
905 }
906 }
907 #ifdef ARGUSDEBUG
908 ArgusDebug (1, "RadiumParseResourceFile: ArgusAdjustTime is %d secs\n", parser->ArgusAdjustTime);
909 #endif
910 break;
911 }
912
913 case RADIUM_CHROOT_DIR: {
914 if (chroot_dir != NULL)
915 free(chroot_dir);
916 chroot_dir = strdup(optarg);
917 break;
918 }
919 case RADIUM_SETUSER_ID: {
920 struct passwd *pw;
921 if ((pw = getpwnam(optarg)) == NULL)
922 ArgusLog (LOG_ERR, "unknown user \"%s\"\n", optarg);
923 new_uid = pw->pw_uid;
924 endpwent();
925 break;
926 }
927 case RADIUM_SETGROUP_ID: {
928 struct group *gr;
929 if ((gr = getgrnam(optarg)) == NULL)
930 ArgusLog (LOG_ERR, "unknown group \"%s\"\n", optarg);
931 new_gid = gr->gr_gid;
932 endgrent();
933 break;
934 }
935
936
937 case RADIUM_CLASSIFIER_FILE: {
938 if (parser->ArgusLabeler == NULL) {
939 if ((parser->ArgusLabeler = ArgusNewLabeler(parser, 0L)) == NULL)
940 ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");
941 }
942
943 if (RaLabelParseResourceFile (parser, parser->ArgusLabeler, optarg) != 0)
944 ArgusLog (LOG_ERR, "ArgusClientInit: label conf file error %s", strerror(errno));
945
946 RadiumAnalyticAlgorithmTable[0] = ArgusLabelRecord;
947 break;
948 }
949 }
950
951 done = 1;
952 break;
953 }
954 }
955 }
956 }
957
958 fclose(fd);
959
960 } else {
961 retn++;
962 #ifdef ARGUSDEBUG
963 ArgusDebug (1, "RadiumParseResourceFile: open %s %s\n", file, strerror(errno));
964 #endif
965 }
966 }
967
968 #ifdef ARGUSDEBUG
969 ArgusDebug (1, "RadiumParseResourceFile (%s) returning %d\n", file, retn);
970 #endif
971
972 return (retn);
973 }
974
975 void
clearRadiumConfiguration(void)976 clearRadiumConfiguration (void)
977 {
978 ArgusParser->dflag = 0;
979 setArgusID (ArgusParser, 0, 0);
980
981 ArgusParser->ArgusPortNum = 0;
982
983 clearArgusWfile (ArgusParser);
984 setArgusBindAddr (ArgusParser, NULL);
985 setArgusOflag (ArgusParser, 1);
986
987 ArgusParser->dflag = 0;
988
989 if (ArgusParser->ArgusRemoteHostList != NULL)
990 ArgusDeleteHostList(ArgusParser);
991
992 if (ArgusParser->ArgusInputFileList) {
993 ArgusDeleteFileList(ArgusParser);
994 }
995
996 if (ArgusParser->ArgusRemoteFilter) {
997 ArgusFree(ArgusParser->ArgusRemoteFilter);
998 ArgusParser->ArgusRemoteFilter = NULL;
999 }
1000
1001 #ifdef ARGUSDEBUG
1002 ArgusDebug (1, "clearRadiumConfiguration () returning\n");
1003 #endif
1004 }
1005