コード例 #1
0
ファイル: argus_auth.c プロジェクト: IFGHou/argus
int
ArgusAuthenticate (struct ARGUS_INPUT *input)
{
   int retn = 0;

   if (ArgusInitializeAuthentication(input)) {
#ifdef ARGUS_SASL
      int fd = input->fd;

      if ((input->in = fdopen(fd, "r")) == NULL)
         ArgusLog (LOG_ERR, "ArgusAuthenticate(0x%x) fdopen in failed %s", strerror(errno));

      if ((input->out = fdopen(fd, "w")) == NULL)
         ArgusLog (LOG_ERR, "ArgusAuthenticate(0x%x) fdopen out failed %s", strerror(errno));

      if ((retn = RaSaslNegotiate(input->in, input->out, input->sasl_conn)) == SASL_OK)
         retn = 1;
      else
         retn = 0;
#endif 
   }

#ifdef ARGUSDEBUG
   ArgusDebug (2, "ArgusAuthenticate (0x%x) returning %d\n", input, retn);
#endif 

   return (retn);
}
コード例 #2
0
ファイル: rasort.c プロジェクト: hbock/argus-clients
void
ArgusClientInit (struct ArgusParserStruct *parser)
{
   struct ArgusModeStruct *mode;
   int i = 0, x = 0;

   if (!(parser->RaInitialized)) {
      (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
      (void) signal (SIGTERM, (void (*)(int)) RaParseComplete);
      (void) signal (SIGQUIT, (void (*)(int)) RaParseComplete);
      (void) signal (SIGINT,  (void (*)(int)) RaParseComplete);

      parser->RaWriteOut = 0;

      if (parser->vflag)
         ArgusReverseSortDir++;

      if ((ArgusSorter = ArgusNewSorter()) == NULL)
         ArgusLog (LOG_ERR, "ArgusClientInit ArgusNewSorter error %s", strerror(errno));

      bzero ((char *) ArgusSorter->ArgusSortAlgorithms, sizeof(ArgusSorter->ArgusSortAlgorithms));
      ArgusSorter->ArgusSortAlgorithms[0] = ArgusSortAlgorithmTable[0];
 
      if ((mode = parser->ArgusModeList) != NULL) {
         while (mode) {
            if (!(strcmp ("replace", mode->mode))) {
               ArgusSorter->ArgusReplaceMode++;
               if ((parser->ArgusWfileList != NULL) && (!(ArgusListEmpty(parser->ArgusWfileList)))) {
                  ArgusLog (LOG_ERR, "replace mode and -w option are incompatible\n");
               }
            }
 
            mode = mode->nxt;
         }
      }

      if ((mode = parser->ArgusMaskList) != NULL) {
         while (mode) {
            for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
               if (!strncmp (ArgusSortKeyWords[x], mode->mode, strlen(ArgusSortKeyWords[x]))) {
                  ArgusSorter->ArgusSortAlgorithms[i++] = ArgusSortAlgorithmTable[x];
                  break;
               }
            }

            if (x == MAX_SORT_ALG_TYPES)
               ArgusLog (LOG_ERR, "sort syntax error. \'%s\' not supported", mode->mode);

            mode = mode->nxt;
         }
      }

      parser->RaInitialized++;
   }
}
コード例 #3
0
ファイル: argus_auth.c プロジェクト: IFGHou/argus
int
ArgusInitializeAuthentication (struct ARGUS_INPUT *input)
{
   int retn = 1;

#ifdef ARGUS_SASL
   struct sockaddr_in localaddr, remoteaddr;
   int salen, fd = input->fd;
   char *localhostname = NULL;

   if ((retn = sasl_client_init(RaCallBacks)) != SASL_OK)
      ArgusLog (LOG_ERR, "ArgusInitializeAuthentication() sasl_client_init %d", retn);

   localhostname = ArgusCalloc (1, 1024);
   gethostname(localhostname, 1024);
   if (!strchr (localhostname, '.')) {
      strcat (localhostname, ".");
      getdomainname (&localhostname[strlen(localhostname)], 1024 - strlen(localhostname));
   }

   if ((retn = sasl_client_new("argus", localhostname, NULL, SASL_SECURITY_LAYER, &input->sasl_conn)) != SASL_OK)
      ArgusLog (LOG_ERR, "ArgusInitializeAuthentication() sasl_client_new %d", retn);
   
   /* set external properties here
   sasl_setprop(input->sasl_conn, SASL_SSF_EXTERNAL, &extprops); */
   
   /* set required security properties here
   sasl_setprop(input->sasl_conn, SASL_SEC_PROPS, &secprops); */
   
   /* set ip addresses */
   salen = sizeof(localaddr);
   if (getsockname(fd, (struct sockaddr *)&localaddr, &salen) < 0)
      perror("getsockname");

   salen = sizeof(remoteaddr); 
   if (getpeername(fd, (struct sockaddr *)&remoteaddr, &salen) < 0)
      perror("getpeername");

   if ((retn = sasl_setprop(input->sasl_conn, SASL_IP_LOCAL, &localaddr)) != SASL_OK)
      ArgusLog (LOG_ERR, "ArgusInitializeAuthentication() error setting localaddr %d", retn);

   if ((retn = sasl_setprop(input->sasl_conn, SASL_IP_REMOTE, &remoteaddr)) != SASL_OK)
      ArgusLog (LOG_ERR, "ArgusInitializeAuthentication() error setting remoteaddr %d", retn);

   retn = 1;
#endif 

#ifdef ARGUSDEBUG
   ArgusDebug (2, "ArgusInitializeAuthentication () returning %d\n", retn);
#endif 

   return (retn);
}
コード例 #4
0
ファイル: rasort.c プロジェクト: hbock/argus-clients
void
RaArgusInputComplete (struct ArgusInput *input)
{
   struct ArgusRecordStruct *nsr;
   struct ArgusWfileStruct *wfile = NULL;
   char buf[MAXSTRLEN];
   int count, label, i, fd;
 
   if (ArgusSorter->ArgusReplaceMode) {
      if (ArgusParser->ArgusWfileList == NULL)
         ArgusParser->ArgusWfileList = ArgusNewList();
 
      if ((count = ArgusSorter->ArgusRecordQueue->count) > 0) {
         if (!(ArgusParser->ArgusRandomSeed))
            srandom(ArgusParser->ArgusRandomSeed);

         srandom (ArgusParser->ArgusRealTime.tv_usec);
         label = random() % 100000;
 
         bzero(buf, sizeof(buf));
         snprintf (buf, MAXSTRLEN, "%s.tmp%d", input->filename, label);
         if ((fd = open(buf, O_CREAT|O_EXCL, input->statbuf.st_mode)) < 0)
            ArgusLog (LOG_ERR, "open %s error: %s", buf, strerror(errno));
 
         close(fd);
 
         if ((wfile = (struct ArgusWfileStruct *) ArgusCalloc (1, sizeof (*wfile))) != NULL) {
            ArgusPushFrontList(ArgusParser->ArgusWfileList, (struct ArgusListRecord *)wfile, ARGUS_NOLOCK);
            wfile->filename  = strdup(buf);
 
         } else
            ArgusLog (LOG_ERR, "setArgusWfile, ArgusCalloc %s", strerror(errno));
 
         ArgusSortQueue (ArgusSorter, ArgusSorter->ArgusRecordQueue);
 
         for (i = 0, count = ArgusSorter->ArgusRecordQueue->count; i < count; i++)
            RaSendArgusRecord ((struct ArgusRecordStruct *)ArgusSorter->ArgusRecordQueue->array[i]);
 
         while ((nsr = (struct ArgusRecordStruct *) ArgusPopQueue(ArgusSorter->ArgusRecordQueue, ARGUS_NOLOCK)) != NULL)
            ArgusDeleteRecordStruct(ArgusParser, nsr);
 
         rename (wfile->filename, input->filename);
         fclose (wfile->fd);
         ArgusDeleteList (ArgusParser->ArgusWfileList, ARGUS_WFILE_LIST);
         ArgusParser->ArgusWfileList = NULL;
 
         if (ArgusParser->Vflag)
            ArgusLog(LOG_INFO, "file %s sorted", input->filename);
      }
   }
}
コード例 #5
0
ファイル: ralabel.c プロジェクト: hbock/argus-clients
char *
RaProcessAddress (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus, unsigned int *addr, int type)
{
   struct ArgusLabelerStruct *labeler = NULL;
   struct RaAddressStruct *raddr;
   char *retn = NULL;

   if ((labeler = parser->ArgusLabeler) == NULL)
      ArgusLog (LOG_ERR, "RaProcessAddress: No labeler\n");

   if (labeler->ArgusAddrTree != NULL) {
      switch (type) {
         case ARGUS_TYPE_IPV4: {
            struct RaAddressStruct node;
            bzero ((char *)&node, sizeof(node));

            node.addr.type = AF_INET;
            node.addr.len = 4;
            node.addr.addr[0] = *addr;
            node.addr.masklen = 32;

            if ((raddr = RaFindAddress (parser, labeler->ArgusAddrTree[AF_INET], &node, ARGUS_LONGEST_MATCH)) != NULL)
               retn = raddr->label;
            else {
               char *ptr, *sptr;
               if ((ptr = ArgusGetName(ArgusParser, (u_char *)addr)) != NULL) {
                  if ((sptr = strrchr(ptr, '.')) != NULL) {
                     if (strlen(++sptr) == 2) {
                        if (!isdigit((int)*sptr)) {
                           char *tptr = sptr;
                           int i, ch;
                           for (i = 0; i < 2; i++, tptr++) {
                              ch = *tptr;
                              if (islower(ch)) {
                                 ch = toupper(ch);
                                 *tptr = ch;
                              }
                           }
                           retn = sptr;
                        }
                     }
                  }
               }
            }

            break;
         }

         case ARGUS_TYPE_IPV6:
            break;
      }
   }

#ifdef ARGUSDEBUG
   ArgusDebug (5, "RaProcessAddress (0x%x, 0x%x, 0x%x, %d) returning %s\n", parser, argus, addr, type, retn);
#endif

   return (retn);
}
コード例 #6
0
ファイル: ralabel.c プロジェクト: hbock/argus-clients
void
ArgusClientInit (struct ArgusParserStruct *parser)
{
   struct ArgusModeStruct *mode = NULL;
   parser->RaWriteOut = 0;

   if (!(parser->RaInitialized)) {
      (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);

      if ((parser->ArgusLabeler = ArgusNewLabeler(parser, 0L)) == NULL)
         ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewLabeler error");

      if (parser->ArgusFlowModelFile) {
         RaLabelParseResourceFile (parser, parser->ArgusLabeler, parser->ArgusFlowModelFile);
         parser->ArgusFlowModelFile = NULL;
      }

      if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL)) == NULL)
         ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");

      if ((mode = parser->ArgusModeList) != NULL) {
         while (mode) {
            if (!(strncasecmp (mode->mode, "noprune", 7))) {
               parser->ArgusLabeler->prune = 0;
            } else
            if (!(strncasecmp (mode->mode, "addr", 4))) {
               if (parser->ArgusFlowModelFile) {
                  if (!(RaReadAddressConfig (parser, parser->ArgusLabeler, parser->ArgusFlowModelFile) > 0))
                     ArgusLog (LOG_ERR, "ArgusNewLabeler: RaReadAddressConfig error");
               }
            } else
            if ((!(strncasecmp (mode->mode, "debug.tree", 10))) ||
                (!(strncasecmp (mode->mode, "debug", 5)))) {
               parser->ArgusLabeler->RaPrintLabelTreeMode = ARGUS_TREE;
               if (parser->ArgusLabeler &&  parser->ArgusLabeler->ArgusAddrTree)
                  RaPrintLabelTree (parser->ArgusLabeler, parser->ArgusLabeler->ArgusAddrTree[AF_INET], 0, 0);
               exit(0);
            }

            mode = mode->nxt;
         }
      }

      parser->RaInitialized++;
   }
}
コード例 #7
0
ファイル: ArgusAuth.c プロジェクト: IFGHou/argus
int
ArgusGetSaslString(FILE *f, char *buf, int buflen)
{
   unsigned int len = -1;
   char *s = NULL;
   int result;

   if (ferror(f))
      clearerr(f);

   if ((s = fgets(buf, buflen, f)) != NULL) {
      switch (*buf) {
         case 'C': {
            if (!(strncmp(buf, "C: ", 3))) {
               buf[strlen(buf) - 1] = '\0';

               result = sasl_decode64(buf + 3, (unsigned) strlen(buf + 3), buf, buflen, &len);

               if (result != SASL_OK)
                  ArgusLog (LOG_ERR, "ArgusGetSaslString: sasl_decode64 error");

               buf[len] = '\0';
            } else
               ArgusLog (LOG_ERR, "ArgusGetSaslString: error %s", strerror(errno));

            break;
         }

         default:
         case 'N': 
            len = -1;
            break;
      }
   }

#ifdef ARGUSDEBUG
   ArgusDebug (2, "ArgusGetSaslString(0x%x, 0x%x, %d) %s", f, buf, buflen, buf);
#endif 
   return len;
}
コード例 #8
0
ファイル: rasort.c プロジェクト: hbock/argus-clients
void
RaProcessRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *ns)
{
   struct ArgusRecordStruct *tns = NULL;

   switch (ns->hdr.type & 0xF0) {
      case ARGUS_MAR:
      case ARGUS_EVENT: {
         break;
      }

      case ARGUS_NETFLOW:
      case ARGUS_FAR: {
         if ((tns = ArgusCopyRecordStruct(ns)) == NULL)
            ArgusLog (LOG_ERR, "RaProcessRecord: ArgusCopyRecordStruct(0x%x) error\n", ns);

         ArgusAddToQueue (ArgusSorter->ArgusRecordQueue, &tns->qhdr, ARGUS_NOLOCK);
         break;
      }
   }
}
コード例 #9
0
void
ArgusClientInit (struct ArgusParserStruct *parser)
{
   struct ArgusModeStruct *mode = NULL;
   int correct = 1;
   parser->RaWriteOut = 0;

   if (!(parser->RaInitialized)) {
      (void) signal (SIGHUP,  (void (*)(int)) RaParseComplete);
      (void) signal (SIGTERM, (void (*)(int)) RaParseComplete);
      (void) signal (SIGQUIT, (void (*)(int)) RaParseComplete);
      (void) signal (SIGINT,  (void (*)(int)) RaParseComplete);

      if ((mode = parser->ArgusModeList) != NULL) {
         while (mode) {
            if (!(strncasecmp (mode->mode, "correct", 7)))
               correct = 1;
            if (!(strncasecmp (mode->mode, "nocorrect", 9)))
               correct = 0;
            if (!(strncasecmp (mode->mode, "rmon", 4)))
               parser->RaMonMode++;
            if (!(strncasecmp (mode->mode, "norep", 5)))
               parser->RaAgMode++;
            if (!(strncasecmp (mode->mode, "ind", 3)))
               ArgusProcessFileIndependantly = 1;
            if (!(strncasecmp (mode->mode, "replace", 7))) {
               ArgusProcessFileIndependantly = 1;
               parser->ArgusReplaceMode++;
               if ((parser->ArgusWfileList != NULL) && (!(ArgusListEmpty(parser->ArgusWfileList)))) {
                  ArgusLog (LOG_ERR, "replace mode and -w option are incompatible\n");
               }
            }
            mode = mode->nxt;
         }
      }

      if ((parser->ArgusMaskList) == NULL)
         parser->ArgusReverse = 1;
      else
         parser->ArgusReverse = 0;

      if (parser->ArgusFlowModelFile) {
         if ((parser->ArgusAggregator = ArgusParseAggregator(parser, parser->ArgusFlowModelFile, NULL)) == NULL)
            ArgusLog (LOG_ERR, "ArgusClientInit: ArgusParseAggregator error");
        
      } else 
         if ((parser->ArgusAggregator = ArgusNewAggregator(parser, NULL)) == NULL)
            ArgusLog (LOG_ERR, "ArgusClientInit: ArgusNewAggregator error");

      if (correct == 0) {
         if (parser->ArgusAggregator->correct != NULL)
            free(parser->ArgusAggregator->correct);
         parser->ArgusAggregator->correct = NULL;
      } else {
         if (parser->ArgusAggregator->correct != NULL)
            free(parser->ArgusAggregator->correct);
         parser->ArgusAggregator->correct = strdup("yes");
      }
      
      if (parser->Hstr)
         if (!(ArgusHistoMetricParse (parser, parser->ArgusAggregator)))
            usage ();

      if (parser->vflag)
         ArgusReverseSortDir++;

      if ((parser->ArgusWfileList != NULL) && (!(ArgusListEmpty(parser->ArgusWfileList))))
         parser->nflag = 2;

      parser->RaInitialized++;
      parser->RaParseCompleting = 0;
      parser->ArgusLastRecordTime = 0;
      parser->RaSortedInput = 1;
   }
}
コード例 #10
0
void
RaProcessThisRecord (struct ArgusParserStruct *parser, struct ArgusRecordStruct *argus)
{

   struct ArgusAggregatorStruct *agg = parser->ArgusAggregator;
   struct ArgusHashStruct *hstruct = NULL;
   int found = 0;

   while (agg && !found) {
      int retn = 0, fretn = -1, lretn = -1;
      if (agg->filterstr) {
         struct nff_insn *fcode = agg->filter.bf_insns;
         fretn = ArgusFilterRecord (fcode, argus);
      }

      if (agg->labelstr) {
         struct ArgusLabelStruct *label;
         if (((label = (void *)argus->dsrs[ARGUS_LABEL_INDEX]) != NULL)) {
            if (regexec(&agg->lpreg, label->l_un.label, 0, NULL, 0))
               lretn = 0;
            else
               lretn = 1;
         } else
            lretn = 0;
      }

      retn = (lretn < 0) ? ((fretn < 0) ? 1 : fretn) : ((fretn < 0) ? lretn : (lretn && fretn));

      if (retn != 0) {
         struct ArgusRecordStruct *tns, *ns = ArgusCopyRecordStruct(argus);

         if ((agg->rap = RaFlowModelOverRides(agg, ns)) == NULL)
            agg->rap = agg->drap;

         ArgusGenerateNewFlow(agg, ns);

         if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
            ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));

         if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
            struct ArgusFlow *flow = (struct ArgusFlow *) ns->dsrs[ARGUS_FLOW_INDEX];
            if (!parser->RaMonMode && parser->ArgusReverse) {
               int tryreverse = 0;

               if (flow != NULL) {
                  if (agg->correct != NULL)
                     tryreverse = 1;

                  switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
                     case ARGUS_TYPE_IPV4: {
                        switch (flow->ip_flow.ip_p) {
                           case IPPROTO_ESP:
                              tryreverse = 0;
                              break;
                        }
                        break;
                     }
                     case ARGUS_TYPE_IPV6: {
                        switch (flow->ipv6_flow.ip_p) {
                           case IPPROTO_ESP:
                              tryreverse = 0;
                              break;
                        }
                        break;
                     }
                  }
               } else
                  tryreverse = 0;

               if (tryreverse) {
                  if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
                     ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));

                  if ((tns = ArgusFindRecord(agg->htable, hstruct)) == NULL) {
                     switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
                        case ARGUS_TYPE_IPV4: {
                           switch (flow->ip_flow.ip_p) {
                              case IPPROTO_ICMP: {
                                 struct ArgusICMPFlow *icmpFlow = &flow->flow_un.icmp;

                                 if (ICMP_INFOTYPE(icmpFlow->type)) {
                                    switch (icmpFlow->type) {
                                       case ICMP_ECHO:
                                       case ICMP_ECHOREPLY:
                                          icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
                                          if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
                                             tns = ArgusFindRecord(agg->htable, hstruct);
                                          icmpFlow->type = (icmpFlow->type == ICMP_ECHO) ? ICMP_ECHOREPLY : ICMP_ECHO;
                                          if (tns)
                                             ArgusReverseRecord (ns);
                                          break;

                                       case ICMP_ROUTERADVERT:
                                       case ICMP_ROUTERSOLICIT:
                                          icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
                                          if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
                                             tns = ArgusFindRecord(agg->htable, hstruct);
                                          icmpFlow->type = (icmpFlow->type == ICMP_ROUTERADVERT) ? ICMP_ROUTERSOLICIT : ICMP_ROUTERADVERT;
                                          if (tns)
                                             ArgusReverseRecord (ns);
                                          break;

                                       case ICMP_TSTAMP:
                                       case ICMP_TSTAMPREPLY:
                                          icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
                                          if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
                                             tns = ArgusFindRecord(agg->htable, hstruct);
                                          icmpFlow->type = (icmpFlow->type == ICMP_TSTAMP) ? ICMP_TSTAMPREPLY : ICMP_TSTAMP;
                                          if (tns)
                                             ArgusReverseRecord (ns);
                                          break;

                                       case ICMP_IREQ:
                                       case ICMP_IREQREPLY:
                                          icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
                                          if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
                                             tns = ArgusFindRecord(agg->htable, hstruct);
                                          icmpFlow->type = (icmpFlow->type == ICMP_IREQ) ? ICMP_IREQREPLY : ICMP_IREQ;
                                          if (tns)
                                             ArgusReverseRecord (ns);
                                          break;

                                       case ICMP_MASKREQ:
                                       case ICMP_MASKREPLY:
                                          icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
                                          if ((hstruct = ArgusGenerateReverseHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) != NULL)
                                             tns = ArgusFindRecord(agg->htable, hstruct);
                                          icmpFlow->type = (icmpFlow->type == ICMP_MASKREQ) ? ICMP_MASKREPLY : ICMP_MASKREQ;
                                          if (tns)
                                             ArgusReverseRecord (ns);
                                          break;
                                    }
                                 }
                                 break;
                              }
                           }
                        }
                     }
                     if ((hstruct = ArgusGenerateHashStruct(agg, ns, (struct ArgusFlow *)&agg->fstruct)) == NULL)
                        ArgusLog (LOG_ERR, "RaProcessThisRecord: ArgusGenerateHashStruct error %s", strerror(errno));

                  } else {
                     switch (flow->hdr.argus_dsrvl8.qual & 0x1F) {
                        case ARGUS_TYPE_IPV4: {
                           switch (flow->ip_flow.ip_p) {
                              case IPPROTO_TCP: {
                                 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)ns->dsrs[ARGUS_NETWORK_INDEX];
                                 if (tcp != NULL) {
                                    struct ArgusTCPObject *ttcp = (struct ArgusTCPObject *)tns->dsrs[ARGUS_NETWORK_INDEX];
                                    if (ttcp != NULL) {
                                       if ((tcp->status & ARGUS_SAW_SYN) && !(ttcp->status & ARGUS_SAW_SYN)) {
                                          ArgusReverseRecord (tns);
                                       } else
                                          ArgusReverseRecord (ns);
                                    } else
                                       ArgusReverseRecord (ns);
                                 } else
                                    ArgusReverseRecord (ns);
                                 break;
                              }

                              default:
                                 ArgusReverseRecord (ns);
                                 break;
                           }
                        }
                        break;

                        case ARGUS_TYPE_IPV6: {
                           switch (flow->ipv6_flow.ip_p) {
                              case IPPROTO_TCP: {
                                 struct ArgusTCPObject *tcp = (struct ArgusTCPObject *)ns->dsrs[ARGUS_NETWORK_INDEX];
                                 if (tcp != NULL) {
                                    struct ArgusTCPObject *ttcp = (struct ArgusTCPObject *)tns->dsrs[ARGUS_NETWORK_INDEX];
                                    if (ttcp != NULL) {
                                       if ((tcp->status & ARGUS_SAW_SYN) && !(ttcp->status & ARGUS_SAW_SYN)) {
                                          ArgusReverseRecord (tns);
                                       } else
                                          ArgusReverseRecord (ns);
                                    } else
                                       ArgusReverseRecord (ns);
                                 } else
                                    ArgusReverseRecord (ns);
                                 break;
                              }

                              default:
                                 ArgusReverseRecord (ns);
                                 break;
                           }
                        }
                        break;

                        default:
                           ArgusReverseRecord (ns);
                     }
                  }
               }
            }
         }

         if (tns != NULL) {
            if (parser->Aflag) {
               if ((tns->status & RA_SVCTEST) != (ns->status & RA_SVCTEST)) {
                  RaSendArgusRecord(tns);
                  tns->status &= ~(RA_SVCTEST);
                  tns->status |= (ns->status & RA_SVCTEST);
               }
            }

            if (tns->status & ARGUS_RECORD_WRITTEN) {
               ArgusZeroRecord (tns);

            } else {
               if (agg->statusint || agg->idleint) {
                  double dur, nsst, tnsst, nslt, tnslt;

                  nsst  = ArgusFetchStartTime(ns);
                  tnsst = ArgusFetchStartTime(tns);
                  nslt  = ArgusFetchLastTime(ns);
                  tnslt = ArgusFetchLastTime(tns);

                  dur = ((tnslt > nslt) ? tnslt : nslt) - ((nsst < tnsst) ? nsst : tnsst); 
               
                  if (agg->statusint && (dur >= agg->statusint)) {
                     RaSendArgusRecord(tns);
                     ArgusZeroRecord(tns);
                  } else {
                     dur = ((nslt < tnsst) ? (tnsst - nslt) : ((tnslt < nsst) ? (nsst - tnslt) : 0.0));
                     if (agg->idleint && (dur >= agg->idleint)) {
                        RaSendArgusRecord(tns);
                        ArgusZeroRecord(tns);
                     }
                  }
               }
            }

            ArgusMergeRecords (agg, tns, ns);
            ArgusRemoveFromQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
            ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
            ArgusDeleteRecordStruct(parser, ns);
            agg->status |= ARGUS_AGGREGATOR_DIRTY;

         } else {
            tns = ns;
            tns->htblhdr = ArgusAddHashEntry (agg->htable, tns, hstruct);
            ArgusAddToQueue (agg->queue, &tns->qhdr, ARGUS_NOLOCK);
            agg->status |= ARGUS_AGGREGATOR_DIRTY;
         }

         if (agg->cont)
            agg = agg->nxt;
         else
            found++;

      } else
         agg = agg->nxt;
   }
}
コード例 #11
0
void
RaParseComplete (int sig)
{
   struct ArgusModeStruct *mode = NULL;
   int i = 0, x = 0, nflag = ArgusParser->eNflag;
   struct ArgusInput *file = ArgusParser->ArgusCurrentFile;
   char buf[MAXSTRLEN];
   int label;

   if (sig >= 0) {
      if (!(ArgusParser->RaParseCompleting++)) {
         struct ArgusAggregatorStruct *agg = ArgusParser->ArgusAggregator;

         ArgusParser->RaParseCompleting += sig;

         if (ArgusParser->ArgusReplaceMode && file) {

            if (!(ArgusParser->ArgusRandomSeed))
               srandom(ArgusParser->ArgusRandomSeed);

            srandom (ArgusParser->ArgusRealTime.tv_usec);
            label = random() % 100000;

            bzero(buf, sizeof(buf));
            snprintf (buf, MAXSTRLEN, "%s.tmp%d", file->filename, label);

            setArgusWfile(ArgusParser, buf, NULL);
         }

         while (agg != NULL) {
            if (agg->queue->count) {
               struct ArgusRecordStruct *argus;

               if (!(ArgusSorter))
                  if ((ArgusSorter = ArgusNewSorter(ArgusParser)) == NULL)
                     ArgusLog (LOG_ERR, "RaParseComplete: ArgusNewSorter error %s", strerror(errno));

               if ((mode = ArgusParser->ArgusMaskList) != NULL) {
                  while (mode) {
                     for (x = 0; x < MAX_SORT_ALG_TYPES; x++) {
                        if (!strncmp (ArgusSortKeyWords[x], mode->mode, strlen(ArgusSortKeyWords[x]))) {
                           ArgusSorter->ArgusSortAlgorithms[i++] = ArgusSortAlgorithmTable[x];
                           break;
                        }
                     }

                     mode = mode->nxt;
                  }
               }

               ArgusSortQueue (ArgusSorter, agg->queue);
       
               argus = ArgusCopyRecordStruct((struct ArgusRecordStruct *) agg->queue->array[0]);

               if (nflag == 0)
                  ArgusParser->eNflag = agg->queue->count;
               else
                  ArgusParser->eNflag = nflag > agg->queue->count ? agg->queue->count : nflag;

               for (i = 1; i < ArgusParser->eNflag; i++)
                  ArgusMergeRecords (agg, argus, (struct ArgusRecordStruct *)agg->queue->array[i]);

               ArgusParser->ns = argus;

               for (i = 0; i < ArgusParser->eNflag; i++) {
                  RaSendArgusRecord ((struct ArgusRecordStruct *) agg->queue->array[i]);
                  ArgusDeleteRecordStruct(ArgusParser, (struct ArgusRecordStruct *) agg->queue->array[i]);
               }

               ArgusDeleteRecordStruct(ArgusParser, ArgusParser->ns);
            }

            agg = agg->nxt;
         }

         if (ArgusParser->ArgusAggregator != NULL)
            ArgusDeleteAggregator(ArgusParser, ArgusParser->ArgusAggregator);

         if (ArgusParser->ArgusReplaceMode && file) {
            if (ArgusParser->ArgusWfileList != NULL) {
               struct ArgusWfileStruct *wfile = NULL;

               if ((wfile = (void *)ArgusParser->ArgusWfileList->start) != NULL) {
                  fflush (wfile->fd);
                  rename (wfile->filename, file->filename);
                  fclose (wfile->fd);
                  wfile->fd = NULL;
               }

               ArgusDeleteList(ArgusParser->ArgusWfileList, ARGUS_WFILE_LIST);
               ArgusParser->ArgusWfileList = NULL;

               if (ArgusParser->Vflag)
                  ArgusLog(LOG_INFO, "file %s aggregated", file->filename);
            }
         }

#ifdef ARGUSDEBUG
         ArgusDebug (2, "RaParseComplete(caught signal %d)\n", sig);
#endif
         switch (sig) {
            case SIGHUP:
            case SIGINT:
            case SIGTERM:
            case SIGQUIT: {
               struct ArgusWfileStruct *wfile = NULL;

               ArgusShutDown(sig);

               if (ArgusParser->ArgusWfileList != NULL) {
                  struct ArgusListObjectStruct *lobj = NULL;
                  int i, count = ArgusParser->ArgusWfileList->count;

                  if ((lobj = ArgusParser->ArgusWfileList->start) != NULL) {
                     for (i = 0; i < count; i++) {
                        if ((wfile = (struct ArgusWfileStruct *) lobj) != NULL) {
                           if (wfile->fd != NULL) {
#ifdef ARGUSDEBUG
                              ArgusDebug (2, "RaParseComplete: closing %s\n", wfile->filename);
#endif
                              fflush (wfile->fd);
                              fclose (wfile->fd);
                              wfile->fd = NULL;
                           }
                        }
                        lobj = lobj->nxt;
                     }
                  }
               }
               exit(0);
               break;
            }
         }
      }
   }

   ArgusParser->eNflag = nflag;

#ifdef ARGUSDEBUG
   ArgusDebug (6, "RaParseComplete(%d) done", sig);
#endif
}
コード例 #12
0
ファイル: ArgusUdt.c プロジェクト: bear6709/argus-3.0.6.1
void
ArgusUpdateUDToEState (struct ArgusModelerStruct *model, struct ArgusFlowStruct *flowstr, unsigned char *state)
{
   struct udtoe_header *udt = (struct udtoe_header *) model->ArgusThisUpHdr;
   u_char *nxtHdr = (u_char *)(udt + 1);

   if (STRUCTCAPTURED(model, *udt)) {
      model->ArgusThisLength -= sizeof(*udt);
      model->ArgusSnapLength -= sizeof(*udt);
      model->ArgusThisUpHdr = nxtHdr;

      if (*state == ARGUS_START) {

      } else {
         struct ArgusNetworkStruct *net = (struct ArgusNetworkStruct *) flowstr->dsrs[ARGUS_NETWORK_INDEX];

         struct ArgusUDTObjectMetrics *ArgusThisUdtMetric;

         if (model->ArgusThisDir) {
            ArgusThisUdtMetric = &net->net_union.udt.src;
         } else {
            ArgusThisUdtMetric = &net->net_union.udt.dst;
         }

         if ((flowstr->canon.metric.src.pkts + flowstr->canon.metric.dst.pkts) > 2)
            flowstr->timeout = ARGUS_IPTIMEOUT;

         switch (udt->un_udt.cntl.type & UDTOE_PACKET_MASK) {
            case UDTOE_CONTROL_PACKET: {
               struct udtoe_control_hdr *udtc = (void *) ((char *)udt + UDTOECONTROLPAD);
               unsigned char type = ((udtc->type & 0x7F) >> 3);

               model->ArgusThisLength -= 48;

               switch (type & UDTOE_CONTROL_TYPE_MASK) {
                  case UDTOE_CONTROL_HANDSHAKE: {
                     struct udt_control_handshake *hshake = (void *) (udtc + 1);
                     if (ntohl(hshake->version) == 4) {
                        ArgusThisUdtHshake = hshake;
                        hshake->version = ntohl(hshake->version);
                        hshake->socktype = ntohl(hshake->socktype);
                        hshake->initseq = ntohl(hshake->initseq);
                        hshake->psize = ntohl(hshake->psize);
                        hshake->wsize = ntohl(hshake->wsize);
                        hshake->conntype = ntohl(hshake->conntype);
                        hshake->sockid = ntohl(hshake->sockid);

                     } else {
//                      ArgusLog(LOG_ERR, "ArgusUpdateUDToEState: hshake version is %d", ntohl(hshake->version));
                     }
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_HANDSHAKE type %d seqNum %d size %d maxWin %d conn %d sockid 0x%x\n", 
                                flowstr, *state, hshake->socktype, hshake->initseq, hshake->psize, hshake->wsize, hshake->conntype, hshake->sockid);
#endif
                     break;
                  }

                  case UDTOE_CONTROL_KEEPALIVE: {
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_KEEPALIVE\n", flowstr, *state);
#endif
                     break;
                  }

                  case UDTOE_CONTROL_ACK: {
                     struct udt_control_ack *ack = (void *) (udtc + 1);
                     int len = model->ArgusThisLength/4;

                     if (len--) { ArgusThisUdtMetric->ack   = ntohl(ack->ackseqnum);
                     if (len--) { ArgusThisUdtMetric->rtt   = ntohl(ack->rtt);
                     if (len--) { ArgusThisUdtMetric->var   = ntohl(ack->var);
                     if (len--) { ArgusThisUdtMetric->bsize = ntohl(ack->bsize);
                                  if (ack->bsize == 0) {
                                     net->net_union.udt.status |= ARGUS_WINDOW_SHUT;
                                  }
                     if (len--) { ArgusThisUdtMetric->rate  = ntohl(ack->rate);
                     if (len--) { ArgusThisUdtMetric->lcap  = ntohl(ack->lcap); }}}}}}
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_ACK, sockid 0x%x ack = 0x%x\n", 
                         flowstr, *state, ntohl(udtc->sockid), net->net_union.udt.src.ack);
#endif
                     break;
                  }

                  case UDTOE_CONTROL_NAK: {
                     struct udt_control_nak *nak = (void *) (udtc + 1);
                     int num = 0, len = model->ArgusThisLength/4;
                     unsigned int *sptr = &nak->seqnum;
                     int i, fitem, sseq, eseq, range;
#ifdef ARGUSDEBUG
                     char buf[256];
                     *buf = '\0';
#endif
                     for (i = 0, fitem = 0; i < len; i++, sptr++) {
                        *sptr = ntohl(*sptr);
                        if (*sptr & 0x80000000) {
                           sseq = *sptr & 0x7FFFFFFF;
                           range = 1;
                        } else {
                           eseq = *sptr;
                           if (range) {
#ifdef ARGUSDEBUG
                              if (fitem++)
                                 sprintf(&buf[strlen(buf)], ",0x%x-0x%x", sseq, eseq);
                              else
                                 sprintf(&buf[strlen(buf)], "0x%x-0x%x", sseq, eseq);
#endif
                              num += (eseq - sseq) + 1;
                              range = 0;
                           } else {
#ifdef ARGUSDEBUG
                              if (fitem++)
                                 sprintf(&buf[strlen(buf)], ",0x%x", eseq);
                              else
                                 sprintf(&buf[strlen(buf)], "0x%x", eseq);
#endif
                              fitem++;
                              num++;
                           }
                        }
                     }
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_NAK, sockid 0x%x nak.comp[%d] num %d %s", 
                           flowstr, *state, ntohl(udtc->sockid), len, num, buf);
#endif
                     if (num)
                        ArgusThisUdtMetric->nacked += num;
                     break;
                  }

                  case UDTOE_CONTROL_CONGEST: {
                     net->net_union.udt.status |= ARGUS_ECN_CONGESTED;
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_CONGEST, sockid 0x%x", 
                           flowstr, *state, ntohl(udtc->sockid));
#endif
                     break;
                  }

                  case UDTOE_CONTROL_SHUTDOWN: {
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_SHUTDOWN\n", flowstr, *state);
#endif
                     break;
                  }
                  case UDTOE_CONTROL_ACKACK: {
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_ACKACK\n", flowstr, *state);
#endif
                     break;
                  }

                  case UDTOE_CONTROL_DROPREQ: {
                     struct udt_control_dropreq *drop = (void *)(udtc + 1);
                     if (drop->firstseqnum == 0)
                        ArgusLog(LOG_ERR, "drop request firstseqnum is 0");
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_DROPREQ\n", flowstr, *state);
#endif
                     break;
                  }

                  default: {
#ifdef ARGUSDEBUG
                     ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_CONTROL_UNKNOWN\n", flowstr, *state);
#endif
                     break;
                  }
               }
               break;
            }
/*
struct ArgusUDTObjectMetrics {
   struct ArgusTime lasttime;
   unsigned int seq, tstamp, ack, rtt, var, bsize, rate, lcap;
   int solo, first, middle, last, drops, retrans, nacked;
};

struct ArgusUDTObject {
   unsigned int state, status;
   struct udt_control_handshake hshake;
   struct ArgusUDTObjectMetrics src;
};
*/
            case UDT_DATA_PACKET: {
               struct udt_data_hdr *udtd = (void *) udt;
               unsigned int seqnum = ntohl(udtd->seqnum);
               unsigned int msgnum = ntohl(udtd->msgnum);
               unsigned int tstamp = ntohl(udtd->tstamp);
#ifdef ARGUSDEBUG
               unsigned int sockid = ntohl(udtd->sockid);
#endif
               int seq = ArgusThisUdtMetric->seq;
               int loss = 0;;

#define ARGUS_UDT_MSGTYPE	0xC0000000
#define ARGUS_UDT_SOLO_MSG	0xC0000000
#define ARGUS_UDT_FIRST_MSG	0x80000000
#define ARGUS_UDT_MIDDLE_MSG	0x00000000
#define ARGUS_UDT_LAST_MSG	0x40000000

               switch (msgnum & ARGUS_UDT_MSGTYPE) {
                  case ARGUS_UDT_SOLO_MSG:
                     ArgusThisUdtMetric->solo++;
                     break;
                  case ARGUS_UDT_FIRST_MSG:
                     ArgusThisUdtMetric->first++;
                     break;
                  case ARGUS_UDT_MIDDLE_MSG:
                     ArgusThisUdtMetric->middle++;
                     break;
                  case ARGUS_UDT_LAST_MSG:
                     ArgusThisUdtMetric->last++;
                     break;
               }
/*
               msgnum &= 0x1FFFFFFF;
*/
               if (seqnum == (seq + 1)) {
                  ArgusThisUdtMetric->lasttime.tv_sec  = model->ArgusGlobalTime.tv_sec;
                  ArgusThisUdtMetric->lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
                  ArgusThisUdtMetric->tstamp = tstamp;
                  ArgusThisUdtMetric->seq = seqnum;

               } else {
                  if (seq > 0) {
                     if (seqnum > (seq + 2)) {
                        loss = seqnum - (seq + 1);
                        ArgusThisUdtMetric->drops += loss;
                        net->net_union.udt.status |= ARGUS_PKTS_DROP;
                        ArgusThisUdtMetric->seq = seqnum;
                     } else {
                        if (seqnum != (seq + 1)) {
                           ArgusThisUdtMetric->retrans++;
                           net->net_union.udt.status |= ARGUS_PKTS_RETRANS;
                        } else {
                           ArgusThisUdtMetric->lasttime.tv_sec  = model->ArgusGlobalTime.tv_sec;
                           ArgusThisUdtMetric->lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
                           ArgusThisUdtMetric->tstamp = tstamp;
                           ArgusThisUdtMetric->seq = seqnum;
                        }
                     }

                  } else {
                     ArgusThisUdtMetric->lasttime.tv_sec  = model->ArgusGlobalTime.tv_sec;
                     ArgusThisUdtMetric->lasttime.tv_usec = model->ArgusGlobalTime.tv_usec;
                     ArgusThisUdtMetric->tstamp = tstamp;
                     ArgusThisUdtMetric->seq = seqnum;
                  }
               }

#ifdef ARGUSDEBUG
               ArgusDebug (4, "ArgusUpdateUDToEState(%p, %d) UDT_DATA_PACKET seq 0x%x msgnum 0x%x tstmp 0x%x sockid 0x%x loss %d\n", 
                                 flowstr, *state, seqnum, msgnum, tstamp, sockid, loss);
#endif
               break;
            }
         }
      }
   }
コード例 #13
0
ファイル: ArgusAuth.c プロジェクト: IFGHou/argus
int
ArgusAuthenticateClient (struct ArgusClientData *client)
{
   int retn = 1;

#ifdef ARGUS_SASL
   unsigned int rlen = 0;
   int len, mechnum = 0;
   char buf[8192], chosenmech[512];
   const char *data;
   sasl_conn_t *conn = NULL;

// int SASLOpts = (SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS);
   FILE *in, *out;

   conn = client->sasl_conn;

   if ((retn = sasl_listmech(conn, NULL, "{", ", ", "}", &data, &rlen, &mechnum)) != SASL_OK)
      ArgusLog (LOG_ERR, "ArgusAuthenticateClient: Error generating mechanism list");

   if ((in  = fdopen (client->fd, "r")) < 0)
      ArgusLog (LOG_ERR, "ArgusAuthenticateClient: fdopen() error %s", strerror(errno));

   if ((out = fdopen (client->fd, "w")) < 0)
      ArgusLog (LOG_ERR, "ArgusAuthenticateClient: fdopen() error %s", strerror(errno));

   ArgusSendSaslString (out, data, rlen, SASL_OK);

   if ((len = ArgusGetSaslString (in, chosenmech, sizeof(chosenmech))) <= 0)  {
#ifdef ARGUSDEBUG
      ArgusDebug (2, "ArgusAuthenticateClient: Error ArgusGetSaslString returned %d\n", len);
#endif
      return 0;
   }

   if ((len = ArgusGetSaslString (in, buf, sizeof(buf))) <= 0)  {
#ifdef ARGUSDEBUG
      ArgusDebug (2, "ArgusAuthenticateClient: Error ArgusGetSaslString returned %d\n", len);
#endif
      return 0;
   }

   if (*buf == 'Y') {
      if ((len = ArgusGetSaslString (in, buf, sizeof(buf))) <= 0)  {
#ifdef ARGUSDEBUG
         ArgusDebug (2, "ArgusAuthenticateClient: Error ArgusGetSaslString returned %d\n", len);
#endif
         return 0;
      }
      retn = sasl_server_start(conn, chosenmech, buf, len, &data, &rlen);

   } else {
      retn = sasl_server_start(conn, chosenmech, NULL, 0, &data, &rlen);
   }

   if ((retn != SASL_OK) && (retn != SASL_CONTINUE)) {
      sprintf (buf, "%s", sasl_errstring(retn, NULL, NULL));
#ifdef ARGUSDEBUG
      ArgusDebug (2, "ArgusAuthenticateClient: Error starting SASL negotiation");
#endif
      ArgusSendSaslString(out, buf, strlen(buf), retn);
      return 0;
   }

   while (retn == SASL_CONTINUE) {
      if (data) {
#ifdef ARGUSDEBUG
         ArgusDebug(2, "sending response length %d...\n", rlen);
#endif
         ArgusSendSaslString(out, data, rlen, retn);
      } else {
#ifdef ARGUSDEBUG
         ArgusDebug(2, "no data to send? ...\n");
#endif
      }

#ifdef ARGUSDEBUG
      ArgusDebug(2, "waiting for client reply...\n");
#endif
      len = ArgusGetSaslString(in, buf, sizeof(buf));

      if (len < 0) {
#ifdef ARGUSDEBUG
         ArgusDebug(2, "client disconnected ...\n");
#endif
         return 0;
      }

      retn = sasl_server_step(conn, buf, len, &data, &rlen);
      if ((retn != SASL_OK) && (retn != SASL_CONTINUE)) {
         sprintf (buf, "%s", sasl_errstring(retn, NULL, NULL));
#ifdef ARGUSDEBUG
         ArgusDebug(2, "Authentication failed %s\n", sasl_errstring(retn, NULL, NULL));
#endif
         ArgusSendSaslString(out, buf, strlen(buf), retn);
         return 0;
      }
   }

   if (retn == SASL_OK)
      ArgusSendSaslString(out, NULL, 0, SASL_OK);

#endif
#ifdef ARGUSDEBUG
   ArgusDebug (1, "ArgusAuthenticateClient() returning %d\n", retn);
#endif

   return (retn);
}
コード例 #14
0
ファイル: ArgusAuth.c プロジェクト: IFGHou/argus
int
ArgusSendSaslString(FILE *f, const char *s, int l, int mode)
{
   char *buf = NULL, *ptr = NULL, error[128];
   unsigned int al, len;
   int result, size, tsize;

   switch (mode) {
      case SASL_OK: {
         if ((s == NULL) || (l == 0)) {
            ptr = "D: ";
            tsize = 3;
            break;
         }
      }
      case SASL_CONTINUE: {
         ptr = "S: ";
         tsize = 3;
         break;
      }
      default: {
         sprintf (error, "E: [%d]", mode);
         ptr = error;
         tsize = strlen(error);
         break;
      }
   }

   if (ferror(f))
      clearerr(f);

   while ((size = fwrite(ptr, 1, tsize, f)) != tsize) {
      if (size >= 0) {
         tsize -= size;
         ptr += size;
      } else {
         if (ferror(f))
            ArgusLog (LOG_ERR, "ArgusSendSaslString: error %d", ferror(f));
      }
   }

   if (l > 0) {
      al = (((l / 3) + 1) * 4) + 1;

      if ((buf = malloc(al)) == NULL)
         ArgusLog (LOG_ERR, "malloc: error %s", strerror(errno));

      if ((ptr = buf) != NULL) {
         result = sasl_encode64(s, l, buf, al, &len);

         if (result == SASL_OK) {
            tsize = len;
            while ((size = fwrite(ptr, 1, tsize, f)) != tsize) {
               if (size >= 0) {
                  tsize -= size;
                  ptr += size;
               } else {
                  if (ferror(f))
                     ArgusLog (LOG_ERR, "ArgusSendSaslString: error %d", ferror(f));
               }
            }
         }
      }

      free(buf);
   }

   ptr = "\n";
   tsize = 1;
   while ((size = fwrite(ptr, 1, tsize, f)) != tsize) {
      if (size >= 0) {
         tsize -= size;
         ptr += size;
      } else {
         if (ferror(f))
            ArgusLog (LOG_ERR, "ArgusSendSaslString: error %d", ferror(f));
      }
   }

   fflush(f);

#ifdef ARGUSDEBUG
   ArgusDebug (2, "ArgusSendSaslString(0x%x, 0x%x, %d) %s", f, s, l, s);
#endif
   return len;
}