1 /* @(#) $Id: testrule.c,v 1.7 2009/08/25 11:30:57 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
11 * License details at the LICENSE file included with OSSEC or
12 * online at: http://www.ossec.net/en/licensing.html
17 * Available at http://www.ossec.net
22 * Responsible for correlation and log decoding.
27 #define ARGV0 "ossec-testrule"
32 #include "alerts/alerts.h"
33 #include "alerts/getloglocation.h"
34 #include "os_execd/execd.h"
36 #include "os_regex/os_regex.h"
37 #include "os_net/os_net.h"
41 #include "active-response.h"
45 #include "eventinfo.h"
46 #include "analysisd.h"
50 /** Internal Functions **/
51 void OS_ReadMSG(int m_queue);
52 RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node);
55 /** External functions prototypes (only called here) **/
58 int GlobalConf(char * cfgfile);
62 void Rules_OP_CreateRules();
63 int Rules_OP_ReadRules(char * cfgfile);
64 int _setlevels(RuleNode *node, int nnode);
65 int AddHash_Rule(RuleNode *node);
69 int OS_CleanMSG(char *msg, Eventinfo *lf);
74 int FTS(Eventinfo *lf);
75 int AddtoIGnore(Eventinfo *lf);
76 int IGnore(Eventinfo *lf);
80 void DecodeEvent(Eventinfo *lf);
81 int DecodeSyscheck(Eventinfo *lf);
82 int DecodeRootcheck(Eventinfo *lf);
83 int DecodeHostinfo(Eventinfo *lf);
87 int ReadDecodeXML(char *file);
93 /** int main(int argc, char **argv)
95 int main(int argc, char **argv)
97 int c = 0, m_queue = 0;
98 char *dir = DEFAULTDIR;
100 char *group = GROUPGLOBAL;
102 char *cfg = DEFAULTCPATH;
104 /* Setting the name */
111 active_responses = NULL;
112 memset(prev_month, '\0', 4);
114 while((c = getopt(argc, argv, "Vfdhu:g:D:c:")) != -1){
127 ErrorExit("%s: -u needs an argument",ARGV0);
132 ErrorExit("%s: -g needs an argument",ARGV0);
137 ErrorExit("%s: -D needs an argument",ARGV0);
141 ErrorExit("%s: -c needs an argument",ARGV0);
155 /* Reading configuration file */
156 if(GlobalConf(cfg) < 0)
158 ErrorExit(CONFIG_ERROR,ARGV0, cfg);
161 debug1(READ_CONFIG, ARGV0);
165 /* Getting servers hostname */
166 memset(__shost, '\0', 512);
167 if(gethostname(__shost, 512 -1) != 0)
169 strncpy(__shost, OSSEC_SERVER, 512 -1);
175 /* Remove domain part if available */
176 _ltmp = strchr(__shost, '.');
184 ErrorExit(CHROOT_ERROR,ARGV0,dir);
188 /* Reading decoders */
189 OS_CreateOSDecoderList();
190 if(!ReadDecodeXML("etc/decoder.xml"))
192 ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER);
195 c = ReadDecodeXML("etc/local_decoder.xml");
199 ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER);
204 /* Creating the rules list */
205 Rules_OP_CreateRules();
208 /* Reading the rules */
211 rulesfiles = Config.includes;
212 while(rulesfiles && *rulesfiles)
214 debug1("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles);
215 if(Rules_OP_ReadRules(*rulesfiles) < 0)
216 ErrorExit(RULES_ERROR, ARGV0, *rulesfiles);
222 free(Config.includes);
223 Config.includes = NULL;
227 /* Fixing the levels/accuracy */
230 RuleNode *tmp_node = OS_GetFirstRule();
232 total_rules = _setlevels(tmp_node, 0);
233 debug1("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules);
237 /* Creating a rules hash (for reading alerts from other servers). */
239 RuleNode *tmp_node = OS_GetFirstRule();
240 Config.g_rules_hash = OSHash_Create();
241 if(!Config.g_rules_hash)
243 ErrorExit(MEM_ERROR, ARGV0);
245 AddHash_Rule(tmp_node);
250 /* Start up message */
251 verbose(STARTUP_MSG, ARGV0, getpid());
254 /* Going to main loop */
265 * Main function. Receives the messages(events)
266 * and analyze them all.
268 void OS_ReadMSG(int m_queue)
271 char msg[OS_MAXSTR +1];
275 /* Null to global currently pointers */
276 currently_rule = NULL;
279 /* Creating the event list */
280 OS_CreateEventList(Config.memorysize);
283 /* Initiating the FTS list */
286 ErrorExit(FTS_LIST_ERROR, ARGV0);
291 /* Getting currently time before starting */
295 /* Doing some cleanup */
296 memset(msg, '\0', OS_MAXSTR +1);
299 print_out("%s: Type one log per line.\n", ARGV0);
305 lf = (Eventinfo *)calloc(1,sizeof(Eventinfo));
307 /* This shouldn't happen .. */
310 ErrorExit(MEM_ERROR,ARGV0);
314 /* Fixing the msg. */
315 strncpy(msg, "1:a:", 5);
319 /* Receive message from queue */
320 if(fgets(msg +4, OS_MAXSTR, stdin))
322 RuleNode *rulenode_pt;
324 /* Getting the time we received the event */
328 /* Removing new line. */
329 if(msg[strlen(msg) -1] == '\n')
330 msg[strlen(msg) -1] = '\0';
333 /* Make sure we ignore blank lines. */
343 /* Default values for the log info */
347 /* Clean the msg appropriately */
348 if(OS_CleanMSG(msg, lf) < 0)
350 merror(IMSG_ERROR,ARGV0,msg);
358 /* Currently rule must be null in here */
359 currently_rule = NULL;
362 /*** Running decoders ***/
364 /* Getting log size */
365 lf->size = strlen(lf->log);
368 /* Decoding event. */
372 /* Looping all the rules */
373 rulenode_pt = OS_GetFirstRule();
376 ErrorExit("%s: Rules in an inconsistent state. Exiting.",
383 print_out("\n**Rule debugging:");
389 if(lf->decoder_info->type == OSSEC_ALERT)
391 if(!lf->generated_rule)
396 /* We go ahead in here and process the alert. */
397 currently_rule = lf->generated_rule;
400 /* The categories must match */
401 else if(rulenode_pt->ruleinfo->category !=
402 lf->decoder_info->type)
408 /* Checking each rule. */
409 else if((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt))
416 print_out("\n**Phase 3: Completed filtering (rules).");
417 print_out(" Rule id: '%d'", currently_rule->sigid);
418 print_out(" Level: '%d'", currently_rule->level);
419 print_out(" Description: '%s'",currently_rule->comment);
425 if(currently_rule->level == 0)
431 /* Checking ignore time */
432 if(currently_rule->ignore_time)
434 if(currently_rule->time_ignored == 0)
436 currently_rule->time_ignored = lf->time;
438 /* If the currently time - the time the rule was ignored
439 * is less than the time it should be ignored,
440 * leave (do not alert again).
442 else if((lf->time - currently_rule->time_ignored)
443 < currently_rule->ignore_time)
449 currently_rule->time_ignored = 0;
453 /* Pointer to the rule that generated it */
454 lf->generated_rule = currently_rule;
457 /* Checking if we should ignore it */
458 if(currently_rule->ckignore && IGnore(lf))
461 lf->generated_rule = NULL;
465 /* Checking if we need to add to ignore list */
466 if(currently_rule->ignore)
472 /* Log the alert if configured to ... */
473 if(currently_rule->alert_opts & DO_LOGALERT)
475 print_out("**Alert to be generated.\n\n");
479 /* Copy the structure to the state memory of if_matched_sid */
480 if(currently_rule->sid_prev_matched)
482 if(!OSList_AddData(currently_rule->sid_prev_matched, lf))
484 merror("%s: Unable to add data to sig list.", ARGV0);
488 lf->sid_node_to_delete =
489 currently_rule->sid_prev_matched->last_node;
493 else if(currently_rule->group_prev_matched)
497 while(i < currently_rule->group_prev_matched_sz)
500 currently_rule->group_prev_matched[i],
503 merror("%s: Unable to add data to grp list.",ARGV0);
513 }while((rulenode_pt = rulenode_pt->next) != NULL);
516 /* Only clear the memory if the eventinfo was not
517 * added to the stateful memory
518 * -- message is free inside clean event --
520 if(lf->generated_rule == NULL)