1 /*
2 * Argus Software. Argus files - Modeler
3 * Copyright (c) 2000-2015 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 * Written by Carter Bullard
21 * QoSient, LLC
22 *
23 */
24
25 /*
26 * $Id: //depot/argus/argus/argus/ArgusOutput.c#81 $
27 * $DateTime: 2015/04/06 10:38:44 $
28 * $Change: 2973 $
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "argus_config.h"
33 #endif
34
35 #if !defined(ArgusOutput)
36 #define ArgusOutput
37 #endif
38
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <ctype.h>
43 #include <math.h>
44
45 #if defined(HAVE_ZLIB_H)
46 #include <zlib.h>
47 #endif
48
49 #include <argus.h>
50 #include <argus_parser.h>
51 #include <argus_filter.h>
52
53 #if defined(ARGUS_THREADS)
54 #include <pthread.h>
55 #endif
56
57 void *ArgusOutputProcess(void *);
58
59 #if defined(ARGUS_TILERA)
60 extern int ArgusFirstTile;
61 #endif
62
63 struct timeval *getArgusMarReportInterval(struct ArgusOutputStruct *);
64 void setArgusMarReportInterval(struct ArgusOutputStruct *, char *);
65
66 struct ArgusRecord *ArgusGenerateInitialMar (struct ArgusOutputStruct *);
67 struct ArgusRecordStruct *ArgusGenerateSupplementalMarRecord (struct ArgusOutputStruct *, unsigned char);
68 struct ArgusRecordStruct *ArgusGenerateStatusMarRecord (struct ArgusOutputStruct *, unsigned char);
69
70 int RaDiffTime (struct timeval *, struct timeval *, struct timeval *);
71
72 struct ArgusOutputStruct *
ArgusNewOutput(struct ArgusSourceStruct * src,struct ArgusModelerStruct * model)73 ArgusNewOutput (struct ArgusSourceStruct *src, struct ArgusModelerStruct *model)
74 {
75 struct ArgusOutputStruct *retn = NULL;
76
77 if ((retn = (struct ArgusOutputStruct *) ArgusCalloc (1, sizeof (struct ArgusOutputStruct))) == NULL)
78 ArgusLog (LOG_ERR, "ArgusNewOutput() ArgusCalloc error %s\n", strerror(errno));
79
80 gettimeofday (&retn->ArgusGlobalTime, 0L);
81 #if defined(ARGUS_NANOSECONDS)
82 retn->ArgusGlobalTime.tv_usec *= 1000;
83 #endif
84 retn->ArgusStartTime = retn->ArgusGlobalTime;
85
86 retn->ArgusReportTime.tv_sec = retn->ArgusGlobalTime.tv_sec + retn->ArgusMarReportInterval.tv_sec;
87 retn->ArgusReportTime.tv_usec += retn->ArgusMarReportInterval.tv_usec;
88 retn->ArgusLastMarUpdateTime = retn->ArgusGlobalTime;
89
90 if ((retn->ArgusClients = ArgusNewQueue()) == NULL)
91 ArgusLog (LOG_ERR, "ArgusNewOutput: clients queue %s", strerror(errno));
92
93 if ((retn->ArgusOutputList = ArgusNewList()) == NULL)
94 ArgusLog (LOG_ERR, "ArgusNewOutput: ArgusNewList %s", strerror(errno));
95
96 if ((retn->ArgusInputList = ArgusNewList()) == NULL)
97 ArgusLog (LOG_ERR, "ArgusNewOutput: ArgusNewList %s", strerror(errno));
98
99 retn->ArgusSrc = src;
100 retn->ArgusModel = model;
101
102 #if defined(ARGUS_THREADS)
103 pthread_mutex_init(&retn->lock, NULL);
104 #endif
105
106 #ifdef ARGUSDEBUG
107 ArgusDebug (1, "ArgusNewOutput() returning retn %p\n", retn);
108 #endif
109
110 return (retn);
111 }
112
113
114 #ifdef ARGUS_SASL
115 int iptostring(const struct sockaddr *, socklen_t, char *, unsigned);
116
117 static int
ArgusSaslLog(void * context,int priority,const char * message)118 ArgusSaslLog (void *context __attribute__((unused)), int priority, const char *message)
119 {
120 const char *label;
121
122 if (! message)
123 return SASL_BADPARAM;
124
125 switch (priority) {
126 case SASL_LOG_ERR: label = "Error"; break;
127 case SASL_LOG_NOTE: label = "Info"; break;
128 default: label = "Other"; break;
129 }
130
131 #ifdef ARGUSDEBUG
132 ArgusDebug(1, "ArgusSaslLog %s: %s", label, message);
133 #endif
134
135 return SASL_OK;
136 }
137
138 //#ifdef _LP64
139 //#define PLUGINDIR "/usr/lib64/sasl2"
140 //#else
141
142 #define PLUGINDIR "/usr/local/lib/sasl2"
143
144 //#endif
145
146
147 char *searchpath = NULL;
148
149 static int
ArgusSaslGetPath(void * context,char ** path)150 ArgusSaslGetPath(void *context __attribute__((unused)), char ** path)
151 {
152 if (! path)
153 return SASL_BADPARAM;
154 if (searchpath)
155 *path = searchpath;
156 else
157 *path = PLUGINDIR;
158
159 #ifdef ARGUSDEBUG
160 ArgusDebug(2, "SASL path %s", *path);
161 #endif
162
163 return SASL_OK;
164 }
165
166 //typedef struct sasl_callback {
167 // /* Identifies the type of the callback function.
168 // * Mechanisms must ignore callbacks with id's they don't recognize.
169 // */
170 // unsigned long id;
171 // int (*proc)(void); /* Callback function. Types of arguments vary by 'id' */
172 // void *context;
173 //} sasl_callback_t;
174
175 typedef int (*funcptr)();
176
177 static const struct sasl_callback argus_cb[] = {
178 { SASL_CB_LOG, (funcptr)&ArgusSaslLog, NULL },
179 { SASL_CB_LIST_END, NULL, NULL }
180 };
181 #endif
182
183 void
ArgusInitOutput(struct ArgusOutputStruct * output)184 ArgusInitOutput (struct ArgusOutputStruct *output)
185 {
186 struct ArgusWfileStruct *wfile;
187 extern char *chroot_dir;
188 extern uid_t new_uid;
189 extern gid_t new_gid;
190 int i, len = 0, retn = 0;
191
192 #if defined(ARGUS_THREADS)
193 extern pthread_attr_t *ArgusAttr;
194 #endif
195
196 ArgusParser = ArgusNewParser(ArgusProgramName);
197
198 if (output->ArgusInitMar != NULL)
199 ArgusFree (output->ArgusInitMar);
200
201 if ((output->ArgusInitMar = ArgusGenerateInitialMar(output)) == NULL)
202 ArgusLog (LOG_ERR, "ArgusInitOutput: ArgusGenerateInitialMar error %s", strerror(errno));
203
204 len = ntohs(output->ArgusInitMar->hdr.len) * 4;
205
206 for (i = 0; i < ARGUS_MAXLISTEN; i++)
207 output->ArgusLfd[i] = -1;
208
209 if (output->ArgusPortNum != 0) {
210 char errbuf[256];
211 if (ArgusEstablishListen (output, errbuf) < 0)
212 ArgusLog (LOG_ERR, "%s", errbuf);
213 }
214
215 if (chroot_dir != NULL)
216 ArgusSetChroot(chroot_dir);
217
218 if (new_gid > 0) {
219 if (setegid(new_gid) < 0)
220 ArgusLog (LOG_ERR, "ArgusInitOutput: setgid error %s", strerror(errno));
221 }
222 if (new_uid > 0) {
223 if (seteuid(new_uid) < 0)
224 ArgusLog (LOG_ERR, "ArgusInitOutput: setuid error %s", strerror(errno));
225 }
226
227 if (output->ArgusWfileList) {
228 struct ArgusListRecord *sfile= output->ArgusWfileList->start->obj;
229 do {
230 if ((wfile = (struct ArgusWfileStruct *) ArgusPopFrontList(output->ArgusWfileList, ARGUS_LOCK)) != NULL) {
231 struct ArgusClientData *client = (void *) ArgusCalloc (1, sizeof(struct ArgusClientData));
232
233 if (client == NULL)
234 ArgusLog (LOG_ERR, "ArgusInitOutput: ArgusCalloc %s", strerror(errno));
235
236 if (strcmp (wfile->filename, "-")) {
237 if ((!(strncmp (wfile->filename, "argus-udp://", 12))) ||
238 (!(strncmp (wfile->filename, "udp://", 6)))) {
239
240 char *baddr = strstr (wfile->filename, "udp://");
241 baddr = &baddr[6];
242
243 #if defined(HAVE_GETADDRINFO)
244 struct addrinfo hints, *hp = NULL, *bhp = NULL;
245 int retn = 0, numerichost = 1;
246 char *port, *ptr;
247
248 if ((port = strchr(baddr, ':')) != NULL) {
249 *port++ = '\0';
250 } else {
251 port = "561";
252 }
253
254 if (output->ArgusBindAddrs || output->ArgusBindPort) {
255 char *ArgusBindAddr = NULL;
256
257 memset(&hints, 0, sizeof(hints));
258 hints.ai_family = AF_INET;
259 hints.ai_socktype = SOCK_DGRAM;
260 hints.ai_protocol = IPPROTO_UDP;
261 hints.ai_flags |= AI_PASSIVE;
262
263 if (ArgusBindAddr && (!strcmp(ArgusBindAddr, "any")))
264 ArgusBindAddr = NULL;
265 getaddrinfo(ArgusBindAddr, output->ArgusBindPort, NULL, &bhp);
266 }
267
268 memset(&hints, 0, sizeof(hints));
269 hints.ai_family = AF_INET;
270 hints.ai_socktype = SOCK_DGRAM;
271 hints.ai_protocol = IPPROTO_UDP;
272
273 for (ptr = port; *ptr != '\0'; ptr++) {
274 int c = *ptr;
275 if (!isdigit(c))
276 numerichost = 0;
277 }
278 #if defined(AI_NUMERICHOST)
279 if (numerichost)
280 hints.ai_flags |= AI_NUMERICHOST;
281 #endif
282 if ((retn = getaddrinfo(baddr, port, &hints, &client->host)) != 0) {
283 switch (retn) {
284 case EAI_AGAIN:
285 ArgusLog(LOG_ERR, "dns server not available");
286 break;
287 case EAI_NONAME:
288 ArgusLog(LOG_ERR, "bind address %s unknown", optarg);
289 break;
290 #if defined(EAI_ADDRFAMILY)
291 case EAI_ADDRFAMILY:
292 ArgusLog(LOG_ERR, "bind address %s has no IP address", optarg);
293 break;
294 #endif
295 case EAI_SYSTEM:
296 ArgusLog(LOG_ERR, "bind address %s name server error %s", optarg, strerror(errno));
297 break;
298 }
299 }
300
301 hp = client->host;
302
303 do {
304 if ((client->fd = socket (hp->ai_family, hp->ai_socktype, hp->ai_protocol)) >= 0) {
305 unsigned char ttl = 128;
306 int ttl_size = sizeof(ttl);
307
308 if (setsockopt(client->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, ttl_size) < 0)
309 ArgusLog (LOG_INFO, "ArgusInitOutput: setsockopt set multicast TTL: %s", strerror(errno));
310
311 if (bhp != NULL) {
312 #if defined(SO_REUSEPORT)
313 int on = 1;
314 #endif
315 if (bind (client->fd, bhp->ai_addr, sizeof(struct sockaddr_in)) < 0)
316 ArgusLog (LOG_ERR, "ArgusInitOutput: bind %s", strerror(errno));
317 #if defined(SO_REUSEPORT)
318 if (setsockopt(client->fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0)
319 ArgusLog (LOG_INFO, "ArgusInitOutput: setsockopt set reuseport %s", strerror(errno));
320 #endif
321 }
322
323 } else
324 ArgusLog (LOG_ERR, "ArgusInitOutput: socket %s: %s", wfile->filename, strerror(errno));
325 hp = hp->ai_next;
326 } while (hp != NULL);
327 #endif
328 } else
329 if ((client->fd = open (wfile->filename, O_WRONLY|O_APPEND|O_CREAT|O_NONBLOCK, 0x1a4)) < 0)
330 ArgusLog (LOG_ERR, "ArgusInitOutput: open %s: %s", wfile->filename, strerror(errno));
331 } else {
332 client->fd = 1;
333 output->ArgusWriteStdOut++;
334 }
335
336 if (wfile->filter != NULL) {
337 if (ArgusFilterCompile (&client->ArgusNFFcode, wfile->filter, 1) < 0)
338 ArgusLog (LOG_ERR, "ArgusInitOutput: ArgusFilter syntax error: %s", wfile->filter);
339 client->ArgusFilterInitialized++;
340 #ifdef ARGUSDEBUG
341 {
342 char buf[MAXSTRLEN];
343 bzero(buf, MAXSTRLEN);
344 nff_dump(&client->ArgusNFFcode, buf, MAXSTRLEN, 1);
345 ArgusDebug (5, "ArgusInitOutput: ArgusFilterCompile returned: \n%s\n", buf);
346 }
347 #endif
348 }
349
350 if ((client->sock = ArgusNewSocket(client->fd)) == NULL)
351 ArgusLog (LOG_ERR, "ArgusInitOutput: ArgusNewSocket error %s", strerror(errno));
352
353 if (client->host != NULL) {
354 if ((retn = sendto(client->fd, (char *) output->ArgusInitMar, len, 0, client->host->ai_addr, client->host->ai_addrlen)) < 0)
355 ArgusLog (LOG_ERR, "ArgusInitOutput: sendto(): retn %d %s", retn, strerror(errno));
356
357 } else {
358 while ((retn = write (client->fd, (char *) output->ArgusInitMar, len)) != len) {
359 if (!output->ArgusWriteStdOut) {
360 close (client->fd);
361 unlink (wfile->filename);
362 }
363 ArgusLog (LOG_ERR, "ArgusInitOutput: write(): retn %d %s", retn, strerror(errno));
364 }
365 }
366
367 if (strcmp(wfile->filename, "/dev/null"))
368 client->sock->filename = strdup(wfile->filename);
369
370 ArgusAddToQueue(output->ArgusClients, &client->qhdr, ARGUS_LOCK);
371
372 client->ArgusClientStart++;
373 ArgusPushBackList (output->ArgusWfileList, (struct ArgusListRecord *) wfile, ARGUS_LOCK);
374 }
375 } while (output->ArgusWfileList->start->obj != sfile);
376
377 ArgusDeleteList(output->ArgusWfileList, ARGUS_WFILE_LIST);
378 output->ArgusWfileList = NULL;
379 }
380
381 if (new_gid > 0)
382 if (setegid(ArgusGid) < 0)
383 ArgusLog (LOG_ERR, "ArgusInitOutput: setgid error %s", strerror(errno));
384
385 if (new_uid > 0)
386 if (seteuid(ArgusUid) < 0)
387 ArgusLog (LOG_ERR, "ArgusInitOutput: setuid error %s", strerror(errno));
388
389 #ifdef ARGUS_SASL
390 if ((retn = sasl_server_init(argus_cb, ArgusProgramName)) != SASL_OK)
391 ArgusLog (LOG_ERR, "ArgusInitOutput() sasl_server_init failed %d\n", retn);
392 #endif /* ARGUS_SASL */
393
394 #if defined(ARGUS_THREADS)
395 if ((pthread_create(&output->thread, ArgusAttr, ArgusOutputProcess, (void *) output)) != 0)
396 ArgusLog (LOG_ERR, "ArgusInitOutput() pthread_create error %s\n", strerror(errno));
397
398 #endif /* ARGUS_THREADS */
399
400 #ifdef ARGUSDEBUG
401 ArgusDebug (1, "ArgusInitOutput() done");
402 #endif
403 }
404
405
406 void
ArgusCloseOutput(struct ArgusOutputStruct * output)407 ArgusCloseOutput(struct ArgusOutputStruct *output)
408 {
409 #if defined(ARGUS_THREADS)
410 void *retn = NULL;
411
412 #ifdef ARGUSDEBUG
413 ArgusDebug (1, "ArgusCloseOutput(%p) scheduling closure after %d records\n", output, output->ArgusInputList->count);
414 #endif
415 if ((output != NULL) && (output->thread != 0)) {
416 output->status |= ARGUS_SHUTDOWN;
417 if (output->thread)
418 pthread_join(output->thread, &retn);
419 } else {
420 #ifdef ARGUSDEBUG
421 ArgusDebug (4, "ArgusCloseOutput(%p) no output or output->thread available\n", output);
422 #endif
423 }
424 #else
425 if (output != NULL) {
426 output->status |= ARGUS_SHUTDOWN;
427 #ifdef ARGUSDEBUG
428 ArgusDebug (2, "ArgusCloseOutput(%p) scheduling closure after writing records\n", output);
429 #endif
430 ArgusOutputProcess(output);
431 }
432 #endif /* ARGUS_THREADS */
433
434 ArgusDeleteList(output->ArgusInputList, ARGUS_OUTPUT_LIST);
435 ArgusDeleteList(output->ArgusOutputList, ARGUS_OUTPUT_LIST);
436
437 ArgusDeleteQueue(output->ArgusClients);
438
439 if (output->ArgusInitMar != NULL)
440 ArgusFree (output->ArgusInitMar);
441
442 if (ArgusParser != NULL) {
443 ArgusCloseParser(ArgusParser);
444 ArgusFree(ArgusParser);
445 ArgusParser = NULL;
446 }
447
448 #ifdef ARGUSDEBUG
449 ArgusDebug (1, "ArgusCloseOutput(%p) done\n", output);
450 #endif
451 }
452
453
454 void ArgusCheckClientStatus (struct ArgusOutputStruct *, int);
455 int ArgusCheckClientMessage (struct ArgusOutputStruct *, struct ArgusClientData *);
456 int ArgusCongested = 0;
457
458 int ArgusOutputStatusTime(struct ArgusOutputStruct *);
459
460 int
ArgusOutputStatusTime(struct ArgusOutputStruct * output)461 ArgusOutputStatusTime(struct ArgusOutputStruct *output)
462 {
463 int retn = 0;
464
465
466 if ((output->ArgusReportTime.tv_sec < output->ArgusGlobalTime.tv_sec) ||
467 ((output->ArgusReportTime.tv_sec == output->ArgusGlobalTime.tv_sec) &&
468 (output->ArgusReportTime.tv_usec < output->ArgusGlobalTime.tv_usec))) {
469
470 long long dtime = ArgusTimeDiff(&output->ArgusGlobalTime, &output->ArgusReportTime);
471
472 if (dtime > 1000000)
473 output->ArgusReportTime = output->ArgusGlobalTime;
474
475 output->ArgusReportTime.tv_sec += getArgusMarReportInterval(output)->tv_sec;
476 output->ArgusReportTime.tv_usec += getArgusMarReportInterval(output)->tv_usec;
477
478 if (output->ArgusReportTime.tv_usec > ARGUS_FRACTION_TIME) {
479 output->ArgusReportTime.tv_sec++;
480 output->ArgusReportTime.tv_usec -= ARGUS_FRACTION_TIME;
481 }
482
483 retn++;
484 }
485
486 #ifdef ARGUSDEBUG
487 ArgusDebug (7, "ArgusOutputStatusTime(%p) done", output);
488 #endif
489 return (retn);
490 }
491
492
493
494 void *
ArgusOutputProcess(void * arg)495 ArgusOutputProcess(void *arg)
496 {
497 struct ArgusOutputStruct *output = (struct ArgusOutputStruct *) arg;
498 struct timeval ArgusUpDate = {0, 500000}, ArgusNextUpdate = {0,0};
499 struct ArgusListStruct *list = NULL;
500 int val, count;
501 void *retn = NULL;
502
503 #if defined(ARGUS_THREADS)
504 sigset_t blocked_signals;
505 #endif /* ARGUS_THREADS */
506
507 #ifdef ARGUSDEBUG
508 #if defined(ARGUS_THREADS)
509 ArgusDebug (1, "ArgusOutputProcess(%p) starting\n", output);
510 #else
511 ArgusDebug (6, "ArgusOutputProcess(%p) starting\n", output);
512 #endif
513 #endif
514
515 #if defined(ARGUS_TILERA)
516 bind_proc(ArgusFirstTile + 1);
517 #endif
518
519 #if defined(ARGUS_THREADS)
520 sigfillset(&blocked_signals);
521 pthread_sigmask(SIG_BLOCK, &blocked_signals, NULL);
522
523 #if defined(HAVE_SOLARIS)
524 sigignore(SIGPIPE);
525 #else
526 (void) signal (SIGPIPE, SIG_IGN);
527 #endif
528
529 while ((list = output->ArgusInputList) == NULL) {
530 struct timespec tsbuf = {0, 10000000}, *ts = &tsbuf;
531 #ifdef ARGUSDEBUG
532 ArgusDebug (6, "ArgusOutputProcess(%p) waiting for ArgusOutputList\n", output);
533 #endif
534 nanosleep (ts, NULL);
535 }
536
537 while (!(output->status & ARGUS_SHUTDOWN) || ((output->status & ARGUS_SHUTDOWN) && !ArgusListEmpty(list))) {
538 #else
539 if ((list = output->ArgusInputList) != NULL) {
540 #endif
541 struct ArgusRecordStruct *rec = NULL;
542
543 gettimeofday (&output->ArgusGlobalTime, 0L);
544 #if defined(ARGUS_NANOSECONDS)
545 output->ArgusGlobalTime.tv_usec *= 1000;
546 #endif
547 #ifdef ARGUSDEBUG
548 ArgusDebug (6, "ArgusOutputProcess() looping\n");
549 #endif
550
551 /* check to see if there are any new clients */
552
553 if ((output->ArgusPortNum != 0) &&
554 ((output->ArgusGlobalTime.tv_sec > ArgusNextUpdate.tv_sec) ||
555 ((output->ArgusGlobalTime.tv_sec == ArgusNextUpdate.tv_sec) &&
556 (output->ArgusGlobalTime.tv_usec > ArgusNextUpdate.tv_usec)))) {
557
558 if (output->ArgusListens) {
559 struct timeval wait = {0, 0};
560 fd_set readmask;
561 int i, width = 0;
562
563 FD_ZERO(&readmask);
564
565 for (i = 0; i < output->ArgusListens; i++) {
566 if (output->ArgusLfd[i] != -1) {
567 FD_SET(output->ArgusLfd[i], &readmask);
568 width = (output->ArgusLfd[i] > width) ? output->ArgusLfd[i] : width;
569 }
570 }
571
572 if (output->ArgusClients) {
573 #ifdef ARGUSDEBUG
574 ArgusDebug (6, "ArgusOutputProcess() checking for remotes\n");
575 #endif
576 #if defined(ARGUS_THREADS)
577 pthread_mutex_lock(&output->ArgusClients->lock);
578 #endif
579 if (output->ArgusClients->count) {
580 struct ArgusClientData *client = (void *)output->ArgusClients->start;
581
582 do {
583 if (client->sock && !(client->sock->filename)) {
584 FD_SET(client->fd, &readmask);
585 width = (client->fd > width) ? client->fd : width;
586 }
587 client = (void *) client->qhdr.nxt;
588 } while (client != (void *)output->ArgusClients->start);
589 }
590
591 if ((val = select (width + 1, &readmask, NULL, NULL, &wait)) >= 0) {
592 if (val > 0) {
593 struct ArgusClientData *client = (void *)output->ArgusClients->start;
594 int done = 0;
595 #ifdef ARGUSDEBUG
596 ArgusDebug (6, "ArgusOutputProcess() select returned with tasks\n");
597 #endif
598 for (i = 0; (i < output->ArgusListens) && (!done); i++) {
599 if (FD_ISSET(output->ArgusLfd[i], &readmask))
600 ArgusCheckClientStatus(output, output->ArgusLfd[i]);
601
602 if (client != NULL) {
603 do {
604 if (client->fd != -1) {
605 if (FD_ISSET(client->fd, &readmask)) {
606 if (ArgusCheckClientMessage(output, client) < 0) {
607 ArgusDeleteSocket(output, client);
608 } else {
609 done++;
610 break;
611 }
612 }
613 }
614 client = (void *) client->qhdr.nxt;
615 } while (client != (void *)output->ArgusClients->start);
616 }
617 }
618 }
619 }
620
621 #if defined(ARGUS_THREADS)
622 pthread_mutex_unlock(&output->ArgusClients->lock);
623 #endif
624 #ifdef ARGUSDEBUG
625 ArgusDebug (6, "ArgusOutputProcess() done checking for remotes\n");
626 #endif
627 }
628
629 ArgusNextUpdate.tv_usec += ArgusUpDate.tv_usec;
630 ArgusNextUpdate.tv_sec += ArgusUpDate.tv_sec;
631
632 if (ArgusNextUpdate.tv_usec > ARGUS_FRACTION_TIME) {
633 ArgusNextUpdate.tv_sec++;
634 ArgusNextUpdate.tv_usec -= ARGUS_FRACTION_TIME;
635 }
636 }
637 }
638
639 #if defined(ARGUS_THREADS)
640 if (ArgusListEmpty(list)) {
641 struct timeval tvp;
642 struct timespec tsbuf, *ts = &tsbuf;
643 gettimeofday (&tvp, 0L);
644 ts->tv_sec = tvp.tv_sec + 0;
645 ts->tv_nsec = tvp.tv_usec * 1000;
646 ts->tv_nsec += 100000000;
647 while (ts->tv_nsec > 1000000000) {
648 ts->tv_sec++;
649 ts->tv_nsec -= 1000000000;
650 }
651 #ifdef ARGUSDEBUG
652 ArgusDebug (6, "ArgusOutputProcess() waiting for input list\n");
653 #endif
654 if (pthread_mutex_lock(&list->lock)) {
655 #ifdef ARGUSDEBUG
656 ArgusDebug (6, "ArgusOutputProcess() pthread_mutex_lock error %s\n", strerror(errno));
657 #endif
658 }
659
660 if (pthread_cond_timedwait(&list->cond, &list->lock, ts) == EINVAL) {
661 #ifdef ARGUSDEBUG
662 ArgusDebug (6, "ArgusOutputProcess() pthread_cond_timedwait error bad value\n");
663 #endif
664 }
665
666 if (pthread_mutex_unlock(&list->lock)) {
667 #ifdef ARGUSDEBUG
668 ArgusDebug (6, "ArgusOutputProcess() pthread_mutex_lock error %s\n", strerror(errno));
669 #endif
670 }
671 }
672 #endif
673
674 if (ArgusOutputStatusTime(output)) {
675 if ((rec = ArgusGenerateStatusMarRecord(output, ARGUS_STATUS)) != NULL) {
676 if (output->ArgusClients) {
677 #if defined(ARGUS_THREADS)
678 pthread_mutex_lock(&output->ArgusClients->lock);
679 #endif
680 if (output->ArgusClients->count) {
681 struct ArgusClientData *client = (void *)output->ArgusClients->start;
682 do {
683 if ((client->fd != -1) && (client->sock != NULL) && client->ArgusClientStart) {
684 if (ArgusWriteSocket (output, client, rec) < 0) {
685 ArgusDeleteSocket(output, client);
686 }
687 }
688 client = (void *) client->qhdr.nxt;
689 } while (client != (void *)output->ArgusClients->start);
690 }
691 #if defined(ARGUS_THREADS)
692 pthread_mutex_unlock(&output->ArgusClients->lock);
693 #endif
694 }
695 ArgusFreeListRecord (rec);
696 output->ArgusLastMarUpdateTime = output->ArgusGlobalTime;
697 }
698 }
699
700 if (output->ArgusOutputList && !(ArgusListEmpty(list))) {
701 int done = 0;
702 ArgusLoadList(list, output->ArgusOutputList);
703
704 while (!done && ((rec = (struct ArgusRecordStruct *) ArgusPopFrontList(output->ArgusOutputList, ARGUS_LOCK)) != NULL)) {
705 output->ArgusTotalRecords++;
706 output->ArgusOutputSequence = rec->canon.trans.seqnum;
707 count = 0;
708 #ifdef ARGUSDEBUG
709 ArgusDebug (6, "ArgusOutputProcess() received rec %p totals %lld seq %d\n", rec, output->ArgusTotalRecords, output->ArgusOutputSequence);
710 #endif
711 if (((rec->hdr.type & 0xF0) == ARGUS_MAR) && ((rec->hdr.cause & 0xF0) == ARGUS_STOP)) {
712 done++;
713 output->status |= ARGUS_SHUTDOWN;
714 ArgusFreeListRecord(rec);
715 if ((rec = ArgusGenerateStatusMarRecord(output, ARGUS_STOP)) == NULL) {
716 }
717 #ifdef ARGUSDEBUG
718 ArgusDebug (3, "ArgusOutputProcess(%p) rec %d received as stop record \n", output, output->ArgusTotalRecords);
719 #endif
720 }
721
722 if (output->ArgusClients) {
723 #if defined(ARGUS_THREADS)
724 pthread_mutex_lock(&output->ArgusClients->lock);
725 #endif
726 if (output->ArgusClients->count) {
727 struct ArgusClientData *client = (void *)output->ArgusClients->start;
728 int i, ArgusWriteRecord = 0;
729 #ifdef ARGUSDEBUG
730 ArgusDebug (5, "ArgusOutputProcess() %d client(s) for record %p\n", output->ArgusClients->count, rec);
731 #endif
732 for (i = 0; i < output->ArgusClients->count; i++) {
733 if ((client->fd != -1) && (client->sock != NULL) && client->ArgusClientStart) {
734 #ifdef ARGUSDEBUG
735 ArgusDebug (5, "ArgusOutputProcess() client %p ready fd %d sock %p start %d", client, client->fd, client->sock, client->ArgusClientStart);
736 #endif
737 ArgusWriteRecord = 1;
738 if (client->ArgusFilterInitialized) {
739 bcopy(&rec->hdr, &rec->canon.hdr, sizeof(rec->hdr));
740 if (!(ArgusFilterRecord ((struct nff_insn *)client->ArgusNFFcode.bf_insns, rec)))
741 ArgusWriteRecord = 0;
742 }
743
744 if (ArgusWriteRecord) {
745 if (ArgusWriteSocket (output, client, rec) < 0) {
746 ArgusDeleteSocket(output, client);
747 } else {
748 if (ArgusWriteOutSocket (output, client) < 0) {
749 ArgusDeleteSocket(output, client);
750 }
751 }
752 } else {
753 #ifdef ARGUSDEBUG
754 ArgusDebug (5, "ArgusOutputProcess() client %p filter blocks fd %d sock %p start %d", client, client->fd, client->sock, client->ArgusClientStart);
755 #endif
756 }
757
758 } else {
759 struct timeval tvbuf, *tvp = &tvbuf;
760 #ifdef ARGUSDEBUG
761 ArgusDebug (5, "ArgusOutputProcess() %d client(s) not ready fd %d sock 0x%x start %d", output->ArgusClients->count, client->fd, client->sock, client->ArgusClientStart);
762 #endif
763 RaDiffTime (&output->ArgusGlobalTime, &client->startime, tvp);
764 if (tvp->tv_sec >= ARGUS_CLIENT_STARTUP_TIMEOUT) {
765 if (client->sock != NULL) {
766 ArgusDeleteSocket(output, client);
767 ArgusLog (LOG_WARNING, "ArgusCheckClientMessage: client %s never started: timed out",
768 (client->hostname != NULL) ? client->hostname : "noname");
769 }
770 client->ArgusClientStart = 1;
771 }
772 }
773 client = (void *) client->qhdr.nxt;
774 }
775 }
776 #if defined(ARGUS_THREADS)
777 pthread_mutex_unlock(&output->ArgusClients->lock);
778 #endif
779 } else {
780 #ifdef ARGUSDEBUG
781 ArgusDebug (5, "ArgusOutputProcess() no client for record %p\n", rec);
782 #endif
783 }
784 ArgusFreeListRecord(rec);
785 }
786
787 if (output->ArgusWriteStdOut)
788 fflush (stdout);
789 }
790 #ifdef ARGUSDEBUG
791 ArgusDebug (6, "ArgusOutputProcess() checking out clients\n");
792 #endif
793 #if defined(ARGUS_THREADS)
794 pthread_mutex_lock(&output->ArgusClients->lock);
795 #endif
796 if ((output->ArgusPortNum != 0) && (output->ArgusClients->count)) {
797 struct ArgusClientData *client = (void *)output->ArgusClients->start;
798 int i;
799
800 for (i = 0; i < output->ArgusClients->count; i++) {
801 if ((client->fd != -1) && (client->sock != NULL)) {
802 if (output->status & ARGUS_SHUTDOWN) {
803 ArgusWriteOutSocket (output, client);
804 ArgusDeleteSocket(output, client);
805 } else {
806 if (ArgusWriteOutSocket (output, client) < 0) {
807 ArgusDeleteSocket(output, client);
808 }
809 }
810 }
811 client = (void *) client->qhdr.nxt;
812 }
813
814 for (i = 0, count = output->ArgusClients->count; (i < count) && output->ArgusClients->count; i++) {
815 if ((client->fd == -1) && (client->sock == NULL) && client->ArgusClientStart) {
816 if (ArgusRemoveFromQueue(output->ArgusClients, &client->qhdr, ARGUS_NOLOCK) != NULL)
817 ArgusFree(client);
818 i = 0; count = output->ArgusClients->count;
819 client = (void *)output->ArgusClients->start;
820 } else
821 client = (void *)client->qhdr.nxt;
822 }
823 }
824
825 #if defined(ARGUS_THREADS)
826 pthread_mutex_unlock(&output->ArgusClients->lock);
827 #endif
828 #ifdef ARGUSDEBUG
829 ArgusDebug (6, "ArgusOutputProcess() done with clients\n");
830 #endif
831
832 #if !defined(ARGUS_THREADS)
833 }
834 #else
835 }
836 #endif /* ARGUS_THREADS */
837
838 #ifdef ARGUSDEBUG
839 #if defined(ARGUS_THREADS)
840 ArgusDebug (6, "ArgusOutputProcess(%p) shuting down %d\n", output, output->ArgusInputList->count);
841 #else
842 ArgusDebug (6, "ArgusOutputProcess(%p) done count %d\n", output, output->ArgusInputList->count);
843 #endif /* ARGUS_THREADS */
844 #endif
845
846 #if defined(ARGUS_THREADS)
847 {
848 struct ArgusClientData *client;
849 while ((client = (void *) output->ArgusClients->start) != NULL) {
850 if ((client->fd != -1) && (client->sock != NULL))
851 ArgusWriteOutSocket (output, client);
852
853 ArgusDeleteSocket(output, client);
854 if (ArgusRemoveFromQueue(output->ArgusClients, &client->qhdr, ARGUS_LOCK) != NULL)
855 ArgusFree(client);
856 }
857 }
858
859 #ifdef ARGUSDEBUG
860 ArgusDebug (1, "ArgusOutputProcess(%p) exiting\n", output);
861 #endif
862 pthread_exit(retn);
863 #endif /* ARGUS_THREADS */
864
865 return (retn);
866 }
867
868
869 #include <netdb.h>
870
871 int
ArgusEstablishListen(struct ArgusOutputStruct * output,char * errbuf)872 ArgusEstablishListen (struct ArgusOutputStruct *output, char *errbuf)
873 {
874 int port = output->ArgusPortNum;
875 struct ArgusBindAddrStruct *ArgusBindAddrs = NULL;
876 char *baddr = NULL;
877 int s = -1;
878
879 if (port > 0) {
880 if (output->ArgusListens > 0) {
881 int i = output->ArgusListens;
882 for (i = 0; i < output->ArgusListens; i++) {
883 close(output->ArgusLfd[i]);
884 output->ArgusLfd[i] = -1;
885 }
886 }
887 output->ArgusListens = 0;
888
889 if (output->ArgusBindAddrs != NULL) {
890 ArgusBindAddrs = (struct ArgusBindAddrStruct *)output->ArgusBindAddrs->start;
891 baddr = ArgusBindAddrs->addr;
892 }
893
894 do {
895 #if defined(HAVE_GETADDRINFO)
896 {
897 struct addrinfo hints, *host, *hp;
898 char portbuf[32];
899 int retn = 0;
900
901 memset(&hints, 0, sizeof(hints));
902 if (output->ArgusAddrInfo.ai_socktype || output->ArgusAddrInfo.ai_protocol) {
903 hints.ai_family = output->ArgusAddrInfo.ai_family;
904 hints.ai_socktype = output->ArgusAddrInfo.ai_socktype;
905 hints.ai_protocol = output->ArgusAddrInfo.ai_protocol;
906 } else {
907 hints.ai_family = PF_UNSPEC;
908 hints.ai_socktype = SOCK_STREAM;
909 hints.ai_protocol = IPPROTO_TCP;
910 hints.ai_flags = AI_PASSIVE;
911 }
912
913 snprintf(portbuf, 32, "%d", port);
914
915 if ((retn = getaddrinfo(baddr, portbuf, &hints, &host)) != 0) {
916 switch (retn) {
917 case EAI_AGAIN:
918 ArgusLog(LOG_ERR, "dns server not available");
919 break;
920 case EAI_NONAME:
921 ArgusLog(LOG_ERR, "bind address %s unknown", optarg);
922 break;
923 #if defined(EAI_ADDRFAMILY)
924 case EAI_ADDRFAMILY:
925 ArgusLog(LOG_ERR, "bind address %s has no IP address", optarg);
926 break;
927 #endif
928 case EAI_SYSTEM:
929 ArgusLog(LOG_ERR, "bind address %s name server error %s", optarg, strerror(errno));
930 break;
931 }
932 }
933
934 hp = host;
935
936 do {
937 retn = -1;
938 if ((s = socket (hp->ai_family, hp->ai_socktype, hp->ai_protocol)) >= 0) {
939 int flags = fcntl (s, F_GETFL, 0L);
940 if ((fcntl (s, F_SETFL, flags | O_NDELAY)) >= 0) {
941 int on = 1;
942 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
943 ArgusLog (LOG_INFO, "ArgusInitOutput: setsockopt set reuseaddr %s", strerror(errno));
944 #ifdef ARGUSDEBUG
945 if (baddr)
946 ArgusDebug (1, "ArgusEstablishListen(%p, %p) binding: %s:%d family: %d\n", output, errbuf, baddr, port, hp->ai_family);
947 else {
948 #if defined(__OpenBSD__)
949 switch (hp->ai_family) {
950 case AF_INET6: ((struct sockaddr_in6 *)hp->ai_addr)->sin6_addr = in6addr_any; break;
951 }
952 #endif
953 ArgusDebug (1, "ArgusEstablishListen(%d, %p) binding: any:%d family: %d\n", port, errbuf, port, hp->ai_family);
954 }
955 #endif
956
957 if (!(bind (s, hp->ai_addr, hp->ai_addrlen))) {
958 switch (hp->ai_socktype) {
959 case SOCK_STREAM:
960 if ((retn = listen (s, ARGUS_MAXLISTEN)) >= 0) {
961 output->ArgusLfd[output->ArgusListens++] = s;
962 } else {
963 snprintf(errbuf, 1024, "%s: ArgusEstablishListen: listen() failure", ArgusProgramName);
964 }
965 break;
966
967 case SOCK_DGRAM:
968 retn = 0;
969 break;
970 }
971 } else {
972 snprintf(errbuf, 256, "%s: ArgusEstablishListen: bind() error", ArgusProgramName);
973 }
974 } else
975 snprintf(errbuf, 256, "%s: ArgusEstablishListen: fcntl() error", ArgusProgramName);
976
977 if (retn == -1) {
978 close (s);
979 s = -1;
980 }
981
982 } else
983 snprintf(errbuf, 256, "%s: ArgusEstablishListen: socket() error", ArgusProgramName);
984
985 hp = hp->ai_next;
986
987 } while ((hp != NULL) && (retn == -1));
988
989 freeaddrinfo(host);
990 }
991 #else
992 struct sockaddr_in sin;
993 struct hostent *host;
994
995 sin.sin_addr.s_addr = INADDR_ANY;
996 if (baddr) {
997 #ifdef ARGUSDEBUG
998 ArgusDebug (1, "ArgusEstablishListen(%d, %s, %p)\n", port, baddr, errbuf);
999 #endif
1000 if ((host = gethostbyname (baddr)) != NULL) {
1001 if ((host->h_addrtype == AF_INET) && (host->h_length == 4)) {
1002 bcopy ((char *) *host->h_addr_list, (char *)&sin.sin_addr.s_addr, host->h_length);
1003 } else
1004 ArgusLog (LOG_ERR, "ArgusEstablishListen() unsupported bind address %s", baddr);
1005 } else
1006 ArgusLog (LOG_ERR, "ArgusEstablishListen() bind address %s error %s", baddr, strerror(errno));
1007 }
1008
1009 sin.sin_port = htons((u_short) port);
1010 sin.sin_family = AF_INET;
1011
1012 #ifdef ARGUSDEBUG
1013 ArgusDebug (1, "ArgusEstablishListen(%p, %p) binding: %d:%d\n", output, errbuf, sin.sin_addr.s_addr, port);
1014 #endif
1015
1016 if ((s = socket (AF_INET, SOCK_STREAM, 0)) != -1) {
1017 int flags = fcntl (s, F_GETFL, 0L);
1018 if ((fcntl (s, F_SETFL, flags | O_NDELAY)) >= 0) {
1019 int on = 1;
1020 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
1021 ArgusLog (LOG_INFO, "ArgusInitOutput: setsockopt set reuseaddr %s", strerror(errno));
1022
1023 if (!(bind (s, (struct sockaddr *)&sin, sizeof(sin)))) {
1024 if ((listen (s, ARGUS_MAXLISTEN)) >= 0) {
1025 output->ArgusLfd[output->ArgusListens++] = s;
1026 } else {
1027 close (s);
1028 s = -1;
1029 snprintf(errbuf, 1024, "%s: ArgusEstablishListen: listen() failure", ArgusProgramName);
1030 }
1031 } else {
1032 close (s);
1033 s = -1;
1034 snprintf(errbuf, 256, "%s: ArgusEstablishListen: bind() error", ArgusProgramName);
1035 }
1036 } else
1037 snprintf(errbuf, 256, "%s: ArgusEstablishListen: fcntl() error", ArgusProgramName);
1038 } else
1039 snprintf(errbuf, 256, "%s: ArgusEstablishListen: socket() error", ArgusProgramName);
1040 #endif
1041 if (ArgusBindAddrs) {
1042 if ((ArgusBindAddrs = (struct ArgusBindAddrStruct *)ArgusBindAddrs->nxt) != NULL) {
1043 baddr = ArgusBindAddrs->addr;
1044 } else
1045 baddr = NULL;
1046 }
1047
1048 } while (baddr != NULL);
1049 }
1050
1051 #ifdef ARGUSDEBUG
1052 ArgusDebug (2, "ArgusEstablishListen(%p, %p) returning %d\n", output, errbuf, s);
1053 #endif
1054
1055 return (s);
1056 }
1057
1058
1059 int ArgusAuthenticateClient (struct ArgusClientData *);
1060 #ifdef ARGUS_SASL
1061 static sasl_ssf_t extprops_ssf = 0;
1062 static char clienthost[NI_MAXHOST*2+1] = "[local]";
1063
1064 sasl_security_properties_t *mysasl_secprops(int);
1065 #endif
1066
1067
1068 void
ArgusCheckClientStatus(struct ArgusOutputStruct * output,int s)1069 ArgusCheckClientStatus (struct ArgusOutputStruct *output, int s)
1070 {
1071 struct sockaddr from;
1072 int len = sizeof (from), bytes;
1073 int fd;
1074
1075 #ifdef ARGUS_SASL
1076 #define SASL_SEC_MASK 0x0fff
1077 struct sockaddr_storage localaddr, remoteaddr;
1078 int retn, argus_have_addr = 0;
1079 char localhostname[1024];
1080 sasl_conn_t *conn = NULL;
1081
1082 socklen_t salen;
1083 sasl_security_properties_t *secprops = NULL;
1084 char localip[60], remoteip[60];
1085 #endif
1086
1087 if ((fd = accept (s, (struct sockaddr *)&from, (socklen_t *)&len)) > 0) {
1088 int flags = fcntl (fd, F_GETFL, 0L);
1089
1090 if ((fcntl (fd, F_SETFL, flags | O_NONBLOCK)) >= 0) {
1091 if (ArgusTcpWrapper (fd, &from) >= 0) {
1092
1093 if (output->ArgusClients && (output->ArgusClients->count < ARGUS_MAXLISTEN)) {
1094 struct ArgusClientData *client = (void *) ArgusCalloc (1, sizeof(struct ArgusClientData));
1095
1096 if (client == NULL)
1097 ArgusLog (LOG_ERR, "ArgusCheckClientStatus: ArgusCalloc %s", strerror(errno));
1098
1099 client->fd = fd;
1100 client->startime = output->ArgusGlobalTime;
1101 #ifdef ARGUSDEBUG
1102 ArgusDebug (2, "ArgusCheckClientStatus() new client\n");
1103 #endif
1104 if ((client->sock = ArgusNewSocket(fd)) == NULL)
1105 ArgusLog (LOG_ERR, "ArgusInitOutput: ArgusNewSocket error %s", strerror(errno));
1106
1107 if (output->ArgusInitMar != NULL)
1108 ArgusFree(output->ArgusInitMar);
1109
1110 if ((output->ArgusInitMar = ArgusGenerateInitialMar(output)) == NULL)
1111 ArgusLog (LOG_ERR, "ArgusCheckClientStatus: ArgusGenerateInitialMar error %s", strerror(errno));
1112
1113 #ifdef ARGUS_SASL
1114 #ifdef ARGUSDEBUG
1115 ArgusDebug (2, "ArgusCheckClientStatus: SASL enabled\n");
1116 #endif
1117 {
1118 char hbuf[NI_MAXHOST];
1119 int niflags;
1120 salen = sizeof(remoteaddr);
1121
1122 bzero(hbuf, sizeof(hbuf));
1123
1124 if (getpeername(fd, (struct sockaddr *)&remoteaddr, &salen) == 0 &&
1125 (remoteaddr.ss_family == AF_INET || remoteaddr.ss_family == AF_INET6)) {
1126 if (getnameinfo((struct sockaddr *)&remoteaddr, salen, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) == 0) {
1127 strncpy(clienthost, hbuf, sizeof(hbuf));
1128 } else {
1129 clienthost[0] = '\0';
1130 }
1131 niflags = NI_NUMERICHOST;
1132 #ifdef NI_WITHSCOPEID
1133 if (((struct sockaddr *)&remoteaddr)->sa_family == AF_INET6)
1134 niflags |= NI_WITHSCOPEID;
1135 #endif
1136 if (getnameinfo((struct sockaddr *)&remoteaddr, salen, hbuf, sizeof(hbuf), NULL, 0, niflags) != 0)
1137 strncpy(hbuf, "unknown", sizeof(hbuf));
1138
1139 sprintf(&clienthost[strlen(clienthost)], "[%s]", hbuf);
1140
1141 salen = sizeof(localaddr);
1142 if (getsockname(fd, (struct sockaddr *)&localaddr, &salen) == 0) {
1143 if(iptostring((struct sockaddr *)&remoteaddr, salen,
1144 remoteip, sizeof(remoteip)) == 0
1145 && iptostring((struct sockaddr *)&localaddr, salen,
1146 localip, sizeof(localip)) == 0) {
1147 argus_have_addr = 1;
1148 }
1149 }
1150 }
1151 }
1152
1153 gethostname(localhostname, 1024);
1154 if (!strchr (localhostname, '.')) {
1155 char domainname[256];
1156 strcat (localhostname, ".");
1157 if (getdomainname (domainname, 256)) {
1158 snprintf (&localhostname[strlen(localhostname)], 1024 - strlen(localhostname), "%s", domainname);
1159 }
1160 }
1161
1162 if ((retn = sasl_server_new("argus", NULL, NULL, localip, remoteip, NULL, 0,
1163 &client->sasl_conn)) != SASL_OK)
1164 ArgusLog (LOG_ERR, "ArgusCheckClientStatus: sasl_server_new failed %d", retn);
1165
1166 conn = client->sasl_conn;
1167
1168 /* set required security properties here */
1169
1170 if (extprops_ssf)
1171 sasl_setprop(conn, SASL_SSF_EXTERNAL, &extprops_ssf);
1172
1173 secprops = mysasl_secprops(0);
1174 sasl_setprop(conn, SASL_SEC_PROPS, secprops);
1175
1176
1177 /* set ip addresses */
1178 if (argus_have_addr) {
1179 sasl_setprop(conn, SASL_IPREMOTEPORT, remoteip);
1180 if (client->saslprops.ipremoteport != NULL)
1181 free(client->saslprops.ipremoteport);
1182 client->saslprops.ipremoteport = strdup(remoteip);
1183
1184 sasl_setprop(conn, SASL_IPLOCALPORT, localip);
1185 if (client->saslprops.iplocalport != NULL)
1186 free(client->saslprops.iplocalport);
1187 client->saslprops.iplocalport = strdup(localip);
1188 }
1189
1190 output->ArgusInitMar->argus_mar.status |= htonl(ARGUS_SASL_AUTHENTICATE);
1191 #endif
1192 len = ntohs(output->ArgusInitMar->hdr.len) * 4;
1193
1194 if ((bytes = write (client->fd, (char *) output->ArgusInitMar, len)) != len) {
1195 close (client->fd);
1196 ArgusLog (LOG_ALERT, "ArgusInitOutput: write(): %s", strerror(errno));
1197 } else {
1198 #ifdef ARGUSDEBUG
1199 ArgusDebug (2, "ArgusCheckClientStatus: wrote %d bytes to client\n", bytes);
1200 #endif
1201 }
1202
1203 #ifdef ARGUS_SASL
1204 if (ArgusMaxSsf > 0) {
1205 int flags = fcntl (fd, F_GETFL, 0);
1206
1207 fcntl (fd, F_SETFL, flags & ~O_NONBLOCK);
1208 if (ArgusAuthenticateClient (client)) {
1209 ArgusDeleteSocket(output, client);
1210 ArgusLog (LOG_ALERT, "ArgusCheckClientStatus: ArgusAuthenticateClient failed\n");
1211 } else {
1212 ArgusAddToQueue(output->ArgusClients, &client->qhdr, ARGUS_NOLOCK);
1213 fcntl (fd, F_SETFL, flags);
1214 }
1215
1216 } else {
1217 }
1218 #else
1219 ArgusAddToQueue(output->ArgusClients, &client->qhdr, ARGUS_NOLOCK);
1220 #endif
1221 } else {
1222 char buf[256];
1223 struct ArgusRecord *argus = (struct ArgusRecord *) &buf;
1224 if ((argus = ArgusGenerateRecord (output->ArgusModel, NULL, ARGUS_ERROR, (struct ArgusRecord *) &buf)) != NULL) {
1225 len = argus->hdr.len * 4;
1226 argus->hdr.len = ntohs(argus->hdr.len);
1227 argus->hdr.cause |= ARGUS_MAXLISTENEXCD;
1228 if (write (fd, (char *) argus, len) != len) {
1229 ArgusLog (LOG_ERR, "ArgusInitOutput: write(): %s", strerror(errno));
1230 } else {
1231 #ifdef ARGUSDEBUG
1232 ArgusDebug (2, "ArgusCheckClientStatus: wrote %d bytes to client fd %d\n", len, fd);
1233 #endif
1234 }
1235 close(fd);
1236 }
1237 }
1238
1239 } else {
1240 ArgusLog (LOG_WARNING, "ArgusCheckClientStatus: ArgusTcpWrapper rejects");
1241 close (fd);
1242 }
1243
1244 } else {
1245 ArgusLog (LOG_WARNING, "ArgusCheckClientStatus: fcntl: %s", strerror(errno));
1246 close (fd);
1247 }
1248
1249 } else
1250 ArgusLog (LOG_WARNING, "ArgusCheckClientStatus: accept: %s", strerror(errno));
1251
1252 #ifdef ARGUSDEBUG
1253 ArgusDebug (2, "ArgusCheckClientStatus() returning\n");
1254 #endif
1255 }
1256
1257
1258
1259 #define ARGUSMAXCLIENTCOMMANDS 6
1260 #define RADIUM_START 0
1261 #define RADIUM_DONE 1
1262 #define RADIUM_FILTER 2
1263 #define RADIUM_MODEL 3
1264 #define RADIUM_PROJECT 4
1265 #define RADIUM_FILE 5
1266
1267 char *ArgusClientCommands[ARGUSMAXCLIENTCOMMANDS] =
1268 {
1269 "START: ",
1270 "DONE: ",
1271 "FILTER: ",
1272 "MODEL: ",
1273 "PROJECT: ",
1274 "FILE: ",
1275 };
1276
1277
1278 int
ArgusCheckClientMessage(struct ArgusOutputStruct * output,struct ArgusClientData * client)1279 ArgusCheckClientMessage (struct ArgusOutputStruct *output, struct ArgusClientData *client)
1280 {
1281 int retn = 0, cnt = 0, i, found, fd = client->fd;
1282 char buf[MAXSTRLEN], *ptr = buf;
1283 unsigned int value = 0;
1284
1285 #ifdef ARGUS_SASL
1286 const char *outputbuf = NULL;
1287 unsigned int outputlen = 0;
1288 #endif /* ARGUS_SASL */
1289
1290 bzero(buf, MAXSTRLEN);
1291
1292 if (value == 0)
1293 value = MAXSTRLEN;
1294
1295 if ((cnt = recv (fd, buf, value, 0)) <= 0) {
1296 if (cnt < 0) {
1297 #ifdef ARGUSDEBUG
1298 ArgusDebug (5, "ArgusCheckClientMessage (%p, %p) recv(%d) returned error %s\n", output, client, fd, strerror(errno));
1299 #endif
1300 return (-1);
1301
1302 } else {
1303 #ifdef ARGUSDEBUG
1304 ArgusDebug (5, "ArgusCheckClientMessage (%p, %p) recv(%d) returned %d bytes\n", output, client, fd, cnt);
1305 #endif
1306 return(-3);
1307 }
1308
1309 } else {
1310 #ifdef ARGUSDEBUG
1311 ArgusDebug (6, "ArgusCheckClientMessage (%p, %p) recv(%d) returned %d bytes\n", output, client, fd, cnt);
1312 #endif
1313 }
1314
1315 #ifdef ARGUS_SASL
1316 if ((client->sasl_conn)) {
1317 const int *ssfp;
1318 int result;
1319
1320 if ((result = sasl_getprop(client->sasl_conn, SASL_SSF, (const void **) &ssfp)) != SASL_OK)
1321 ArgusLog (LOG_ERR, "sasl_getprop: error %s\n", sasl_errdetail(client->sasl_conn));
1322
1323 if (ssfp && (*ssfp > 0)) {
1324 if (sasl_decode (client->sasl_conn, buf, cnt, &outputbuf, &outputlen) != SASL_OK) {
1325 ArgusLog (LOG_WARNING, "ArgusCheckClientMessage(%p, %d) sasl_decode (%p, %p, %d, %p, %d) failed",
1326 client, fd, client->sasl_conn, buf, cnt, &outputbuf, outputlen);
1327 return(-1);
1328 } else {
1329 #ifdef ARGUSDEBUG
1330 ArgusDebug (6, "ArgusCheckClientMessage (%p, %p) sasl_decode(%d) returned %d bytes\n", output, client, fd, outputlen);
1331 #endif
1332 }
1333 if (outputlen > 0) {
1334 if (outputlen < MAXSTRLEN) {
1335 bzero (buf, MAXSTRLEN);
1336 bcopy (outputbuf, buf, outputlen);
1337 cnt = outputlen;
1338 } else
1339 ArgusLog (LOG_ERR, "ArgusCheckClientMessage(%p, %d) sasl_decode returned %d bytes\n", client, fd, outputlen);
1340
1341 } else {
1342 return (0);
1343 }
1344 }
1345 }
1346 #endif /* ARGUS_SASL */
1347
1348 #ifdef ARGUSDEBUG
1349 ArgusDebug (2, "ArgusCheckClientMessage (%p, %p) read '%s' from remote\n", output, client, ptr);
1350 #endif
1351
1352 for (i = 0, found = 0; i < ARGUSMAXCLIENTCOMMANDS; i++) {
1353 if (!(strncmp (ptr, ArgusClientCommands[i], strlen(ArgusClientCommands[i])))) {
1354 found++;
1355 switch (i) {
1356 case RADIUM_START: client->ArgusClientStart++; retn = 0; break;
1357 case RADIUM_DONE: retn = -4; break;
1358 case RADIUM_FILTER: {
1359 char *reply = NULL;
1360 reply = ArgusFilterCompile (&client->ArgusNFFcode, &ptr[7], 1);
1361 if (reply == NULL) {
1362 retn = -2;
1363 if ((cnt = send (fd, "ER", 2, 0)) != 2) {
1364 #ifdef ARGUSDEBUG
1365 ArgusDebug (4, "ArgusCheckClientMessage: send error %s\n", strerror(errno));
1366 #endif
1367 }
1368 #ifdef ARGUSDEBUG
1369 ArgusDebug (3, "ArgusCheckClientMessage: ArgusFilter filter error: %s\n", &ptr[7]);
1370 #endif
1371 } else
1372 if (strcmp(reply, "OK")) {
1373 retn = -3;
1374 if ((cnt = send (fd, reply, 2, 0)) != 2) {
1375 #ifdef ARGUSDEBUG
1376 ArgusDebug (4, "ArgusCheckClientMessage: send error %s\n", strerror(errno));
1377 #endif
1378 }
1379 } else {
1380
1381 #ifdef ARGUSDEBUG
1382 char buf[MAXSTRLEN];
1383 bzero(buf, MAXSTRLEN);
1384 nff_dump(&client->ArgusNFFcode, buf, MAXSTRLEN, 1);
1385 ArgusDebug (3, "ArgusInitOutput: ArgusFilterCompile returned: \n%s\n", buf);
1386 #endif
1387 client->ArgusFilterInitialized++;
1388 if ((cnt = send (fd, "OK", 2, 0)) != 2) {
1389 retn = -3;
1390 #ifdef ARGUSDEBUG
1391 ArgusDebug (4, "ArgusCheckClientMessage: send error %s\n", strerror(errno));
1392 #endif
1393 } else {
1394 retn = 0;
1395 #ifdef ARGUSDEBUG
1396 ArgusDebug (4, "ArgusCheckClientMessage: ArgusFilter %s initialized.\n", &ptr[7]);
1397 #endif
1398 }
1399 }
1400 break;
1401 }
1402
1403 case RADIUM_PROJECT:
1404 case RADIUM_MODEL:
1405 break;
1406
1407 case RADIUM_FILE: {
1408 #ifdef ARGUSDEBUG
1409 ArgusDebug (6, "ArgusCheckClientMessage: ArgusFile %s initialized.\n", &ptr[6]);
1410 #endif
1411 retn = 0;
1412 }
1413 break;
1414
1415 default:
1416 ArgusLog (LOG_WARNING, "ArgusCheckClientMessage: received %s", ptr);
1417 break;
1418 }
1419
1420 break;
1421 }
1422 }
1423
1424 if (!found)
1425 ArgusLog (LOG_WARNING, "ArgusCheckClientMessage: received %s", ptr);
1426
1427 #ifdef ARGUSDEBUG
1428 ArgusDebug (5, "ArgusCheckClientMessage: returning %d\n", retn);
1429 #endif
1430
1431 return (retn);
1432 }
1433
1434
1435 struct ArgusRecord *
ArgusGenerateInitialMar(struct ArgusOutputStruct * output)1436 ArgusGenerateInitialMar (struct ArgusOutputStruct *output)
1437 {
1438 struct ArgusSourceStruct *ArgusSrc, *aSrc;
1439 struct ArgusRecord *retn;
1440 struct timeval now;
1441 int x, done;
1442
1443 if ((retn = (struct ArgusRecord *) ArgusCalloc (1, sizeof(struct ArgusRecord))) == NULL)
1444 ArgusLog (LOG_ERR, "ArgusGenerateInitialMar(%p) ArgusCalloc error %s\n", output, strerror(errno));
1445
1446 retn->hdr.type = ARGUS_MAR | ARGUS_VERSION;
1447 retn->hdr.cause = ARGUS_START;
1448 retn->hdr.len = sizeof(struct ArgusRecord) / 4;
1449
1450 retn->argus_mar.argusid = ARGUS_COOKIE;
1451 retn->argus_mar.thisid = getArgusID(ArgusSourceTask);
1452
1453 switch (getArgusIDType(ArgusSourceTask)) {
1454 case ARGUS_TYPE_STRING: retn->argus_mar.status |= ARGUS_IDIS_STRING; break;
1455 case ARGUS_TYPE_INT: retn->argus_mar.status |= ARGUS_IDIS_INT; break;
1456 case ARGUS_TYPE_IPV4: retn->argus_mar.status |= ARGUS_IDIS_IPV4; break;
1457 }
1458
1459 retn->argus_mar.startime.tv_sec = output->ArgusStartTime.tv_sec;
1460 retn->argus_mar.startime.tv_usec = output->ArgusStartTime.tv_usec;
1461
1462 gettimeofday (&now, 0L);
1463
1464 retn->argus_mar.now.tv_sec = now.tv_sec;
1465 retn->argus_mar.now.tv_usec = now.tv_usec;
1466
1467 retn->argus_mar.major_version = VERSION_MAJOR;
1468 retn->argus_mar.minor_version = VERSION_MINOR;
1469 retn->argus_mar.reportInterval = getArgusFarReportInterval(output->ArgusModel)->tv_sec;
1470 retn->argus_mar.argusMrInterval = getArgusMarReportInterval(output)->tv_sec;
1471
1472 if ((ArgusSrc = output->ArgusSrc) != NULL) {
1473 for (x = 0, done = 0; x < ARGUS_MAXINTERFACE && !done; x++) {
1474 if ((aSrc = ArgusSrc->srcs[x]) != NULL) {
1475 if (aSrc->ArgusInterface[0].ArgusLocalNet != 0) {
1476 retn->argus_mar.localnet = aSrc->ArgusInterface[0].ArgusLocalNet;
1477 retn->argus_mar.netmask = aSrc->ArgusInterface[0].ArgusNetMask;
1478 done = 1;
1479 }
1480 }
1481 }
1482 }
1483
1484 retn->argus_mar.nextMrSequenceNum = output->ArgusOutputSequence;
1485 retn->argus_mar.record_len = -1;
1486
1487 #if defined(_LITTLE_ENDIAN)
1488 ArgusHtoN(retn);
1489 #endif
1490
1491 #ifdef ARGUSDEBUG
1492 ArgusDebug (4, "ArgusGenerateInitialMar() returning\n");
1493 #endif
1494
1495 return (retn);
1496 }
1497
1498 // The supplemental mar record is designed to extend the descriptions of the sensors, their inputs,
1499 // providing interfaces, names, interface types, extended argus identifiers (> 4 bytes),
1500 // and stats, if appropriate,
1501 //
1502 // This will be the way we provide long argus id's, IPv6, ethernet, and long strings.
1503 //
1504 // Minimally it should provide the argusid, used in all records, and the list of input descriptions,
1505 // as well as the extended argus id itself.
1506
1507
1508 struct ArgusRecordStruct *
ArgusGenerateSupplementalMarRecord(struct ArgusOutputStruct * output,unsigned char status)1509 ArgusGenerateSupplementalMarRecord (struct ArgusOutputStruct *output, unsigned char status)
1510 {
1511 struct ArgusRecordStruct *retn = NULL;
1512 struct ArgusRecord *rec = NULL;
1513
1514 while ((retn = (struct ArgusRecordStruct *) ArgusMallocListRecord (sizeof(*retn))) == NULL) {
1515 if (output && output->ArgusInputList) {
1516 if ((retn = (struct ArgusRecordStruct *) ArgusPopFrontList(output->ArgusInputList, ARGUS_LOCK)) != NULL) {
1517 ArgusFreeListRecord (retn);
1518 } else
1519 break;
1520 } else
1521 break;
1522 }
1523
1524 if (retn) {
1525 struct ArgusSourceStruct *ArgusSrc = NULL, *aSrc = NULL;
1526 struct timeval now;
1527
1528 memset(retn, 0, sizeof(*retn));
1529
1530 retn->hdr.type = ARGUS_MAR | ARGUS_VERSION;
1531 retn->hdr.cause = ARGUS_SUPPLEMENTAL;
1532 retn->hdr.len = (sizeof(struct ArgusMarSupStruct)/4) + 1; // have size for one interface, and add as you go
1533
1534 rec = (struct ArgusRecord *) &retn->canon;
1535 rec->hdr = retn->hdr;
1536
1537 rec->argus_sup.argusid = getArgusID(ArgusSourceTask);
1538
1539 switch (getArgusIDType(ArgusSourceTask)) {
1540 case ARGUS_TYPE_STRING: rec->argus_sup.status |= ARGUS_IDIS_STRING; break;
1541 case ARGUS_TYPE_INT: rec->argus_sup.status |= ARGUS_IDIS_INT; break;
1542 case ARGUS_TYPE_IPV4: rec->argus_sup.status |= ARGUS_IDIS_IPV4; break;
1543 }
1544
1545 gettimeofday (&now, 0L);
1546
1547 rec->argus_sup.startime.tv_sec = output->ArgusLastMarUpdateTime.tv_sec;
1548 rec->argus_sup.startime.tv_usec = output->ArgusLastMarUpdateTime.tv_usec;
1549
1550 rec->argus_sup.now.tv_sec = now.tv_sec;
1551 rec->argus_sup.now.tv_usec = now.tv_usec;
1552
1553 if ((ArgusSrc = output->ArgusSrc) != NULL) {
1554 int x;
1555 for (x = 0; x < ARGUS_MAXINTERFACE; x++) {
1556 if ((aSrc = ArgusSrc->srcs[x]) != NULL) {
1557 if (aSrc->ArgusInterface[0].ArgusPd != NULL) {
1558 int i;
1559 rec->argus_mar.interfaceType = pcap_datalink(aSrc->ArgusInterface[0].ArgusPd);
1560 rec->argus_mar.interfaceStatus = getArgusInterfaceStatus(aSrc);
1561
1562 rec->argus_mar.pktsRcvd = 0;
1563 rec->argus_mar.bytesRcvd = 0;
1564 rec->argus_mar.dropped = 0;
1565
1566 for (i = 0; i < ARGUS_MAXINTERFACE; i++) {
1567 rec->argus_mar.pktsRcvd += aSrc->ArgusInterface[i].ArgusTotalPkts -
1568 aSrc->ArgusInterface[i].ArgusLastPkts;
1569 rec->argus_mar.bytesRcvd += aSrc->ArgusInterface[i].ArgusTotalBytes -
1570 aSrc->ArgusInterface[i].ArgusLastBytes;
1571 rec->argus_mar.dropped += aSrc->ArgusInterface[i].ArgusStat.ps_drop -
1572 aSrc->ArgusInterface[i].ArgusLastDrop;
1573
1574 aSrc->ArgusInterface[i].ArgusLastPkts = aSrc->ArgusInterface[i].ArgusTotalPkts;
1575 aSrc->ArgusInterface[i].ArgusLastDrop = aSrc->ArgusInterface[i].ArgusStat.ps_drop;
1576 aSrc->ArgusInterface[i].ArgusLastBytes = aSrc->ArgusInterface[i].ArgusTotalBytes;
1577 }
1578 }
1579 }
1580 }
1581 }
1582 }
1583
1584 #ifdef ARGUSDEBUG
1585 ArgusDebug (4, "ArgusGenerateStatusMar(%p, %d) returning 0x%x", output, status, retn);
1586 #endif
1587
1588 return (retn);
1589 }
1590
1591
1592 struct ArgusRecordStruct *
ArgusGenerateStatusMarRecord(struct ArgusOutputStruct * output,unsigned char status)1593 ArgusGenerateStatusMarRecord (struct ArgusOutputStruct *output, unsigned char status)
1594 {
1595 struct ArgusRecordStruct *retn = NULL;
1596 struct ArgusRecord *rec = NULL;
1597
1598 while ((retn = (struct ArgusRecordStruct *) ArgusMallocListRecord (sizeof(*retn))) == NULL) {
1599 if (output && output->ArgusInputList) {
1600 if ((retn = (struct ArgusRecordStruct *) ArgusPopFrontList(output->ArgusInputList, ARGUS_LOCK)) != NULL) {
1601 ArgusFreeListRecord (retn);
1602 } else
1603 break;
1604 } else
1605 break;
1606 }
1607
1608 if (retn) {
1609 extern int ArgusAllocTotal, ArgusFreeTotal, ArgusAllocBytes;
1610 struct ArgusSourceStruct *ArgusSrc = NULL, *aSrc = NULL;
1611 struct timeval now;
1612
1613 memset(retn, 0, sizeof(*retn));
1614
1615 retn->hdr.type = ARGUS_MAR | ARGUS_VERSION;
1616 retn->hdr.cause = status;
1617 retn->hdr.len = (sizeof(struct ArgusMarStruct)/4) + 1;
1618
1619 rec = (struct ArgusRecord *) &retn->canon;
1620
1621 rec->hdr = retn->hdr;
1622 rec->argus_mar.argusid = getArgusID(ArgusSourceTask);
1623 switch (getArgusIDType(ArgusSourceTask)) {
1624 case ARGUS_TYPE_STRING: rec->argus_mar.status |= ARGUS_IDIS_STRING; break;
1625 case ARGUS_TYPE_INT: rec->argus_mar.status |= ARGUS_IDIS_INT; break;
1626 case ARGUS_TYPE_IPV4: rec->argus_mar.status |= ARGUS_IDIS_IPV4; break;
1627 }
1628
1629 gettimeofday (&now, 0L);
1630
1631 rec->argus_mar.startime.tv_sec = output->ArgusLastMarUpdateTime.tv_sec;
1632 rec->argus_mar.startime.tv_usec = output->ArgusLastMarUpdateTime.tv_usec;
1633
1634 rec->argus_mar.now.tv_sec = now.tv_sec;
1635 rec->argus_mar.now.tv_usec = now.tv_usec;
1636
1637 rec->argus_mar.major_version = VERSION_MAJOR;
1638 rec->argus_mar.minor_version = VERSION_MINOR;
1639 rec->argus_mar.reportInterval = getArgusFarReportInterval(output->ArgusModel)->tv_sec;
1640 rec->argus_mar.argusMrInterval = getArgusMarReportInterval(ArgusOutputTask)->tv_sec;
1641
1642 rec->argus_mar.localnet = output->ArgusSrc->ArgusInterface[0].ArgusLocalNet;
1643 rec->argus_mar.netmask = output->ArgusSrc->ArgusInterface[0].ArgusNetMask;
1644
1645 rec->argus_mar.nextMrSequenceNum = output->ArgusOutputSequence;
1646 rec->argus_mar.record_len = -1;
1647
1648 if ((ArgusSrc = output->ArgusSrc) != NULL) {
1649 int x;
1650 for (x = 0; x < ARGUS_MAXINTERFACE; x++) {
1651 if ((aSrc = ArgusSrc->srcs[x]) != NULL) {
1652 if (aSrc->ArgusInterface[0].ArgusPd != NULL) {
1653 int i;
1654 rec->argus_mar.interfaceType = pcap_datalink(aSrc->ArgusInterface[0].ArgusPd);
1655 rec->argus_mar.interfaceStatus = getArgusInterfaceStatus(aSrc);
1656
1657 rec->argus_mar.pktsRcvd = 0;
1658 rec->argus_mar.bytesRcvd = 0;
1659 rec->argus_mar.dropped = 0;
1660
1661 for (i = 0; i < ARGUS_MAXINTERFACE; i++) {
1662 rec->argus_mar.pktsRcvd += aSrc->ArgusInterface[i].ArgusTotalPkts -
1663 aSrc->ArgusInterface[i].ArgusLastPkts;
1664 rec->argus_mar.bytesRcvd += aSrc->ArgusInterface[i].ArgusTotalBytes -
1665 aSrc->ArgusInterface[i].ArgusLastBytes;
1666 rec->argus_mar.dropped += aSrc->ArgusInterface[i].ArgusStat.ps_drop -
1667 aSrc->ArgusInterface[i].ArgusLastDrop;
1668
1669 aSrc->ArgusInterface[i].ArgusLastPkts = aSrc->ArgusInterface[i].ArgusTotalPkts;
1670 aSrc->ArgusInterface[i].ArgusLastDrop = aSrc->ArgusInterface[i].ArgusStat.ps_drop;
1671 aSrc->ArgusInterface[i].ArgusLastBytes = aSrc->ArgusInterface[i].ArgusTotalBytes;
1672 }
1673 }
1674 }
1675 }
1676 }
1677
1678 rec->argus_mar.records = output->ArgusTotalRecords - output->ArgusLastRecords;
1679 output->ArgusLastRecords = output->ArgusTotalRecords;
1680
1681 rec->argus_mar.flows = output->ArgusModel->ArgusTotalNewFlows - output->ArgusModel->ArgusLastNewFlows;
1682 output->ArgusModel->ArgusLastNewFlows = output->ArgusModel->ArgusTotalNewFlows;
1683
1684 if (output->ArgusModel && output->ArgusModel->ArgusStatusQueue)
1685 rec->argus_mar.queue = output->ArgusModel->ArgusStatusQueue->count;
1686 else
1687 rec->argus_mar.queue = 0;
1688
1689 if (output->ArgusOutputList)
1690 rec->argus_mar.output = output->ArgusOutputList->count;
1691 else
1692 rec->argus_mar.output = 0;
1693
1694 rec->argus_mar.clients = output->ArgusClients->count;
1695
1696 rec->argus_mar.bufs = ArgusAllocTotal - ArgusFreeTotal;
1697 rec->argus_mar.bytes = ArgusAllocBytes;
1698 rec->argus_mar.suserlen = getArgusUserDataLen(ArgusModel);
1699 rec->argus_mar.duserlen = getArgusUserDataLen(ArgusModel);
1700
1701 }
1702
1703 #ifdef ARGUSDEBUG
1704 ArgusDebug (4, "ArgusGenerateStatusMarRecord(%p, %d) returning 0x%x", output, status, retn);
1705 #endif
1706
1707 return (retn);
1708 }
1709
1710
1711 struct timeval *
getArgusMarReportInterval(struct ArgusOutputStruct * output)1712 getArgusMarReportInterval(struct ArgusOutputStruct *output) {
1713 return (&output->ArgusMarReportInterval);
1714 }
1715
1716
1717 #include <ctype.h>
1718 #include <math.h>
1719
1720 void
setArgusMarReportInterval(struct ArgusOutputStruct * output,char * value)1721 setArgusMarReportInterval(struct ArgusOutputStruct *output, char *value)
1722 {
1723 struct timeval *tvp = getArgusMarReportInterval(output);
1724
1725 struct timeval ovalue, now;
1726 double thisvalue = 0.0, iptr, fptr;
1727 int ivalue = 0;
1728 char *ptr = NULL;;
1729
1730 if (tvp != NULL) {
1731 ovalue = *tvp;
1732 tvp->tv_sec = 0;
1733 tvp->tv_usec = 0;
1734 } else {
1735 ovalue.tv_sec = 0;
1736 ovalue.tv_usec = 0;
1737 }
1738
1739 if (((ptr = strchr (value, '.')) != NULL) || isdigit((int)*value)) {
1740 if (ptr != NULL) {
1741 thisvalue = atof(value);
1742 } else {
1743 if (isdigit((int)*value)) {
1744 ivalue = atoi(value);
1745 thisvalue = ivalue * 1.0;
1746 }
1747 }
1748
1749 fptr = modf(thisvalue, &iptr);
1750
1751 tvp->tv_sec = iptr;
1752 tvp->tv_usec = fptr * ARGUS_FRACTION_TIME;
1753
1754 gettimeofday(&now, 0L);
1755 #if defined(ARGUS_NANOSECONDS)
1756 now.tv_usec *= 1000;
1757 #endif
1758 output->ArgusReportTime.tv_sec = now.tv_sec + tvp->tv_sec;
1759 output->ArgusReportTime.tv_usec = tvp->tv_usec;
1760
1761 } else
1762 *tvp = ovalue;
1763
1764 #ifdef ARGUSDEBUG
1765 ArgusDebug (4, "setArgusMarReportInterval(%s) returning\n", value);
1766 #endif
1767 }
1768
1769
1770 #if defined HAVE_TCP_WRAPPER
1771
1772 #if defined(HAVE_SYSLOG_H)
1773 #include <syslog.h>
1774 #endif
1775
1776 #include <tcpd.h>
1777
1778 #if !defined(MAXPATHNAMELEN)
1779 #define MAXPATHNAMELEN BUFSIZ
1780 #endif
1781
1782 #define PARANOID 1
1783 #define KILL_IP_OPTIONS 1
1784 #define HOSTS_ACCESS 1
1785
1786 int allow_severity = LOG_INFO; /* run-time adjustable */
1787 int deny_severity = LOG_WARNING; /* ditto */
1788
1789 void fix_options(struct request_info *);
1790
1791 #endif
1792
1793 int
ArgusTcpWrapper(int fd,struct sockaddr * from)1794 ArgusTcpWrapper (int fd, struct sockaddr *from)
1795 {
1796 #if defined(HAVE_TCP_WRAPPER)
1797 int retn = 0;
1798 struct request_info request;
1799
1800 /*
1801 * Find out the endpoint addresses of this conversation. Host name
1802 * lookups and double checks will be done on demand.
1803 */
1804
1805 request_init(&request, RQ_DAEMON, ArgusProgramName, RQ_FILE, STDIN_FILENO, 0);
1806 request.fd = fd;
1807 fromhost(&request);
1808
1809 /*
1810 * Optionally look up and double check the remote host name. Sites
1811 * concerned with security may choose to refuse connections from hosts
1812 * that pretend to have someone elses host name.
1813 */
1814
1815 #ifdef PARANOID
1816 if (STR_EQ(eval_hostname(request.client), paranoid)) {
1817 ArgusLog (deny_severity, "refused connect from %s", eval_client(&request));
1818 if (request.sink)
1819 request.sink(request.fd);
1820 return -1;
1821 }
1822 #endif
1823
1824 /*
1825 * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
1826 * socket options at the IP level. They do so for a good reason.
1827 * Unfortunately, we cannot use this with SunOS 4.1.x because the
1828 * getsockopt() system call can panic the system.
1829 */
1830
1831 #if defined(KILL_IP_OPTIONS)
1832 fix_options(&request);
1833 #endif /* KILL_IP_OPTIONS */
1834
1835 /*
1836 * Find out and verify the remote host name. Sites concerned with
1837 * security may choose to refuse connections from hosts that pretend to
1838 * have someone elses host name.
1839 */
1840
1841 #ifdef HOSTS_ACCESS
1842 if (!hosts_access(&request)) {
1843 ArgusLog (deny_severity, "refused connect from %s", eval_client(&request));
1844 if (request.sink)
1845 request.sink(request.fd);
1846 return -1;
1847 } else
1848 #endif
1849
1850 /* Report remote client */
1851 ArgusLog (allow_severity, "connect from %s", eval_client(&request));
1852 return (retn);
1853
1854 #else
1855 return (1);
1856 #endif /* HAVE_TCP_WRAPPER */
1857 }
1858
1859
1860 #if defined(ARGUS_SASL)
1861 /* This creates a structure that defines the allowable
1862 * security properties
1863 */
1864 #define PROT_BUFSIZE 4096
1865 sasl_security_properties_t *
mysasl_secprops(int flags)1866 mysasl_secprops(int flags)
1867 {
1868 static sasl_security_properties_t ret;
1869
1870 bzero((char *)&ret, sizeof(ret));
1871
1872 ret.maxbufsize = PROT_BUFSIZE;
1873 ret.min_ssf = ArgusMinSsf; /* minimum allowable security strength */
1874 ret.max_ssf = ArgusMaxSsf; /* maximum allowable security strength */
1875
1876 ret.security_flags = flags;
1877
1878 ret.property_names = NULL;
1879 ret.property_values = NULL;
1880
1881 return &ret;
1882 }
1883
1884 int
iptostring(const struct sockaddr * addr,socklen_t addrlen,char * out,unsigned outlen)1885 iptostring(const struct sockaddr *addr, socklen_t addrlen, char *out, unsigned outlen)
1886 {
1887 char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
1888 int niflags;
1889
1890 if(!addr || !out) {
1891 errno = EINVAL;
1892 return -1;
1893 }
1894
1895 niflags = NI_NUMERICHOST | NI_NUMERICSERV;
1896 #ifdef NI_WITHSCOPEID
1897 if (addr->sa_family == AF_INET6)
1898 niflags |= NI_WITHSCOPEID;
1899 #endif
1900 if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
1901 niflags) != 0) {
1902 errno = EINVAL;
1903 return -1;
1904 }
1905
1906 if(outlen < strlen(hbuf) + strlen(pbuf) + 2) {
1907 errno = ENOMEM;
1908 return -1;
1909 }
1910
1911 snprintf(out, outlen, "%s;%s", hbuf, pbuf);
1912
1913 return 0;
1914 }
1915 #endif
1916