X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fanalysisd%2Ftestrule.c;fp=src%2Fanalysisd%2Ftestrule.c;h=c36d8ecf5e57c6aaac90c520890020e99df13563;hp=db769f771f6dcf57ee591644c161f9d5d53f9a99;hb=301048b51990573e58a30dc4a5bb4ec285cad554;hpb=914feba5d54f979cd5d7e69c349c3d01f630042a diff --git a/src/analysisd/testrule.c b/src/analysisd/testrule.c index db769f7..c36d8ec 100755 --- a/src/analysisd/testrule.c +++ b/src/analysisd/testrule.c @@ -1,11 +1,11 @@ -/* @(#) $Id: testrule.c,v 1.7 2009/08/25 11:30:57 dcid Exp $ */ +/* @(#) $Id$ */ /* Copyright (C) 2009 Trend Micro Inc. * All rights reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public - * License (version 3) as published by the FSF - Free Software + * License (version 2) as published by the FSF - Free Software * Foundation. * * License details at the LICENSE file included with OSSEC or @@ -27,6 +27,8 @@ #define ARGV0 "ossec-testrule" #endif + + #include "shared.h" #include "alerts/alerts.h" @@ -42,13 +44,14 @@ #include "config.h" #include "rules.h" #include "stats.h" + #include "eventinfo.h" #include "analysisd.h" /** Internal Functions **/ -void OS_ReadMSG(int m_queue); +void OS_ReadMSG(int m_queue, char *ut_str); RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node); @@ -60,6 +63,7 @@ int GlobalConf(char * cfgfile); /* For rules */ void Rules_OP_CreateRules(); +void Lists_OP_CreateLists(); int Rules_OP_ReadRules(char * cfgfile); int _setlevels(RuleNode *node, int nnode); int AddHash_Rule(RuleNode *node); @@ -94,7 +98,10 @@ int SetDecodeXML(); */ int main(int argc, char **argv) { + int t_config = 0; int c = 0, m_queue = 0; + char *ut_str = NULL; + char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; @@ -108,20 +115,30 @@ int main(int argc, char **argv) today = 0; prev_year = 0; full_output = 0; + alert_only = 0; + active_responses = NULL; memset(prev_month, '\0', 4); - while((c = getopt(argc, argv, "Vfdhu:g:D:c:")) != -1){ + while((c = getopt(argc, argv, "VatfdhU:u:g:D:c:")) != -1){ switch(c){ case 'V': print_version(); break; + case 't': + t_config = 1; + break; case 'h': help(ARGV0); break; case 'd': nowDebug(); break; + case 'U': + if(!optarg) + ErrorExit("%s: -U needs an argument",ARGV0); + ut_str = optarg; + break; case 'u': if(!optarg) ErrorExit("%s: -u needs an argument",ARGV0); @@ -141,6 +158,9 @@ int main(int argc, char **argv) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; + case 'a': + alert_only = 1; + break; case 'f': full_output = 1; break; @@ -152,6 +172,8 @@ int main(int argc, char **argv) } + + /* Reading configuration file */ if(GlobalConf(cfg) < 0) { @@ -184,45 +206,106 @@ int main(int argc, char **argv) ErrorExit(CHROOT_ERROR,ARGV0,dir); - - /* Reading decoders */ - OS_CreateOSDecoderList(); - if(!ReadDecodeXML("etc/decoder.xml")) + /* + * Anonymous Section: Load rules, decoders, and lists + * + * As lists require two pass loading of rules that make use of list lookups + * are created with blank database structs, and need to be filled in after + * completion of all rules and lists. + */ { - ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); - } + { /* Lad decders */ + /* Initializing the decoders list */ + OS_CreateOSDecoderList(); + + if(!Config.decoders) + { /* Legacy loading */ + /* Reading decoders */ + if(!ReadDecodeXML("etc/decoder.xml")) + { + ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); + } - c = ReadDecodeXML("etc/local_decoder.xml"); - if(!c) - { - if((c != -2)) - ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER); - } - SetDecodeXML(); + /* Reading local ones. */ + c = ReadDecodeXML("etc/local_decoder.xml"); + if(!c) + { + if((c != -2)) + ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER); + } + else + { + verbose("%s: INFO: Reading local decoder file.", ARGV0); + } + } + else + { /* New loaded based on file speified in ossec.conf */ + char **decodersfiles; + decodersfiles = Config.decoders; + while( decodersfiles && *decodersfiles) + { - - /* Creating the rules list */ - Rules_OP_CreateRules(); + verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles); + if(!ReadDecodeXML(*decodersfiles)) + ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles); + + free(*decodersfiles); + decodersfiles++; + } + } - - /* Reading the rules */ - { - char **rulesfiles; - rulesfiles = Config.includes; - while(rulesfiles && *rulesfiles) - { - debug1("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles); - if(Rules_OP_ReadRules(*rulesfiles) < 0) - ErrorExit(RULES_ERROR, ARGV0, *rulesfiles); - - free(*rulesfiles); - rulesfiles++; + /* Load decoders */ + SetDecodeXML(); + } + { /* Load Lists */ + /* Initializing the lists of list struct */ + Lists_OP_CreateLists(); + /* Load each list into list struct */ + { + char **listfiles; + listfiles = Config.lists; + while(listfiles && *listfiles) + { + verbose("%s: INFO: Reading loading the lists file: '%s'", ARGV0, *listfiles); + if(Lists_OP_LoadList(*listfiles) < 0) + ErrorExit(LISTS_ERROR, ARGV0, *listfiles); + free(*listfiles); + listfiles++; + } + free(Config.lists); + Config.lists = NULL; + } } + { /* Load Rules */ + /* Creating the rules list */ + Rules_OP_CreateRules(); + + /* Reading the rules */ + { + char **rulesfiles; + rulesfiles = Config.includes; + while(rulesfiles && *rulesfiles) + { + debug1("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles); + if(Rules_OP_ReadRules(*rulesfiles) < 0) + ErrorExit(RULES_ERROR, ARGV0, *rulesfiles); + + free(*rulesfiles); + rulesfiles++; + } - free(Config.includes); - Config.includes = NULL; + free(Config.includes); + Config.includes = NULL; + } + + /* Find all rules with that require list lookups and attache the + * the correct list struct to the rule. This keeps rules from having to + * search thought the list of lists for the correct file during rule evaluation. + */ + OS_ListLoadRules(); + } } - + /* Fixing the levels/accuracy */ { @@ -246,13 +329,18 @@ int main(int argc, char **argv) } + if(t_config == 1) + { + exit(0); + } + /* Start up message */ verbose(STARTUP_MSG, ARGV0, getpid()); /* Going to main loop */ - OS_ReadMSG(m_queue); + OS_ReadMSG(m_queue, ut_str); exit(0); @@ -265,10 +353,44 @@ int main(int argc, char **argv) * Main function. Receives the messages(events) * and analyze them all. */ -void OS_ReadMSG(int m_queue) +void OS_ReadMSG(int m_queue, char *ut_str) { int i; char msg[OS_MAXSTR +1]; + int exit_code = 0; + char *ut_alertlevel = NULL; + char *ut_rulelevel = NULL; + char *ut_decoder_name = NULL; + + if(ut_str) + { + /* XXX Break apart string */ + ut_rulelevel = ut_str; + ut_alertlevel = strchr(ut_rulelevel, ':'); + if(!ut_alertlevel) + { + ErrorExit("%s: -U requires the matching format to be " + "\"::\"", ARGV0); + } + else + { + *ut_alertlevel = '\0'; + ut_alertlevel++; + } + ut_decoder_name = strchr(ut_alertlevel, ':'); + if(!ut_decoder_name) + { + ErrorExit("%s: -U requires the matching format to be " + "\"::\"", ARGV0); + } + else + { + *ut_decoder_name = '\0'; + ut_decoder_name++; + } + } + + RuleInfoDetail *last_info_detail; Eventinfo *lf; @@ -287,6 +409,8 @@ void OS_ReadMSG(int m_queue) } + __crt_ftell = 1; + /* Getting currently time before starting */ c_time = time(NULL); @@ -296,6 +420,7 @@ void OS_ReadMSG(int m_queue) memset(msg, '\0', OS_MAXSTR +1); + if(!alert_only) print_out("%s: Type one log per line.\n", ARGV0); @@ -312,12 +437,12 @@ void OS_ReadMSG(int m_queue) /* Fixing the msg. */ - strncpy(msg, "1:a:", 5); + snprintf(msg, 15, "1:stdin:"); /* Receive message from queue */ - if(fgets(msg +4, OS_MAXSTR, stdin)) + if(fgets(msg +8, OS_MAXSTR, stdin)) { RuleNode *rulenode_pt; @@ -331,13 +456,13 @@ void OS_ReadMSG(int m_queue) /* Make sure we ignore blank lines. */ - if(strlen(msg) < 6) + if(strlen(msg) < 10) { continue; } - print_out("\n"); + if(!alert_only)print_out("\n"); /* Default values for the log info */ @@ -379,7 +504,7 @@ void OS_ReadMSG(int m_queue) #ifdef TESTRULE - if(full_output) + if(full_output && !alert_only) print_out("\n**Rule debugging:"); #endif @@ -413,10 +538,18 @@ void OS_ReadMSG(int m_queue) } #ifdef TESTRULE + if(!alert_only) + { + char *(ruleinfodetail_text[])={"Text","Link","CVE","OSVDB","BUGTRACKID"}; print_out("\n**Phase 3: Completed filtering (rules)."); print_out(" Rule id: '%d'", currently_rule->sigid); print_out(" Level: '%d'", currently_rule->level); print_out(" Description: '%s'",currently_rule->comment); + for (last_info_detail = currently_rule->info_details; last_info_detail != NULL; last_info_detail = last_info_detail->next) + { + print_out(" Info - %s: '%s'", ruleinfodetail_text[last_info_detail->type], last_info_detail->data); + } + } #endif @@ -472,7 +605,15 @@ void OS_ReadMSG(int m_queue) /* Log the alert if configured to ... */ if(currently_rule->alert_opts & DO_LOGALERT) { - print_out("**Alert to be generated.\n\n"); + if(alert_only) + { + OS_LogOutput(lf); + __crt_ftell++; + } + else + { + print_out("**Alert to be generated.\n\n"); + } } @@ -512,6 +653,29 @@ void OS_ReadMSG(int m_queue) }while((rulenode_pt = rulenode_pt->next) != NULL); + if(ut_str) + { + /*setup exit code if we are doing unit testing*/ + char holder[1024]; + holder[1] = '\0'; + exit_code = 3; + if(strcasecmp(ut_decoder_name, lf->decoder_info->name) == 0) + { + exit_code--; + snprintf(holder, 1023, "%d", currently_rule->sigid); + if(strcasecmp(ut_rulelevel, holder) == 0) + { + exit_code--; + snprintf(holder, 1023, "%d", currently_rule->level); + if(strcasecmp(ut_alertlevel, holder) == 0) + { + exit_code--; + printf("%d\n",exit_code); + } + } + } + } + /* Only clear the memory if the eventinfo was not * added to the stateful memory @@ -523,12 +687,14 @@ void OS_ReadMSG(int m_queue) } else { - exit(0); + exit(exit_code); } } + exit(exit_code); return; } /* EOF */ +