int main_analysisd(int argc, char **argv) #endif { int c = 0, m_queue = 0, test_config = 0,run_foreground = 0; int debug_level = 0; char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; int uid = 0,gid = 0; char *cfg = DEFAULTCPATH; /* Setting the name */ OS_SetName(ARGV0); thishour = 0; today = 0; prev_year = 0; memset(prev_month, '\0', 4); hourly_alerts = 0; hourly_events = 0; hourly_syscheck = 0; hourly_firewall = 0; while((c = getopt(argc, argv, "Vtdhfu:g:D:c:")) != -1){ switch(c){ case 'V': print_version(); break; case 'h': help_analysisd(); break; case 'd': nowDebug(); debug_level = 1; break; case 'f': run_foreground = 1; break; case 'u': if(!optarg) ErrorExit("%s: -u needs an argument",ARGV0); user = optarg; break; case 'g': if(!optarg) ErrorExit("%s: -g needs an argument",ARGV0); group = optarg; break; case 'D': if(!optarg) ErrorExit("%s: -D needs an argument",ARGV0); dir = optarg; break; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; case 't': test_config = 1; break; default: help_analysisd(); break; } } /* Check current debug_level * Command line setting takes precedence */ if (debug_level == 0) { /* Getting debug level */ debug_level = getDefine_Int("analysisd", "debug", 0, 2); while(debug_level != 0) { nowDebug(); debug_level--; } } /* Starting daemon */ debug1(STARTED_MSG,ARGV0); DEBUG_MSG("%s: DEBUG: Starting on debug mode - %d ", ARGV0, (int)time(0)); /*Check if the user/group given are valid */ uid = Privsep_GetUser(user); gid = Privsep_GetGroup(group); if((uid < 0)||(gid < 0)) ErrorExit(USER_ERROR,ARGV0,user,group); /* Found user */ debug1(FOUND_USER, ARGV0); /* Initializing Active response */ AR_Init(); if(AR_ReadConfig(cfg) < 0) { ErrorExit(CONFIG_ERROR,ARGV0, cfg); } debug1(ASINIT, ARGV0); /* Reading configuration file */ if(GlobalConf(cfg) < 0) { ErrorExit(CONFIG_ERROR,ARGV0, cfg); } debug1(READ_CONFIG, ARGV0); /* Fixing Config.ar */ Config.ar = ar_flag; if(Config.ar == -1) Config.ar = 0; /* Getting servers hostname */ memset(__shost, '\0', 512); if(gethostname(__shost, 512 -1) != 0) { strncpy(__shost, OSSEC_SERVER, 512 -1); } else { char *_ltmp; /* Remove domain part if available */ _ltmp = strchr(__shost, '.'); if(_ltmp) *_ltmp = '\0'; } /* going on Daemon mode */ if(!test_config && !run_foreground) { nowDaemon(); goDaemon(); } /* Starting prelude */ #ifdef PRELUDE if(Config.prelude) { prelude_start(Config.prelude_profile, argc, argv); } #endif /* Starting zeromq */ #ifdef ZEROMQ_OUTPUT if(Config.zeromq_output) { zeromq_output_start(Config.zeromq_output_uri, argc, argv); } #endif /* Opening the Picviz socket */ if(Config.picviz) { OS_PicvizOpen(Config.picviz_socket); if(chown(Config.picviz_socket, uid, gid) == -1) { ErrorExit(CHOWN_ERROR, ARGV0, Config.picviz_socket); } } /* Setting the group */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* Chrooting */ if(Privsep_Chroot(dir) < 0) ErrorExit(CHROOT_ERROR,ARGV0,dir); nowChroot(); /* * 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. */ { { /* Initializing the decoders list */ OS_CreateOSDecoderList(); if(!Config.decoders) { /* Legacy loading */ /* Reading decoders */ if(!ReadDecodeXML(XML_DECODER)) { ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); } /* Reading local ones. */ c = ReadDecodeXML(XML_LDECODER); if(!c) { if((c != -2)) ErrorExit(CONFIG_ERROR, ARGV0, XML_LDECODER); } else { if(!test_config) 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) { if(!test_config) verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles); if(!ReadDecodeXML(*decodersfiles)) ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles); free(*decodersfiles); decodersfiles++; } } /* 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) { if(!test_config) 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) { if(!test_config) verbose("%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; } /* 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 */ { int total_rules; RuleNode *tmp_node = OS_GetFirstRule(); total_rules = _setlevels(tmp_node, 0); if(!test_config) verbose("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules); } /* Creating a rules hash (for reading alerts from other servers). */ { RuleNode *tmp_node = OS_GetFirstRule(); Config.g_rules_hash = OSHash_Create(); if(!Config.g_rules_hash) { ErrorExit(MEM_ERROR, ARGV0); } AddHash_Rule(tmp_node); } /* Ignored files on syscheck */ { char **files; files = Config.syscheck_ignore; while(files && *files) { if(!test_config) verbose("%s: INFO: Ignoring file: '%s'", ARGV0, *files); files++; } } /* Checking if log_fw is enabled. */ Config.logfw = getDefine_Int("analysisd", "log_fw", 0, 1); /* Success on the configuration test */ if(test_config) exit(0); /* Verbose message */ debug1(PRIVSEP_MSG, ARGV0, dir, user); /* Signal manipulation */ StartSIG(ARGV0); /* Setting the user */ if(Privsep_SetUser(uid) < 0) ErrorExit(SETUID_ERROR,ARGV0,user); /* Creating the PID file */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); /* Setting the queue */ if((m_queue = StartMQ(DEFAULTQUEUE,READ)) < 0) ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); /* White list */ if(Config.white_list == NULL) { if(Config.ar) verbose("%s: INFO: No IP in the white list for active reponse.", ARGV0); } else { if(Config.ar) { os_ip **wl; int wlc = 0; wl = Config.white_list; while(*wl) { verbose("%s: INFO: White listing IP: '%s'",ARGV0, (*wl)->ip); wl++;wlc++; } verbose("%s: INFO: %d IPs in the white list for active response.", ARGV0, wlc); } } /* Hostname White list */ if(Config.hostname_white_list == NULL) { if(Config.ar) verbose("%s: INFO: No Hostname in the white list for active reponse.", ARGV0); } else { if(Config.ar) { int wlc = 0; OSMatch **wl; wl = Config.hostname_white_list; while(*wl) { char **tmp_pts = (*wl)->patterns; while(*tmp_pts) { verbose("%s: INFO: White listing Hostname: '%s'",ARGV0,*tmp_pts); wlc++; tmp_pts++; } wl++; } verbose("%s: INFO: %d Hostname(s) in the white list for active response.", ARGV0, wlc); } } /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); /* Going to main loop */ OS_ReadMSG(m_queue); if (Config.picviz) { OS_PicvizClose(); } exit(0); }
int main(int argc, char **argv) { int test_config = 0; int c = 0; char *ut_str = NULL; const char *dir = DEFAULTDIR; const char *cfg = DEFAULTCPATH; /* Set the name */ OS_SetName(ARGV0); thishour = 0; today = 0; prev_year = 0; full_output = 0; alert_only = 0; active_responses = NULL; memset(prev_month, '\0', 4); while ((c = getopt(argc, argv, "VatvdhU:D:c:")) != -1) { switch (c) { case 'V': print_version(); break; case 't': test_config = 1; break; case 'h': help_logtest(); break; case 'd': nowDebug(); break; case 'U': if (!optarg) { ErrorExit("%s: -U needs an argument", ARGV0); } ut_str = optarg; break; case 'D': if (!optarg) { ErrorExit("%s: -D needs an argument", ARGV0); } dir = optarg; break; case 'c': if (!optarg) { ErrorExit("%s: -c needs an argument", ARGV0); } cfg = optarg; break; case 'a': alert_only = 1; break; case 'v': full_output = 1; break; default: help_logtest(); break; } } /* Read configuration file */ if (GlobalConf(cfg) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } debug1(READ_CONFIG, ARGV0); /* Get server hostname */ memset(__shost, '\0', 512); if (gethostname(__shost, 512 - 1) != 0) { strncpy(__shost, OSSEC_SERVER, 512 - 1); } else { char *_ltmp; /* Remove domain part if available */ _ltmp = strchr(__shost, '.'); if (_ltmp) { *_ltmp = '\0'; } } if (chdir(dir) != 0) { ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); } Config.decoder_order_size = (size_t)getDefine_Int("analysisd", "decoder_order_size", 8, MAX_DECODER_ORDER_SIZE); /* * 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. */ { { /* Load decoders */ /* Initialize the decoders list */ OS_CreateOSDecoderList(); if (!Config.decoders) { /* Legacy loading */ /* Read decoders */ if (!ReadDecodeXML("etc/decoder.xml")) { ErrorExit(CONFIG_ERROR, ARGV0, XML_DECODER); } /* Read 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 specified in ossec.conf */ char **decodersfiles; decodersfiles = Config.decoders; while ( decodersfiles && *decodersfiles) { verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles); if (!ReadDecodeXML(*decodersfiles)) { ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles); } free(*decodersfiles); decodersfiles++; } } /* Load decoders */ SetDecodeXML(); } { /* Load Lists */ /* Initialize 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 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 */ /* Create the rules list */ Rules_OP_CreateRules(); /* Read 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; } /* 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(); } } /* Fix the levels/accuracy */ { int total_rules; RuleNode *tmp_node = OS_GetFirstRule(); total_rules = _setlevels(tmp_node, 0); debug1("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules); } /* Creating a rules hash (for reading alerts from other servers) */ { RuleNode *tmp_node = OS_GetFirstRule(); Config.g_rules_hash = OSHash_Create(); if (!Config.g_rules_hash) { ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno)); } AddHash_Rule(tmp_node); } if (test_config == 1) { exit(0); } /* Start up message */ verbose(STARTUP_MSG, ARGV0, getpid()); /* Going to main loop */ OS_ReadMSG(ut_str); exit(0); }