// ******************************************************************** // * // * flattenConjunct // * -------------- // * // * gives flat representation of conjunctive construct // * // ********************************************************************* void construct::flattenConjunct(constructNode *Node, marray<int> &discAttrIdxs, marray<int> &AttrVals, marray<int> &contAttrIdxs, marray<double> &lowerBndys, marray<double> &upperBndys) { switch (Node->nodeType) { case cnAND: if (Node->left) flattenConjunct(Node->left, discAttrIdxs, AttrVals, contAttrIdxs, lowerBndys, upperBndys) ; if (Node->right) flattenConjunct(Node->right, discAttrIdxs, AttrVals, contAttrIdxs, lowerBndys, upperBndys) ; break ; case cnCONTattrValue: contAttrIdxs.addEnd(Node->attrIdx) ; lowerBndys.addEnd(Node->lowerBoundary) ; upperBndys.addEnd(Node->upperBoundary) ; break ; case cnDISCattrValue: discAttrIdxs.addEnd(Node->attrIdx) ; AttrVals.addEnd(Node->valueIdx) ; break ; default: merror("construct::flattenConjunct", "unexpected node type detected") ; } }
/* OS_UpdateKeys(keystore *keys) * Update the keys if changed. */ int OS_UpdateKeys(keystore *keys) { if(keys->file_change != File_DateofChange(KEYS_FILE)) { merror(ENCFILE_CHANGED, __local_name); debug1("%s: DEBUG: Freekeys", __local_name); OS_FreeKeys(keys); debug1("%s: DEBUG: OS_ReadKeys", __local_name); /* Reading keys */ verbose(ENC_READ, __local_name); OS_ReadKeys(keys); debug1("%s: DEBUG: OS_StartCounter", __local_name); OS_StartCounter(keys); debug1("%s: DEBUG: OS_UpdateKeys completed", __local_name); return(1); } return(0); }
/** * Shutdowns execd properly. */ static void execd_shutdown(int sig) { /* Removing pending active responses. */ merror(EXEC_SHUTDOWN, ARGV0); timeout_node = OSList_GetFirstNode(timeout_list); while(timeout_node) { timeout_data *list_entry; list_entry = (timeout_data *)timeout_node->data; ExecCmd(list_entry->command); /* Delete currently node - already sets the pointer to next */ OSList_DeleteCurrentlyNode(timeout_list); timeout_node = OSList_GetCurrentlyNode(timeout_list); } #ifndef WIN32 HandleSIG(sig); #endif }
int main (void) { void *p; int save; errno = 0; p = malloc (-1); save = errno; if (p != NULL) merror ("malloc (-1) succeeded."); if (p == NULL && save != ENOMEM) merror ("errno is not set correctly"); p = malloc (10); if (p == NULL) merror ("malloc (10) failed."); /* realloc (p, 0) == free (p). */ p = realloc (p, 0); if (p != NULL) merror ("realloc (p, 0) failed."); p = malloc (0); #if !defined(__UCLIBC__) || defined(__MALLOC_GLIBC_COMPAT__) if (p == NULL) #else if (p != NULL) #endif merror ("malloc (0) failed."); p = realloc (p, 0); if (p != NULL) merror ("realloc (p, 0) failed."); return errors != 0; }
int main (void) { void *p; int save; errno = 0; p = malloc (-1); save = errno; if (p != NULL) merror ("malloc (-1) succeeded."); if (p == NULL && save != ENOMEM) merror ("errno is not set correctly"); p = malloc (10); if (p == NULL) merror ("malloc (10) failed."); /* realloc (p, 0) == free (p). */ p = realloc (p, 0); if (p != NULL) merror ("realloc (p, 0) failed."); p = malloc (0); if (p == NULL) merror ("malloc (0) failed."); p = realloc (p, 0); if (p != NULL) merror ("realloc (p, 0) failed."); return errors != 0; }
/* run_notify: Send periodically notification to server */ void run_notify() { char keep_alive_random[1024]; char tmp_msg[OS_SIZE_1024 +1]; char *uname; char *shared_files; os_md5 md5sum; keep_alive_random[0] = '\0'; time_t curr_time; curr_time = time(0); #ifndef ONEWAY /* Check if the server has responded */ if((curr_time - available_server) > (3*NOTIFY_TIME)) { /* If response is not available, set lock and * wait for it. */ verbose(SERVER_UNAV, ARGV0); os_setwait(); /* Send sync message */ start_agent(0); verbose(SERVER_UP, ARGV0); os_delwait(); } #endif /* Check if time has elapsed */ if((curr_time - g_saved_time) < (NOTIFY_TIME - 120)) { return; } g_saved_time = curr_time; debug1("%s: DEBUG: Sending agent notification.", ARGV0); /* Send the message. * Message is going to be the * uname\n checksum file\n checksum file\n */ /* Getting uname */ uname = getuname(); if(!uname) { merror(MEM_ERROR,ARGV0); return; } /* get shared files */ shared_files = getsharedfiles(); if(!shared_files) { shared_files = strdup("\0"); if(!shared_files) { free(uname); merror(MEM_ERROR,ARGV0); return; } } rand_keepalive_str2(keep_alive_random, 700); /* creating message */ if((File_DateofChange(AGENTCONFIGINT) > 0 ) && (OS_MD5_File(AGENTCONFIGINT, md5sum) == 0)) { snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s\n%s", uname, md5sum, shared_files, keep_alive_random); } else { snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s\n%s", uname, shared_files, keep_alive_random); } /* Sending status message */ send_msg(0, tmp_msg); free(uname); free(shared_files); return; }
/** main **/ int main(int argc, char **argv) { char *dir = DEFAULTDIR; char *group = GROUPGLOBAL; char *user = USER; char *agent_id = NULL; char *ip_address = NULL; char *ar = NULL; int arq = 0; int gid = 0; int uid = 0; int c = 0, restart_syscheck = 0, restart_all_agents = 0, list_agents = 0; int info_agent = 0, agt_id = 0, active_only = 0, csv_output = 0; int list_responses = 0, end_time = 0, restart_agent = 0; char shost[512]; keystore keys; /* Setting the name */ OS_SetName(ARGV0); /* user arguments */ if(argc < 2) { helpmsg(); } while((c = getopt(argc, argv, "VehdlLcsaru:i:b:f:R:")) != -1) { switch(c){ case 'V': print_version(); break; case 'h': helpmsg(); break; case 'd': nowDebug(); break; case 'L': list_responses = 1; break; case 'e': end_time = 1; break; case 'r': restart_syscheck = 1; break; case 'l': list_agents++; break; case 's': csv_output = 1; break; case 'c': active_only++; break; case 'i': info_agent++; case 'u': if(!optarg) { merror("%s: -u needs an argument",ARGV0); helpmsg(); } agent_id = optarg; break; case 'b': if(!optarg) { merror("%s: -b needs an argument",ARGV0); helpmsg(); } ip_address = optarg; break; case 'f': if(!optarg) { merror("%s: -e needs an argument",ARGV0); helpmsg(); } ar = optarg; break; case 'R': if(!optarg) { merror("%s: -R needs an argument",ARGV0); helpmsg(); } agent_id = optarg; restart_agent = 1; case 'a': restart_all_agents = 1; break; default: helpmsg(); break; } } /* Getting the group name */ gid = Privsep_GetGroup(group); uid = Privsep_GetUser(user); if(gid < 0) { ErrorExit(USER_ERROR, ARGV0, user, group); } /* Setting the group */ if(Privsep_SetGroup(gid) < 0) { ErrorExit(SETGID_ERROR,ARGV0, group); } /* Chrooting to the default directory */ if(Privsep_Chroot(dir) < 0) { ErrorExit(CHROOT_ERROR, ARGV0, dir); } /* Inside chroot now */ nowChroot(); /* Setting the user */ if(Privsep_SetUser(uid) < 0) { ErrorExit(SETUID_ERROR, ARGV0, user); } /* Getting servers hostname */ memset(shost, '\0', 512); if(gethostname(shost, 512 -1) != 0) { strncpy(shost, "localhost", 32); return(0); } /* Listing responses. */ if(list_responses) { FILE *fp; if(!csv_output) { printf("\nOSSEC HIDS %s. Available active responses:\n", ARGV0); } fp = fopen(DEFAULTAR, "r"); if(fp) { char buffer[256]; while(fgets(buffer, 255, fp) != NULL) { char *r_name; char *r_cmd; char *r_timeout; r_name = buffer; r_cmd = strchr(buffer, ' '); if(!r_cmd) continue; *r_cmd = '\0'; r_cmd++; if(*r_cmd == '-') r_cmd++; if(*r_cmd == ' ') r_cmd++; r_timeout = strchr(r_cmd, ' '); if(!r_timeout) continue; *r_timeout = '\0'; if(strcmp(r_name, "restart-ossec0") == 0) { continue; } printf("\n Response name: %s, command: %s", r_name, r_cmd); } printf("\n\n"); fclose(fp); } else { printf("\n No active response available.\n\n"); } exit(0); } /* Listing available agents. */ if(list_agents) { if(!csv_output) { printf("\nOSSEC HIDS %s. List of available agents:", ARGV0); printf("\n ID: 000, Name: %s (server), IP: 127.0.0.1, Active/Local\n", shost); } else { printf("000,%s (server),127.0.0.1,Active/Local,\n", shost); } print_agents(1, active_only, csv_output); printf("\n"); exit(0); } /* Checking if the provided ID is valid. */ if(agent_id != NULL) { if(strcmp(agent_id, "000") != 0) { OS_ReadKeys(&keys); agt_id = OS_IsAllowedID(&keys, agent_id); if(agt_id < 0) { printf("\n** Invalid agent id '%s'.\n", agent_id); helpmsg(); } } else { /* server. */ agt_id = -1; } } /* Printing information from an agent. */ if(info_agent) { int agt_status = 0; char final_ip[IPSIZE + 4]; agent_info *agt_info; final_ip[(sizeof final_ip) - 1] = '\0'; if(!csv_output) printf("\nOSSEC HIDS %s. Agent information:", ARGV0); if(agt_id != -1) { agt_status = get_agent_status(keys.keyentries[agt_id]->name, keys.keyentries[agt_id]->ip->ip); agt_info = get_agent_info(keys.keyentries[agt_id]->name, keys.keyentries[agt_id]->ip->ip); /* Getting full address/prefix length from ip. */ snprintf(final_ip, sizeof final_ip, "%s/%u", keys.keyentries[agt_id]->ip->ip, keys.keyentries[agt_id]->ip->prefixlength); if(!csv_output) { printf("\n Agent ID: %s\n", keys.keyentries[agt_id]->id); printf(" Agent Name: %s\n", keys.keyentries[agt_id]->name); printf(" IP address: %s\n", final_ip); printf(" Status: %s\n\n",print_agent_status(agt_status)); } else { printf("%s,%s,%s,%s,", keys.keyentries[agt_id]->id, keys.keyentries[agt_id]->name, final_ip, print_agent_status(agt_status)); } } else { agt_status = get_agent_status(NULL, NULL); agt_info = get_agent_info(NULL, "127.0.0.1"); if(!csv_output) { printf("\n Agent ID: 000 (local instance)\n"); printf(" Agent Name: %s\n", shost); printf(" IP address: 127.0.0.1\n"); printf(" Status: %s/Local\n\n",print_agent_status(agt_status)); } else { printf("000,%s,127.0.0.1,%s/Local,", shost, print_agent_status(agt_status)); } } if(!csv_output) { printf(" Operating system: %s\n", agt_info->os); printf(" Client version: %s\n", agt_info->version); printf(" Last keep alive: %s\n\n", agt_info->last_keepalive); if(end_time) { printf(" Syscheck last started at: %s\n", agt_info->syscheck_time); printf(" Syscheck last ended at: %s\n", agt_info->syscheck_endtime); printf(" Rootcheck last started at: %s\n", agt_info->rootcheck_time); printf(" Rootcheck last ended at: %s\n\n", agt_info->rootcheck_endtime); } else { printf(" Syscheck last started at: %s\n", agt_info->syscheck_time); printf(" Rootcheck last started at: %s\n", agt_info->rootcheck_time); } } else { printf("%s,%s,%s,%s,%s,\n", agt_info->os, agt_info->version, agt_info->last_keepalive, agt_info->syscheck_time, agt_info->rootcheck_time); } exit(0); } /* Restarting syscheck every where. */ if(restart_all_agents && restart_syscheck) { /* Connecting to remoted. */ debug1("%s: DEBUG: Connecting to remoted...", ARGV0); arq = connect_to_remoted(); if(arq < 0) { printf("\n** Unable to connect to remoted.\n"); exit(1); } debug1("%s: DEBUG: Connected...", ARGV0); /* Sending restart message to all agents. */ if(send_msg_to_agent(arq, HC_SK_RESTART, NULL, NULL) == 0) { printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on all agents.", ARGV0); } else { printf("\n** Unable to restart syscheck on all agents.\n"); exit(1); } exit(0); } if(restart_syscheck && agent_id) { /* Restart on the server. */ if(strcmp(agent_id, "000") == 0) { os_set_restart_syscheck(); printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck " "locally.\n", ARGV0); exit(0); } /* Connecting to remoted. */ debug1("%s: DEBUG: Connecting to remoted...", ARGV0); arq = connect_to_remoted(); if(arq < 0) { printf("\n** Unable to connect to remoted.\n"); exit(1); } debug1("%s: DEBUG: Connected...", ARGV0); if(send_msg_to_agent(arq, HC_SK_RESTART, agent_id, NULL) == 0) { printf("\nOSSEC HIDS %s: Restarting Syscheck/Rootcheck on agent: %s\n", ARGV0, agent_id); } else { printf("\n** Unable to restart syscheck on agent: %s\n", agent_id); exit(1); } exit(0); } if(restart_agent && agent_id) { /* Connecting to remoted. */ debug1("%s: DEBUG: Connecting to remoted...", ARGV0); arq = connect_to_remoted(); if(arq < 0) { printf("\n** Unable to connect to remoted.\n"); exit(1); } debug1("%s: DEBUG: Connected...", ARGV0); if(send_msg_to_agent(arq, "restart-ossec0", agent_id, "null") == 0) { printf("\nOSSEC HIDS %s: Restarting agent: %s\n", ARGV0, agent_id); } else { printf("\n** Unable to restart agent: %s\n", agent_id); exit(1); } exit(0); } /* running active response on the specified agent id. */ if(ip_address && ar && agent_id) { /* Connecting to remoted. */ debug1("%s: DEBUG: Connecting to remoted...", ARGV0); arq = connect_to_remoted(); if(arq < 0) { printf("\n** Unable to connect to remoted.\n"); exit(1); } debug1("%s: DEBUG: Connected...", ARGV0); if(send_msg_to_agent(arq, ar, agent_id, ip_address) == 0) { printf("\nOSSEC HIDS %s: Running active response '%s' on: %s\n", ARGV0, ar, agent_id); } else { printf("\n** Unable to restart syscheck on agent: %s\n", agent_id); exit(1); } exit(0); } printf("\n** Invalid argument combination.\n"); helpmsg(); return(0); }
/* check_rc_if: v0.1 * Check all interfaces for promiscuous mode */ void check_rc_if() { int _fd, _errors = 0, _total = 0; struct ifreq tmp_str[16]; struct ifconf _if; struct ifreq *_ir; struct ifreq *_ifend; struct ifreq _ifr; _fd = socket(AF_INET, SOCK_DGRAM, 0); if(_fd < 0) { merror("%s: Error checking interfaces (socket)", ARGV0); return; } memset(tmp_str, 0, sizeof(struct ifreq)*16); _if.ifc_len = sizeof(tmp_str); _if.ifc_buf = (caddr_t)(tmp_str); if (ioctl(_fd, SIOCGIFCONF, &_if) < 0) { close(_fd); merror("%s: Error checking interfaces (ioctl)", ARGV0); return; } _ifend = (struct ifreq*) (void *) ((char*)tmp_str + _if.ifc_len); _ir = tmp_str; /* Looping on all interfaces */ for (; _ir < _ifend; _ir++) { strncpy(_ifr.ifr_name, _ir->ifr_name, sizeof(_ifr.ifr_name)); /* Getting information from each interface */ if (ioctl(_fd, SIOCGIFFLAGS, (char*)&_ifr) == -1) { continue; } _total++; if ((_ifr.ifr_flags & IFF_PROMISC) ) { char op_msg[OS_SIZE_1024 +1]; if(run_ifconfig(_ifr.ifr_name)) { snprintf(op_msg, OS_SIZE_1024,"Interface '%s' in promiscuous" " mode.", _ifr.ifr_name); notify_rk(ALERT_SYSTEM_CRIT, op_msg); } else { snprintf(op_msg, OS_SIZE_1024,"Interface '%s' in promiscuous" " mode, but ifconfig is not showing it" "(probably trojaned).", _ifr.ifr_name); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); } _errors++; } } close(_fd); if(_errors == 0) { char op_msg[OS_SIZE_1024 +1]; snprintf(op_msg, OS_SIZE_1024, "No problem detected on ifconfig/ifs." " Analyzed %d interfaces.", _total); notify_rk(ALERT_OK, op_msg); } return; }
/* main: v0.3: 2005/04/04 */ int main(int argc, char **argv) { int c; int debug_level = 0; int test_config = 0,run_foreground = 0; int accept_manager_commands = 0; const char *cfg = DEFAULTCPATH; /* Setuping up random */ #ifndef WIN32 #ifdef __OpenBSD__ srandomdev(); #else srandom((unsigned int)time(0)); #endif #else srandom(time(0)) #endif /* Setting the name */ OS_SetName(ARGV0); while((c = getopt(argc, argv, "Vtdhfc:")) != -1) { switch(c) { case 'V': print_version(); break; case 'h': help_logcollector(); break; case 'd': nowDebug(); debug_level = 1; break; case 'f': run_foreground = 1; break; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; case 't': test_config = 1; break; default: help_logcollector(); break; } } /* Check current debug_level * Command line setting takes precedence */ if (debug_level == 0) { /* Getting debug level */ debug_level = getDefine_Int("logcollector", "debug", 0, 2); while(debug_level != 0) { nowDebug(); debug_level--; } } debug1(STARTED_MSG,ARGV0); accept_manager_commands = getDefine_Int("logcollector", "remote_commands", 0, 1); /* Reading config file */ if(LogCollectorConfig(cfg, accept_manager_commands) < 0) ErrorExit(CONFIG_ERROR, ARGV0, cfg); /* Getting loop timeout */ loop_timeout = getDefine_Int("logcollector", "loop_timeout", 1, 120); open_file_attempts = getDefine_Int("logcollector", "open_attempts", 2, 998); /* Exit if test config */ if(test_config) exit(0); /* No file available to monitor -- continue */ if(logff == NULL) { os_calloc(2, sizeof(logreader), logff); logff[0].file = NULL; logff[0].ffile = NULL; logff[0].logformat = NULL; logff[0].fp = NULL; logff[1].file = NULL; logff[1].logformat = NULL; merror(NO_FILE, ARGV0); } /* Starting signal handler */ StartSIG(ARGV0); if (!run_foreground) { /* Going on daemon mode */ nowDaemon(); goDaemon(); } /* Creating PID file */ if(CreatePID(ARGV0, getpid()) < 0) merror(PID_ERROR, ARGV0); /* Waiting 6 seconds for the analysisd/agentd to settle */ debug1("%s: DEBUG: Waiting main daemons to settle.", ARGV0); sleep(6); /* Starting the queue. */ if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0) ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); /* Main loop */ LogCollectorStart(); }
/** int ReadActiveCommands(XML_NODE node, void *d1, void *d2) */ int ReadActiveCommands(XML_NODE node, void *d1, void *d2) { int i = 0; char *tmp_str = NULL; /* Xml values */ char *command_name = "name"; char *command_expect = "expect"; char *command_executable = "executable"; char *timeout_allowed = "timeout_allowed"; ar_command *tmp_command; /* Allocating the active-response command */ tmp_command = calloc(1, sizeof(ar_command)); if(!tmp_command) { merror(MEM_ERROR, ARGV0); return(-1); } tmp_command->name = NULL; tmp_command->expect= 0; tmp_command->executable = NULL; tmp_command->timeout_allowed = 0; /* Searching for the commands */ while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } if(strcmp(node[i]->element, command_name) == 0) { tmp_command->name = strdup(node[i]->content); } else if(strcmp(node[i]->element, command_expect) == 0) { tmp_str = strdup(node[i]->content); } else if(strcmp(node[i]->element, command_executable) == 0) { tmp_command->executable = strdup(node[i]->content); } else if(strcmp(node[i]->element, timeout_allowed) == 0) { if(strcmp(node[i]->content, "yes") == 0) tmp_command->timeout_allowed = 1; else if(strcmp(node[i]->content, "no") == 0) tmp_command->timeout_allowed = 0; else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } if(!tmp_command->name || !tmp_str || !tmp_command->executable) { merror(AR_CMD_MISS, ARGV0); return(-1); } /* Getting the expect */ if(strlen(tmp_str) > 4) { if(OS_Regex("user", tmp_str)) tmp_command->expect |= USERNAME; if(OS_Regex("srcip", tmp_str)) tmp_command->expect |= SRCIP; } free(tmp_str); tmp_str = NULL; /* Adding command to the list */ if(!OSList_AddData(d1, (void *)tmp_command)) { merror(LIST_ADD_ERROR, ARGV0); return(-1); } /* Done over here */ return(0); }
/* read_dir v0.1 * */ int read_sys_dir(char *dir_name, int do_read) { int i = 0; unsigned int entry_count = 0; int did_changed = 0; DIR *dp; struct dirent *entry; struct stat statbuf; #ifndef WIN32 char *(dirs_to_doread[]) = { "/bin", "/sbin", "/usr/bin", "/usr/sbin", "/dev", "/etc", "/boot", NULL }; #endif if((dir_name == NULL)||(strlen(dir_name) > PATH_MAX)) { merror("%s: Invalid directory given.",ARGV0); return(-1); } /* Ignoring user-supplied list. */ if(rootcheck.ignore) { while(rootcheck.ignore[i]) { if(strcmp(dir_name, rootcheck.ignore[i]) == 0) { return(1); } i++; } i = 0; } /* Getting the number of nodes. The total number on opendir * must be the same */ if(lstat(dir_name, &statbuf) < 0) { return(-1); } /* Currently device id */ if(did != statbuf.st_dev) { if(did != 0) did_changed = 1; did = statbuf.st_dev; } if(!S_ISDIR(statbuf.st_mode)) { return(-1); } #ifndef WIN32 /* Check if the do_read is valid for this directory */ while(dirs_to_doread[i]) { if(strcmp(dir_name, dirs_to_doread[i]) == 0) { do_read = 1; break; } i++; } #else do_read = 0; #endif /* Opening the directory given */ dp = opendir(dir_name); if(!dp) { if((strcmp(dir_name, "") == 0)&& (dp = opendir("/"))) { /* ok */ } else { return(-1); } } /* Reading every entry in the directory */ while((entry = readdir(dp)) != NULL) { char f_name[PATH_MAX +2]; struct stat statbuf_local; /* Just ignore . and .. */ if((strcmp(entry->d_name,".") == 0) || (strcmp(entry->d_name,"..") == 0)) { entry_count++; continue; } /* Creating new file + path string */ if(strcmp(dir_name, "/") == 0) { snprintf(f_name, PATH_MAX +1, "/%s", entry->d_name); } else { snprintf(f_name, PATH_MAX +1, "%s/%s",dir_name, entry->d_name); } /* Checking if file is a directory */ if(lstat(f_name, &statbuf_local) == 0) { /* On all the systems, except darwin, the * link count is only increased on directories. */ #ifndef Darwin if(S_ISDIR(statbuf_local.st_mode)) #else if(S_ISDIR(statbuf_local.st_mode) || S_ISREG(statbuf_local.st_mode) || S_ISLNK(statbuf_local.st_mode)) #endif { entry_count++; } } /* Checking every file against the rootkit database */ for(i = 0; i<= rk_sys_count; i++) { if(!rk_sys_file[i]) break; if(strcmp(rk_sys_file[i], entry->d_name) == 0) { char op_msg[OS_SIZE_1024 +1]; _sys_errors++; snprintf(op_msg, OS_SIZE_1024, "Rootkit '%s' detected " "by the presence of file '%s/%s'.", rk_sys_name[i], dir_name, rk_sys_file[i]); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); } } /* Ignoring /proc */ if((strcmp(f_name, "/proc") == 0) || (strcmp(f_name, "/sys") == 0)) continue; read_sys_file(f_name, do_read); } /* Entry count for directory different than the actual * link count from stats. */ if((entry_count != statbuf.st_nlink) && ((did_changed == 0) || ((entry_count + 1) != statbuf.st_nlink))) { #ifndef WIN32 struct stat statbuf2; char op_msg[OS_SIZE_1024 +1]; if((lstat(dir_name, &statbuf2) == 0) && (statbuf2.st_nlink != entry_count)) { snprintf(op_msg, OS_SIZE_1024, "Files hidden inside directory " "'%s'. Link count does not match number of files " "(%d,%d).", dir_name, entry_count, (int)statbuf.st_nlink); /* Solaris /boot is terrible :) */ #ifdef SOLARIS if(strncmp(dir_name, "/boot", strlen("/boot")) != 0) { notify_rk(ALERT_ROOTKIT_FOUND, op_msg); _sys_errors++; } #elif Darwin if(strncmp(dir_name, "/dev", strlen("/dev")) != 0) { notify_rk(ALERT_ROOTKIT_FOUND, op_msg); _sys_errors++; } #else notify_rk(ALERT_ROOTKIT_FOUND, op_msg); _sys_errors++; #endif } #endif } closedir(dp); return(0); }
/* Read Output of commands */ void *read_command(int pos, int *rc, int drop_it) { size_t cmd_size = 0; char *p; char str[OS_MAXSTR+1]; FILE *cmd_output; str[OS_MAXSTR]= '\0'; *rc = 0; debug2("%s: DEBUG: Running command '%s'", ARGV0, logff[pos].command); cmd_output = popen(logff[pos].command, "r"); if(!cmd_output) { merror("%s: ERROR: Unable to execute command: '%s'.", ARGV0, logff[pos].command); logff[pos].command = NULL; return (NULL); } snprintf(str, 256, "ossec: output: '%s': ", (NULL != logff[pos].alias) ? logff[pos].alias : logff[pos].command); cmd_size = strlen(str); while(fgets(str + cmd_size, OS_MAXSTR - OS_LOG_HEADER - 256, cmd_output) != NULL) { /* Getting the last occurence of \n */ if ((p = strrchr(str, '\n')) != NULL) { *p = '\0'; } /* Removing empty lines. */ #ifdef WIN32 if(str[0] == '\r' && str[1] == '\0') { continue; } #endif if(str[0] == '\0') { continue; } debug2("%s: DEBUG: Reading command message: '%s'", ARGV0, str); /* Sending message to queue */ if(drop_it == 0) { if(SendMSG(logr_queue,str, (NULL != logff[pos].alias) ? logff[pos].alias : logff[pos].command, LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } } } continue; } pclose(cmd_output); return(NULL); }
/* Read DJB multilog. */ void *read_djbmultilog(int pos, int *rc, int drop_it) { int str_len = 0; int need_clear = 0; char *p; char str[OS_MAXSTR + 1]; char buffer[OS_MAXSTR + 1]; str[OS_MAXSTR]= '\0'; *rc = 0; /* Must have a valid program name. */ if(!logff[pos].djb_program_name) { return(NULL); } /* Getting new entry */ while(fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { /* Getting buffer size */ str_len = strlen(str); /* Getting the last occurence of \n */ if ((p = strrchr(str, '\n')) != NULL) { *p = '\0'; /* If need clear is set, we just get the line and ignore it. */ if(need_clear) { need_clear = 0; continue; } } else { need_clear = 1; } /* Multilog messages have the following format: * @40000000463246020c2ca16c xx... */ if((str_len > 26) && (str[0] == '@') && isalnum((int)str[1]) && isalnum((int)str[2]) && isalnum((int)str[3]) && isalnum((int)str[24]) && (str[25] == ' ')) { /* Removing spaces and tabs */ p = str + 26; while(*p == ' ' || *p == '\t') { p++; } /* If message has a valid syslog header, send as is. */ if((str_len > 44) && (p[3] == ' ') && (p[6] == ' ') && (p[9] == ':') && (p[12] == ':') && (p[15] == ' ')) { p+=16; strncpy(buffer, p, OS_MAXSTR); } else { /* We will add a proper syslog header. */ time_t djbtime; struct tm *pt; djbtime = time(NULL); pt = localtime(&djbtime); /* Syslog time: Apr 27 14:50:32 */ snprintf(buffer, OS_MAXSTR, "%s %02d %02d:%02d:%02d %s %s: %s", djb_month[pt->tm_mon], pt->tm_mday, pt->tm_hour, pt->tm_min, pt->tm_sec, djb_host, logff[pos].djb_program_name, p); } } else { debug2("%s: DEBUG: Invalid DJB log: '%s'", ARGV0, str); continue; } debug2("%s: DEBUG: Reading DJB multilog message: '%s'", ARGV0, buffer); /* Sending message to queue */ if(drop_it == 0) { if(SendMSG(logr_queue, buffer, logff[pos].file, MYSQL_MQ) < 0) { merror(QUEUE_SEND, ARGV0); if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } } } continue; } return(NULL); }
/* Handle each client */ static void HandleClient(int client_socket, char *srcip) { int sb_size = OS_MAXSTR; int r_sz = 0; char buffer[OS_MAXSTR + 2]; char storage_buffer[OS_MAXSTR + 2]; char tmp_buffer[OS_MAXSTR + 2]; char *buffer_pt = NULL; /* Create PID file */ if (CreatePID(ARGV0, getpid()) < 0) { ErrorExit(PID_ERROR, ARGV0); } /* Initialize some variables */ memset(buffer, '\0', OS_MAXSTR + 2); memset(storage_buffer, '\0', OS_MAXSTR + 2); memset(tmp_buffer, '\0', OS_MAXSTR + 2); while (1) { /* If we fail, we need to return and close the socket */ if ((r_sz = OS_RecvTCPBuffer(client_socket, buffer, OS_MAXSTR - 2)) < 0) { close(client_socket); DeletePID(ARGV0); return; } /* We must have a new line at the end */ buffer_pt = strchr(buffer, '\n'); if (!buffer_pt) { /* Buffer is full */ if ((sb_size - r_sz) <= 2) { merror("%s: Full buffer receiving from: '%s'", ARGV0, srcip); sb_size = OS_MAXSTR; storage_buffer[0] = '\0'; continue; } strncat(storage_buffer, buffer, sb_size); sb_size -= r_sz; continue; } /* See if we received more than just one message */ if (*(buffer_pt + 1) != '\0') { *buffer_pt = '\0'; buffer_pt++; strncpy(tmp_buffer, buffer_pt, OS_MAXSTR); } /* Store everything in the storage_buffer * Check if buffer will be full */ if ((sb_size - r_sz) <= 2) { merror("%s: Full buffer receiving from: '%s'.", ARGV0, srcip); sb_size = OS_MAXSTR; storage_buffer[0] = '\0'; tmp_buffer[0] = '\0'; continue; } strncat(storage_buffer, buffer, sb_size); /* Remove carriage returns too */ buffer_pt = strchr(storage_buffer, '\r'); if (buffer_pt) { *buffer_pt = '\0'; } /* Remove syslog header */ if (storage_buffer[0] == '<') { buffer_pt = strchr(storage_buffer + 1, '>'); if (buffer_pt) { buffer_pt++; } else { buffer_pt = storage_buffer; } } else { buffer_pt = storage_buffer; } /* Send to the queue */ if (SendMSG(logr.m_queue, buffer_pt, srcip, SYSLOG_MQ) < 0) { merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); } } /* Clean up the buffers */ if (tmp_buffer[0] != '\0') { strncpy(storage_buffer, tmp_buffer, OS_MAXSTR); sb_size = OS_MAXSTR - (strlen(storage_buffer) + 1); tmp_buffer[0] = '\0'; } else { storage_buffer[0] = '\0'; sb_size = OS_MAXSTR; } } }
int Read_Localfile(XML_NODE node, void *d1, void *d2) { int pl = 0; int i = 0; int glob_set = 0; #ifndef WIN32 int glob_offset = 0; #endif /* XML Definitions */ char *xml_localfile_location = "location"; char *xml_localfile_command = "command"; char *xml_localfile_logformat = "log_format"; char *xml_localfile_frequency = "frequency"; char *xml_localfile_alias = "alias"; logreader *logf; logreader_config *log_config; log_config = (logreader_config *)d1; /* If config is not set, we need to create it */ if(!log_config->config) { os_calloc(2, sizeof(logreader), log_config->config); logf = log_config->config; logf[0].file = NULL; logf[0].command = NULL; logf[0].alias = NULL; logf[0].logformat = NULL; logf[1].file = NULL; logf[1].command = NULL; logf[1].alias = NULL; logf[1].logformat = NULL; } else { logf = log_config->config; while(logf[pl].file != NULL) { pl++; } /* Allocating more memory */ os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config); logf = log_config->config; logf[pl +1].file = NULL; logf[pl +1].command = NULL; logf[pl +1].alias = NULL; logf[pl +1].logformat = NULL; } logf[pl].file = NULL; logf[pl].command = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; logf[pl].ffile = NULL; logf[pl].djb_program_name = NULL; logf[pl].ign = 360; /* Searching for entries related to files */ i = 0; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } else if(strcmp(node[i]->element,xml_localfile_command) == 0) { /* We don't accept remote commands from the manager - just in case. */ if(log_config->agent_cfg == 1 && log_config->accept_remote == 0) { merror("%s: Remote commands are not accepted from the manager. " "Ignoring it on the agent.conf", ARGV0); logf[pl].file = NULL; logf[pl].ffile = NULL; logf[pl].command = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; return(OS_INVALID); } os_strdup(node[i]->content, logf[pl].file); logf[pl].command = logf[pl].file; } else if(strcmp(node[i]->element,xml_localfile_frequency) == 0) { if(strcmp(node[i]->content, "hourly") == 0) { logf[pl].ign = 3600; } else if(strcmp(node[i]->content, "daily") == 0) { logf[pl].ign = 86400; } else { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logf[pl].ign = atoi(node[i]->content); } } else if(strcmp(node[i]->element,xml_localfile_location) == 0) { #ifdef WIN32 /* Expand variables on Windows. */ if(strchr(node[i]->content, '%')) { int expandreturn = 0; char newfile[OS_MAXSTR +1]; newfile[OS_MAXSTR] = '\0'; expandreturn = ExpandEnvironmentStrings(node[i]->content, newfile, OS_MAXSTR); if((expandreturn > 0) && (expandreturn < OS_MAXSTR)) { free(node[i]->content); os_strdup(newfile, node[i]->content); } } #endif /* This is a glob*. * We will call this file multiple times until * there is no one else available. */ #ifndef WIN32 /* No windows support for glob */ if(strchr(node[i]->content, '*') || strchr(node[i]->content, '?') || strchr(node[i]->content, '[')) { glob_t g; /* Setting ot the first entry of the glob */ if(glob_set == 0) glob_set = pl +1; if(glob(node[i]->content, 0, NULL, &g) != 0) { merror(GLOB_ERROR, ARGV0, node[i]->content); os_strdup(node[i]->content, logf[pl].file); i++; continue; } /* Checking for the last entry */ if((g.gl_pathv[glob_offset]) == NULL) { /* Checking when nothing is found. */ if(glob_offset == 0) { merror(GLOB_NFOUND, ARGV0, node[i]->content); return(OS_INVALID); } i++; continue; } /* Checking for strftime on globs too. */ if(strchr(g.gl_pathv[glob_offset], '%')) { struct tm *p; time_t l_time = time(0); char lfile[OS_FLSIZE + 1]; size_t ret; p = localtime(&l_time); lfile[OS_FLSIZE] = '\0'; ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p); if(ret == 0) { merror(PARSE_ERROR, ARGV0, g.gl_pathv[glob_offset]); return(OS_INVALID); } os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile); os_strdup(g.gl_pathv[glob_offset], logf[pl].file); } else { os_strdup(g.gl_pathv[glob_offset], logf[pl].file); } glob_offset++; globfree(&g); /* Now we need to create another file entry */ pl++; os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config); logf = log_config->config; logf[pl].file = NULL; logf[pl].alias = NULL; logf[pl].logformat = NULL; logf[pl].fp = NULL; logf[pl].ffile = NULL; logf[pl +1].file = NULL; logf[pl +1].alias = NULL; logf[pl +1].logformat = NULL; /* We can not increment the file count in here */ continue; } else if(strchr(node[i]->content, '%')) #else if(strchr(node[i]->content, '%')) #endif /* WIN32 */ /* We need the format file (based on date) */ { struct tm *p; time_t l_time = time(0); char lfile[OS_FLSIZE + 1]; size_t ret; p = localtime(&l_time); lfile[OS_FLSIZE] = '\0'; ret = strftime(lfile, OS_FLSIZE, node[i]->content, p); if(ret == 0) { merror(PARSE_ERROR, ARGV0, node[i]->content); return(OS_INVALID); } os_strdup(node[i]->content, logf[pl].ffile); os_strdup(node[i]->content, logf[pl].file); } /* Normal file */ else { os_strdup(node[i]->content, logf[pl].file); } } /* Getting log format */ else if(strcasecmp(node[i]->element,xml_localfile_logformat) == 0) { os_strdup(node[i]->content, logf[pl].logformat); if(strcmp(logf[pl].logformat, "syslog") == 0) { } else if(strcmp(logf[pl].logformat, "generic") == 0) { } else if(strcmp(logf[pl].logformat, "snort-full") == 0) { } else if(strcmp(logf[pl].logformat, "snort-fast") == 0) { } else if(strcmp(logf[pl].logformat, "apache") == 0) { } else if(strcmp(logf[pl].logformat, "iis") == 0) { } else if(strcmp(logf[pl].logformat, "squid") == 0) { } else if(strcmp(logf[pl].logformat, "nmapg") == 0) { } else if(strcmp(logf[pl].logformat, "mysql_log") == 0) { } else if(strcmp(logf[pl].logformat, "ossecalert") == 0) { } else if(strcmp(logf[pl].logformat, "mssql_log") == 0) { } else if(strcmp(logf[pl].logformat, "postgresql_log") == 0) { } else if(strcmp(logf[pl].logformat, "djb-multilog") == 0) { } else if(strcmp(logf[pl].logformat, "syslog-pipe") == 0) { } else if(strcmp(logf[pl].logformat, "command") == 0) { } else if(strcmp(logf[pl].logformat, "full_command") == 0) { } else if(strncmp(logf[pl].logformat, "multi-line", 10) == 0) { int x = 0; logf[pl].logformat+=10; while(logf[pl].logformat[0] == ' ') logf[pl].logformat++; if(logf[pl].logformat[0] != ':') { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logf[pl].logformat++; while(*logf[pl].logformat == ' ') logf[pl].logformat++; while(logf[pl].logformat[x] >= '0' && logf[pl].logformat[x] <= '9') x++; while(logf[pl].logformat[x] == ' ') x++; if(logf[pl].logformat[x] != '\0') { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(logf[pl].logformat, EVENTLOG) == 0) { } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcasecmp(node[i]->element,xml_localfile_alias) == 0) { os_strdup(node[i]->content, logf[pl].alias); } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Validating glob entries */ if(glob_set) { char *format; /* Getting log format */ if(logf[pl].logformat) { format = logf[pl].logformat; } else if(logf[glob_set -1].logformat) { format = logf[glob_set -1].logformat; } else { merror(MISS_LOG_FORMAT, ARGV0); return(OS_INVALID); } /* The last entry is always null on glob */ pl--; /* Setting format for all entries */ for(i = (glob_set -1); i<= pl; i++) { /* Every entry must be valid */ if(!logf[i].file) { merror(MISS_FILE, ARGV0); return(OS_INVALID); } if(logf[i].logformat == NULL) { logf[i].logformat = format; } } } /* Missing log format */ if(!logf[pl].logformat) { merror(MISS_LOG_FORMAT, ARGV0); return(OS_INVALID); } /* Missing file */ if(!logf[pl].file) { merror(MISS_FILE, ARGV0); return(OS_INVALID); } /* Verifying a valid event log config */ if(strcmp(logf[pl].logformat, EVENTLOG) == 0) { if((strcmp(logf[pl].file, "Application") != 0)&& (strcmp(logf[pl].file, "System") != 0)&& (strcmp(logf[pl].file, "Security") != 0)) { /* Invalid event log */ merror(NSTD_EVTLOG, ARGV0, logf[pl].file); return(0); } } if((strcmp(logf[pl].logformat, "command") == 0)|| (strcmp(logf[pl].logformat, "full_command") == 0)) { if(!logf[pl].command) { merror("%s: ERROR: Missing 'command' argument. " "This option will be ignored.", ARGV0); } } return(0); }
/* Read syslog files/snort fast/apache files */ void *read_mysql_log(int pos, int *rc, int drop_it) { size_t str_len = 0; int need_clear = 0; char *p; char str[OS_MAXSTR + 1]; char buffer[OS_MAXSTR + 1]; str[OS_MAXSTR]= '\0'; *rc = 0; /* Getting new entry */ while(fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL) { /* Getting buffer size */ str_len = strlen(str); /* Getting the last occurence of \n */ if ((p = strrchr(str, '\n')) != NULL) { *p = '\0'; /* If need clear is set, we just get the line and ignore it. */ if(need_clear) { need_clear = 0; continue; } } else { need_clear = 1; } #ifdef WIN32 if ((p = strrchr(str, '\r')) != NULL) { *p = '\0'; } /* Looking for empty string (only on windows) */ if(str_len <= 2) { continue; } /* Windows can have comment on their logs */ if(str[0] == '#') { continue; } #endif /* Mysql messages have the following format: * 070823 21:01:30 xx */ if((str_len > 18) && (str[6] == ' ') && (str[9] == ':') && (str[12] == ':') && isdigit((int)str[0]) && isdigit((int)str[1]) && isdigit((int)str[2]) && isdigit((int)str[3]) && isdigit((int)str[4]) && isdigit((int)str[5]) && isdigit((int)str[7]) && isdigit((int)str[8])) { /* Saving last time */ strncpy(__mysql_last_time, str, 16); __mysql_last_time[15] = '\0'; /* Removing spaces and tabs */ p = str + 15; while(*p == ' ' || *p == '\t') { p++; } /* Valid MySQL message */ snprintf(buffer, OS_MAXSTR, "MySQL log: %s %s", __mysql_last_time, p); } /* Multiple events at the same second share the same * time stamp. * 0909 2020 2020 2020 20 */ else if((str_len > 10) && (__mysql_last_time[0] != '\0') && (str[0] == 0x09) && (str[1] == 0x09) && (str[2] == 0x20) && (str[3] == 0x20) && (str[4] == 0x20) && (str[5] == 0x20) && (str[6] == 0x20) && (str[7] == 0x20)) { p = str +2; /* Removing extra spaces and tabs */ while(*p == ' ' || *p == '\t') { p++; } /* Valid MySQL message */ snprintf(buffer, OS_MAXSTR, "MySQL log: %s %s", __mysql_last_time, p); } else { continue; } debug2("%s: DEBUG: Reading mysql messages: '%s'", ARGV0, buffer); /* Sending message to queue */ if(drop_it == 0) { if(SendMSG(logr_queue, buffer, logff[pos].file, MYSQL_MQ) < 0) { merror(QUEUE_SEND, ARGV0); if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH); } } } continue; } return(NULL); }
void logErrors() { GLenum error; while (GL_NO_ERROR != (error = glGetError())) { merror(M_DISPLAY_MESSAGE_DOMAIN, "GL error = 0x%04X", error); } }
/* Real monitord global */ void Monitord() { time_t tm; struct tm *p; int today = 0; int thismonth = 0; int thisyear = 0; char str[OS_SIZE_1024 +1]; /* Waiting a few seconds to settle */ sleep(10); memset(str, '\0', OS_SIZE_1024 +1); /* Getting currently time before starting */ tm = time(NULL); p = localtime(&tm); today = p->tm_mday; thismonth = p->tm_mon; thisyear = p->tm_year+1900; /* Connecting to the message queue * Exit if it fails. */ if((mond.a_queue = StartMQ(DEFAULTQUEUE,WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); } /* Sending startup message */ snprintf(str, OS_SIZE_1024 -1, OS_AD_STARTED); if(SendMSG(mond.a_queue, str, ARGV0, LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } /* Main monitor loop */ while(1) { tm = time(NULL); p = localtime(&tm); /* Checking unavailable agents */ if(mond.monitor_agents) { monitor_agents(); } /* Day changed, deal with log files */ if(today != p->tm_mday) { /* Generate reports. */ generate_reports(today, thismonth, thisyear, p); manage_files(today, thismonth, thisyear); today = p->tm_mday; thismonth = p->tm_mon; thisyear = p->tm_year+1900; } /* We only check every two minutes */ sleep(120); } }
/** int ReadActiveResponses(XML_NODE node, void *d1, void *d2) * Generates a list with all active responses. */ int ReadActiveResponses(XML_NODE node, void *d1, void *d2) { FILE *fp; int i = 0; int r_ar = 0; int l_ar = 0; int rpt = 0; /* Xml options */ char *xml_ar_command = "command"; char *xml_ar_location = "location"; char *xml_ar_agent_id = "agent_id"; char *xml_ar_rules_id = "rules_id"; char *xml_ar_rules_group = "rules_group"; char *xml_ar_level = "level"; char *xml_ar_timeout = "timeout"; char *xml_ar_disabled = "disabled"; char *xml_ar_repeated = "repeated_offenders"; char *tmp_location; /* Currently active response */ active_response *tmp_ar; /* Opening shared ar file */ fp = fopen(DEFAULTARPATH, "a"); if(!fp) { merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH); return(-1); } chmod(DEFAULTARPATH, 0444); /* Allocating for the active-response */ tmp_ar = calloc(1, sizeof(active_response)); if(!tmp_ar) { merror(MEM_ERROR, ARGV0); return(-1); } /* Initializing variables */ tmp_ar->name = NULL; tmp_ar->command = NULL; tmp_ar->location = 0; tmp_ar->timeout = 0; tmp_ar->level = 0; tmp_ar->agent_id = NULL; tmp_ar->rules_id = NULL; tmp_ar->rules_group = NULL; tmp_ar->ar_cmd = NULL; tmp_location = NULL; /* Searching for the commands */ while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Command */ if(strcmp(node[i]->element, xml_ar_command) == 0) { tmp_ar->command = strdup(node[i]->content); } /* Target */ else if(strcmp(node[i]->element, xml_ar_location) == 0) { tmp_location = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_agent_id) == 0) { tmp_ar->agent_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_id) == 0) { tmp_ar->rules_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_group) == 0) { tmp_ar->rules_group = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_level) == 0) { /* Level must be numeric */ if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } tmp_ar->level = atoi(node[i]->content); /* Making sure the level is valid */ if((tmp_ar->level < 0) || (tmp_ar->level > 20)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_timeout) == 0) { tmp_ar->timeout = atoi(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) { ar_flag = -1; } else if(strcmp(node[i]->content, "no") == 0) { /* Don't do anything if disabled is set to "no" */ } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_repeated) == 0) { /* Nothing - we deal with it on execd. */ rpt = 1; } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Checking if ar is disabled */ if(ar_flag == -1) { fclose(fp); return(0); } /* Command and location must be there */ if(!tmp_ar->command || !tmp_location) { if(rpt == 1) { fclose(fp); return(0); } merror(AR_MISS, ARGV0); return(-1); } /* analysisd */ if(OS_Regex("AS|analysisd|analysis-server|server", tmp_location)) { tmp_ar->location|= AS_ONLY; } if(OS_Regex("local", tmp_location)) { tmp_ar->location|= REMOTE_AGENT; } if(OS_Regex("defined-agent", tmp_location)) { if(!tmp_ar->agent_id) { merror(AR_DEF_AGENT, ARGV0); return(-1); } tmp_ar->location|= SPECIFIC_AGENT; } if(OS_Regex("all|any", tmp_location)) { tmp_ar->location|=ALL_AGENTS; } /* If we didn't set any value for the location */ if(tmp_ar->location == 0) { merror(AR_INV_LOC, ARGV0, tmp_location); return(-1); } /* cleaning tmp_location */ free(tmp_location); tmp_location = NULL; /* Checking if command name is valid */ { OSListNode *my_commands_node; my_commands_node = OSList_GetFirstNode(d1); while(my_commands_node) { ar_command *my_command; my_command = (ar_command *)my_commands_node->data; if(strcmp(my_command->name, tmp_ar->command) == 0) { tmp_ar->ar_cmd = my_command; break; } my_commands_node = OSList_GetNextNode(d1); } /* Didn't find a valid command */ if(tmp_ar->ar_cmd == NULL) { merror(AR_INV_CMD, ARGV0, tmp_ar->command); return(-1); } } /* Checking if timeout is allowed */ if(tmp_ar->timeout && !tmp_ar->ar_cmd->timeout_allowed) { merror(AR_NO_TIMEOUT, ARGV0, tmp_ar->ar_cmd->name); return(-1); } /* d1 is the active response list */ if(!OSList_AddData(d2, (void *)tmp_ar)) { merror(LIST_ADD_ERROR, ARGV0); return(-1); } /* Setting a unique active response name */ tmp_ar->name = calloc(OS_FLSIZE +1, sizeof(char)); if(!tmp_ar->name) { ErrorExit(MEM_ERROR, ARGV0); } snprintf(tmp_ar->name, OS_FLSIZE, "%s%d", tmp_ar->ar_cmd->name, tmp_ar->timeout); /* Adding to shared file */ fprintf(fp, "%s - %s - %d\n", tmp_ar->name, tmp_ar->ar_cmd->executable, tmp_ar->timeout); /* Setting the configs to start the right queues */ if(tmp_ar->location & AS_ONLY) { l_ar = 1; } if(tmp_ar->location & ALL_AGENTS) { r_ar = 1; } if(tmp_ar->location & REMOTE_AGENT) { r_ar = 1; l_ar = 1; } if(tmp_ar->location & SPECIFIC_AGENT) { r_ar = 1; } /* Setting the configuration for the active response */ if(r_ar && (!(ar_flag & REMOTE_AR))) { ar_flag|= REMOTE_AR; } if(l_ar && (!(ar_flag & LOCAL_AR))) { ar_flag|= LOCAL_AR; } /* Closing shared file for active response */ fclose(fp); /* Done over here */ return(0); }
// here we define a particular calibrator class by // 1) register a particular set of input and out vars // 2) define a fittable function that is meant to calibrate between them // // in principle, one can make a class just like this one for ANY set of vars // and ANY fitable funciton (as long as the fitable function class is also written) EyeCalibrator::EyeCalibrator(std::string _tag, shared_ptr<Variable> _eyeHraw, shared_ptr<Variable> _eyeVraw, shared_ptr<Variable> _eyeHcalibrated, shared_ptr<Variable> _eyeVcalibrated, const int order):Calibrator(_tag) { nextTimeToWarnUS = 0; lastHtimeUS = 0; if (VERBOSE_EYE_CALIBRATORS) mprintf("mEyeCalibrator constructor has been called."); // 1) register inputs and outputs inputIndexH = (this->registerInput(_eyeHraw)); inputIndexV = (this->registerInput(_eyeVraw)); outputIndexH = (this->registerOutput(_eyeHcalibrated)); outputIndexV = (this->registerOutput(_eyeVcalibrated)); this->initialize(); // create memory for the expected data, averagers, and fitable functions // 2) create and assign a specific fitableFunction for each output shared_ptr<FitableFunction> fitableFunctionH; shared_ptr<FitableFunction> fitableFunctionV; // In this case, they are identical, but they do not need to be the same. (any fitable function object will work here) // default values for parameters are established in here. switch(order) { case 1: fitableFunctionH = shared_ptr<FitableFunction>(new FirstOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexH)); fitableFunctionV = shared_ptr<FitableFunction>(new FirstOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexV)); break; case 2: fitableFunctionH = shared_ptr<FitableFunction>(new SecondOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexH)); fitableFunctionV = shared_ptr<FitableFunction>(new SecondOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexV)); break; default: merror(M_PARSER_MESSAGE_DOMAIN,"%s has an unsupported order (%d)", _tag.c_str(), order); break; } HfunctionIndex = (fitableFunctions->addReference(outputIndexH, fitableFunctionH))-1; VfunctionIndex = (fitableFunctions->addReference(outputIndexV, fitableFunctionV))-1; // // 2) create and assign a specific fitableFunction for each output // // In this case, they are identical, but they do not need to be the same. (any fitable function object will work here) // // default values for parameters are established in here. // // first output (h) // shared_ptr<FitableFunction> fitableFunctionH(new SecondOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexH)); // HfunctionIndex = (fitableFunctions->addReference(outputIndexH, fitableFunctionH))-1; // // // second output (v) // shared_ptr<FitableFunction> fitableFunctionV(new SecondOrderPolynomialFitableFunction(this->getNumInputs(),true,inputIndexV)); // VfunctionIndex = (fitableFunctions->addReference(outputIndexV, fitableFunctionV))-1; // make sure fitable functions parameters are set to defaults (they will be, but nice form) this->setParametersToDefaults(); // 3) if the private variable was found, then we should use its values to set the parameters (i.e. replace defaults) if(privateVariableNameAlreadyInstantiated) { tryToUseDataToSetParameters(privateVariable->getValue()); } // 4) announce our current paramters (JJD added Sept 13, 2006) announceCalibrationUpdate(); // the eye calibrator uses this object to buffer and pair eye samples together. int buffer_size = M_ASSUMED_EYE_SAMPLES_PER_MS * M_MAX_EYE_BUFFER_SIZE_MS; pairedEyeData = new PairedEyeData(buffer_size); }
/* AgentdStart v0.2, 2005/11/09 * Starts the agent daemon. */ void AgentdStart(char *dir, int uid, int gid, char *user, char *group) { int rc = 0; int pid = 0; int maxfd = 0; fd_set fdset; struct timeval fdtimeout; pid = getpid(); available_server = 0; /* Going Daemon */ if (!run_foreground) { nowDaemon(); goDaemonLight(); } /* Setting group ID */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR, ARGV0, group); /* chrooting */ if(Privsep_Chroot(dir) < 0) ErrorExit(CHROOT_ERROR, ARGV0, dir); nowChroot(); if(Privsep_SetUser(uid) < 0) ErrorExit(SETUID_ERROR, ARGV0, user); /* Create the queue. In this case we are going to create * and read from it * Exit if fails. */ if((agt->m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); maxfd = agt->m_queue; agt->sock = -1; /* Creating PID file */ if(CreatePID(ARGV0, getpid()) < 0) merror(PID_ERROR,ARGV0); /* Reading the private keys */ verbose(ENC_READ, ARGV0); OS_ReadKeys(&keys); OS_StartCounter(&keys); /* cmoraes : changed the following call to os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id); */ os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, agt->profile); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); /* Initial random numbers */ #ifdef __OpenBSD__ srandomdev(); #else srandom( time(0) + getpid()+ pid + getppid()); #endif random(); /* Connecting UDP */ rc = 0; while(rc < agt->rip_id) { verbose("%s: INFO: Server IP Address: %s", ARGV0, agt->rip[rc]); rc++; } /* Trying to connect to the server */ if(!connect_server(0)) { ErrorExit(UNABLE_CONN, ARGV0); } /* Setting max fd for select */ if(agt->sock > maxfd) { maxfd = agt->sock; } /* Connecting to the execd queue */ if(agt->execdq == 0) { if((agt->execdq = StartMQ(EXECQUEUE, WRITE)) < 0) { merror("%s: INFO: Unable to connect to the active response " "queue (disabled).", ARGV0); agt->execdq = -1; } } /* Trying to connect to server */ os_setwait(); start_agent(1); os_delwait(); /* Sending integrity message for agent configs */ intcheck_file(OSSECCONF, dir); intcheck_file(OSSEC_DEFINES, dir); /* Sending first notification */ run_notify(); /* Maxfd must be higher socket +1 */ maxfd++; /* monitor loop */ while(1) { /* Monitoring all available sockets from here */ FD_ZERO(&fdset); FD_SET(agt->sock, &fdset); FD_SET(agt->m_queue, &fdset); fdtimeout.tv_sec = 1; fdtimeout.tv_usec = 0; /* Continuously send notifications */ run_notify(); /* Wait with a timeout for any descriptor */ rc = select(maxfd, &fdset, NULL, NULL, &fdtimeout); if(rc == -1) { ErrorExit(SELECT_ERROR, ARGV0); } else if(rc == 0) { continue; } /* For the receiver */ if(FD_ISSET(agt->sock, &fdset)) { receive_msg(); } /* For the forwarder */ if(FD_ISSET(agt->m_queue, &fdset)) { EventForward(); } } }
int main(int argc, char **argv) { FILE *fp; // Bucket to keep pids in. int process_pool[POOL_SIZE]; // Count of pids we are wait()ing on. int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0; int gid = 0, client_sock = 0, sock = 0, port = 1515, ret = 0; char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; // TODO: implement or delete char *cfg __attribute__((unused)) = DEFAULTCPATH; char buf[4096 +1]; SSL_CTX *ctx; SSL *ssl; char srcip[IPSIZE +1]; struct sockaddr_in _nc; socklen_t _ncl; /* Initializing some variables */ memset(srcip, '\0', IPSIZE + 1); memset(process_pool, 0x0, POOL_SIZE); bio_err = 0; /* Setting the name */ OS_SetName(ARGV0); /* add an option to use the ip on the socket to tie the name to a specific address */ while((c = getopt(argc, argv, "Vdhiu:g:D:c:m:p:")) != -1) { switch(c){ case 'V': print_version(); break; case 'h': report_help(); break; case 'd': nowDebug(); break; case 'i': use_ip_address = 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; case 'p': if(!optarg) ErrorExit("%s: -%c needs an argument",ARGV0, c); port = atoi(optarg); if(port <= 0 || port >= 65536) { ErrorExit("%s: Invalid port: %s", ARGV0, optarg); } break; default: report_help(); break; } } /* Starting daemon -- NB: need to double fork and setsid */ debug1(STARTED_MSG,ARGV0); /* Check if the user/group given are valid */ gid = Privsep_GetGroup(group); if(gid < 0) ErrorExit(USER_ERROR,ARGV0,user,group); /* Exit here if test config is set */ if(test_config) exit(0); /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* chrooting -- TODO: this isn't a chroot. Should also close unneeded open file descriptors (like stdin/stdout)*/ chdir(dir); /* Signal manipulation */ StartSIG(ARGV0); /* Creating PID files */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); fp = fopen(KEYSFILE_PATH,"a"); if(!fp) { merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH); exit(1); } /* Starting SSL */ ctx = os_ssl_keys(0, dir); if(!ctx) { merror("%s: ERROR: SSL error. Exiting.", ARGV0); exit(1); } /* Connecting via TCP */ sock = OS_Bindporttcp(port, NULL, 0); if(sock <= 0) { merror("%s: Unable to bind to port %d", ARGV0, port); exit(1); } fcntl(sock, F_SETFL, O_NONBLOCK); debug1("%s: DEBUG: Going into listening mode.", ARGV0); while(1) { // no need to completely pin the cpu, 100ms should be fast enough usleep(100*1000); // Only check process-pool if we have active processes if(active_processes > 0){ for (i = 0; i < POOL_SIZE; i++) { int rv = 0; status = 0; if (process_pool[i]) { rv = waitpid(process_pool[i], &status, WNOHANG); if (rv != 0){ debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]); process_pool[i] = 0; active_processes = active_processes - 1; } } } } memset(&_nc, 0, sizeof(_nc)); _ncl = sizeof(_nc); if((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0){ if (active_processes >= POOL_SIZE) { merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0); break; } pid = fork(); if(pid) { active_processes = active_processes + 1; close(client_sock); for (i = 0; i < POOL_SIZE; i++) { if (! process_pool[i]) { process_pool[i] = pid; break; } } } else { strncpy(srcip, inet_ntoa(_nc.sin_addr),IPSIZE -1); char *agentname = NULL; ssl = SSL_new(ctx); SSL_set_fd(ssl, client_sock); do { ret = SSL_accept(ssl); if (ssl_error(ssl, ret)) clean_exit(ctx, client_sock); } while (ret <= 0); verbose("%s: INFO: New connection from %s", ARGV0, srcip); do { ret = SSL_read(ssl, buf, sizeof(buf)); if (ssl_error(ssl, ret)) clean_exit(ctx, client_sock); } while (ret <= 0); int parseok = 0; if(strncmp(buf, "OSSEC A:'", 9) == 0) { char *tmpstr = buf; agentname = tmpstr + 9; tmpstr += 9; while(*tmpstr != '\0') { if(*tmpstr == '\'') { *tmpstr = '\0'; verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip); parseok = 1; break; } tmpstr++; } } if(parseok == 0) { merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip); } else { int acount = 2; char fname[2048 +1]; char response[2048 +1]; char *finalkey = NULL; response[2048] = '\0'; fname[2048] = '\0'; if(!OS_IsValidName(agentname)) { merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip); snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } /* Checking for a duplicated names. */ strncpy(fname, agentname, 2048); while(NameExist(fname)) { snprintf(fname, 2048, "%s%d", agentname, acount); acount++; if(acount > 256) { merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname); snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } } agentname = fname; /* Adding the new agent. */ if (use_ip_address) { finalkey = OS_AddNewAgent(agentname, srcip, NULL, NULL); } else { finalkey = OS_AddNewAgent(agentname, NULL, NULL, NULL); } if(!finalkey) { merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname); snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname); ret = SSL_write(ssl, response, strlen(response)); snprintf(response, 2048, "ERROR: Unable to add agent.\n\n"); ret = SSL_write(ssl, response, strlen(response)); sleep(1); exit(0); } snprintf(response, 2048,"OSSEC K:'%s'\n\n", finalkey); verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip); ret = SSL_write(ssl, response, strlen(response)); if(ret < 0) { merror("%s: ERROR: SSL write error (%d)", ARGV0, ret); merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname); ERR_print_errors_fp(stderr); } else { verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip); } } clean_exit(ctx, client_sock); } } } /* Shutdown the socket */ clean_exit(ctx, sock); return (0); }
/* Receive events from the server */ int receive_msg() { ssize_t recv_b; netsize_t length; int reads = 0; char buffer[OS_MAXSTR + 1]; char cleartext[OS_MAXSTR + 1]; char *tmp_msg; memset(cleartext, '\0', OS_MAXSTR + 1); memset(buffer, '\0', OS_MAXSTR + 1); /* Read until no more messages are available */ while (1) { if (agt->protocol == TCP_PROTO) { /* Only one read per call */ if (reads++) { break; } recv_b = recv(agt->sock, (char*)&length, sizeof(length), MSG_WAITALL); /* Manager disconnected */ if (recv_b <= 0) { return -1; } recv_b = recv(agt->sock, buffer, length, MSG_WAITALL); if (recv_b != length) { merror(RECV_ERROR, ARGV0); continue; } } else { recv_b = recv(agt->sock, buffer, OS_SIZE_1024, MSG_DONTWAIT); if (recv_b <= 0) { break; } } buffer[recv_b] = '\0'; tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b - 1); if (tmp_msg == NULL) { merror(MSG_ERROR, ARGV0, agt->rip[agt->rip_id]); continue; } /* Check for commands */ if (IsValidHeader(tmp_msg)) { available_server = (int)time(NULL); #ifdef WIN32 /* Run timeout commands */ if (agt->execdq >= 0) { WinTimeoutRun(available_server); } #endif /* If it is an active response message */ if (strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0) { tmp_msg += strlen(EXECD_HEADER); #ifndef WIN32 if (agt->execdq >= 0) { if (OS_SendUnix(agt->execdq, tmp_msg, 0) < 0) { merror("%s: Error communicating with execd", ARGV0); } } #else /* Run on Windows */ if (agt->execdq >= 0) { WinExecdRun(tmp_msg); } #endif continue; } /* Restart syscheck */ else if (strcmp(tmp_msg, HC_SK_RESTART) == 0) { os_set_restart_syscheck(); continue; } /* Ack from server */ else if (strcmp(tmp_msg, HC_ACK) == 0) { continue; } /* Close any open file pointer if it was being written to */ if (fp) { fclose(fp); fp = NULL; } /* File update message */ if (strncmp(tmp_msg, FILE_UPDATE_HEADER, strlen(FILE_UPDATE_HEADER)) == 0) { char *validate_file; tmp_msg += strlen(FILE_UPDATE_HEADER); /* Going to after the file sum */ validate_file = strchr(tmp_msg, ' '); if (!validate_file) { continue; } *validate_file = '\0'; /* Copy the file sum */ strncpy(file_sum, tmp_msg, 33); /* Set tmp_msg to the beginning of the file name */ validate_file++; tmp_msg = validate_file; if ((validate_file = strchr(tmp_msg, '\n')) != NULL) { *validate_file = '\0'; } while ((validate_file = strchr(tmp_msg, '/')) != NULL) { *validate_file = '-'; } if (tmp_msg[0] == '.') { tmp_msg[0] = '-'; } snprintf(file, OS_SIZE_1024, "%s/%s", SHAREDCFG_DIR, tmp_msg); fp = fopen(file, "w"); if (!fp) { merror(FOPEN_ERROR, ARGV0, file, errno, strerror(errno)); } } else if (strncmp(tmp_msg, FILE_CLOSE_HEADER, strlen(FILE_CLOSE_HEADER)) == 0) { /* No error */ os_md5 currently_md5; /* Close for the rename to work */ if (fp) { fclose(fp); fp = NULL; } if (file[0] == '\0') { /* Nothing to be done */ } else if (OS_MD5_File(file, currently_md5, OS_TEXT) < 0) { /* Remove file */ unlink(file); file[0] = '\0'; } else { if (strcmp(currently_md5, file_sum) != 0) { debug1("%s: ERROR: Failed md5 for: %s -- deleting.", ARGV0, file); unlink(file); } else { char *final_file; /* Rename the file to its original name */ final_file = strrchr(file, '/'); if (final_file) { if (strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0) { UnmergeFiles(file, SHAREDCFG_DIR); } } else { /* Remove file */ unlink(file); } } file[0] = '\0'; } } else { merror("%s: WARN: Unknown message received from server.", ARGV0); } } else if (fp) { available_server = (int)time(NULL); fprintf(fp, "%s", tmp_msg); } else { merror("%s: WARN: Unknown message received. No action defined.", ARGV0); } } return 0; }
/* Read and generate the integrity data of a file */ static int read_file(const char *file_name, int opts, OSMatch *restriction) { char *buf; char sha1s = '+'; struct stat statbuf; /* Check if the file should be ignored */ if (syscheck.ignore) { int i = 0; while (syscheck.ignore[i] != NULL) { if (strncasecmp(syscheck.ignore[i], file_name, strlen(syscheck.ignore[i])) == 0) { return (0); } i++; } } /* Check in the regex entry */ if (syscheck.ignore_regex) { int i = 0; while (syscheck.ignore_regex[i] != NULL) { if (OSMatch_Execute(file_name, strlen(file_name), syscheck.ignore_regex[i])) { return (0); } i++; } } #ifdef WIN32 /* Win32 does not have lstat */ if (stat(file_name, &statbuf) < 0) #else if (lstat(file_name, &statbuf) < 0) #endif { if(errno == ENOTDIR){ /*Deletion message sending*/ char alert_msg[PATH_MAX+4]; alert_msg[PATH_MAX + 3] = '\0'; snprintf(alert_msg, PATH_MAX + 4, "-1 %s", file_name); send_syscheck_msg(alert_msg); return (0); }else{ merror("%s: Error accessing '%s'.", ARGV0, file_name); return (-1); } } if (S_ISDIR(statbuf.st_mode)) { #ifdef DEBUG verbose("%s: Reading dir: %s\n", ARGV0, file_name); #endif #ifdef WIN32 /* Directory links are not supported */ if (GetFileAttributes(file_name) & FILE_ATTRIBUTE_REPARSE_POINT) { merror("%s: WARN: Links are not supported: '%s'", ARGV0, file_name); return (-1); } #endif return (read_dir(file_name, opts, restriction)); } /* Restrict file types */ if (restriction) { if (!OSMatch_Execute(file_name, strlen(file_name), restriction)) { return (0); } } /* No S_ISLNK on Windows */ #ifdef WIN32 if (S_ISREG(statbuf.st_mode)) #else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) #endif { os_md5 mf_sum; os_sha1 sf_sum; os_sha1 sf_sum2; os_sha1 sf_sum3; /* Clean sums */ strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); strncpy(sf_sum2, "xxx", 4); strncpy(sf_sum3, "xxx", 4); /* Generate checksums */ if ((opts & CHECK_MD5SUM) || (opts & CHECK_SHA1SUM)) { /* If it is a link, check if dest is valid */ #ifndef WIN32 if (S_ISLNK(statbuf.st_mode)) { struct stat statbuf_lnk; if (stat(file_name, &statbuf_lnk) == 0) { if (S_ISREG(statbuf_lnk.st_mode)) { if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) { strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); } } } } else if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) #else if (OS_MD5_SHA1_File(file_name, syscheck.prefilter_cmd, mf_sum, sf_sum, OS_BINARY) < 0) #endif { strncpy(mf_sum, "xxx", 4); strncpy(sf_sum, "xxx", 4); } if (opts & CHECK_SEECHANGES) { sha1s = 's'; } } else { if (opts & CHECK_SEECHANGES) { sha1s = 'n'; } else { sha1s = '-'; } } buf = (char *) OSHash_Get(syscheck.fp, file_name); if (!buf) { char alert_msg[916 + 1]; /* to accommodate a long */ alert_msg[916] = '\0'; if (opts & CHECK_SEECHANGES) { char *alertdump = seechanges_addfile(file_name); if (alertdump) { free(alertdump); alertdump = NULL; } } snprintf(alert_msg, 916, "%c%c%c%c%c%c%c%c%ld:%d:%d:%d:%s:%s:%s:%s:%ld:%ld", opts & CHECK_SIZE ? '+' : '-', opts & CHECK_PERM ? '+' : '-', opts & CHECK_OWNER ? '+' : '-', opts & CHECK_GROUP ? '+' : '-', opts & CHECK_MD5SUM ? '+' : '-', sha1s, opts & CHECK_MTIME ? '+' : '-', opts & CHECK_INODE ? '+' : '-', opts & CHECK_SIZE ? (long)statbuf.st_size : 0, opts & CHECK_PERM ? (int)statbuf.st_mode : 0, opts & CHECK_OWNER ? (int)statbuf.st_uid : 0, opts & CHECK_GROUP ? (int)statbuf.st_gid : 0, opts & CHECK_MD5SUM ? mf_sum : "xxx", opts & CHECK_SHA1SUM ? sf_sum : "xxx", opts & CHECK_OWNER ? get_user(file_name, statbuf.st_uid) : "", opts & CHECK_GROUP ? get_group(statbuf.st_gid) : "", opts & CHECK_MTIME ? (long)statbuf.st_mtime : 0, opts & CHECK_INODE ? (long)statbuf.st_ino : 0); if (OSHash_Add(syscheck.fp, file_name, strdup(alert_msg)) <= 0) { merror("%s: ERROR: Unable to add file to db: %s", ARGV0, file_name); } /* Send the new checksum to the analysis server */ alert_msg[916] = '\0'; snprintf(alert_msg, 916, "%ld:%d:%d:%d:%s:%s:%s:%s:%ld:%ld %s", opts & CHECK_SIZE ? (long)statbuf.st_size : 0, opts & CHECK_PERM ? (int)statbuf.st_mode : 0, opts & CHECK_OWNER ? (int)statbuf.st_uid : 0, opts & CHECK_GROUP ? (int)statbuf.st_gid : 0, opts & CHECK_MD5SUM ? mf_sum : "xxx", opts & CHECK_SHA1SUM ? sf_sum : "xxx", opts & CHECK_OWNER ? get_user(file_name, statbuf.st_uid) : "", opts & CHECK_GROUP ? get_group(statbuf.st_gid) : "", opts & CHECK_MTIME ? (long)statbuf.st_mtime : 0, opts & CHECK_INODE ? (long)statbuf.st_ino : 0, file_name); send_syscheck_msg(alert_msg); } else { char alert_msg[OS_MAXSTR + 1]; char c_sum[256 + 2]; c_sum[0] = '\0'; c_sum[256] = '\0'; alert_msg[0] = '\0'; alert_msg[OS_MAXSTR] = '\0'; /* If it returns < 0, we have already alerted */ if (c_read_file(file_name, buf, c_sum) < 0) { return (0); } if (strcmp(c_sum, buf + 6) != 0) { /* Send the new checksum to the analysis server */ alert_msg[OS_MAXSTR] = '\0'; char *fullalert = NULL; if (buf[5] == 's' || buf[5] == 'n') { fullalert = seechanges_addfile(file_name); if (fullalert) { snprintf(alert_msg, OS_MAXSTR, "%s %s\n%s", c_sum, file_name, fullalert); free(fullalert); fullalert = NULL; } else { snprintf(alert_msg, 916, "%s %s", c_sum, file_name); } } else { snprintf(alert_msg, 916, "%s %s", c_sum, file_name); } send_syscheck_msg(alert_msg); } } /* Sleep here too */ if (__counter >= (syscheck.sleep_after)) { sleep(syscheck.tsleep); __counter = 0; } __counter++; #ifdef DEBUG verbose("%s: file '%s %s'", ARGV0, file_name, mf_sum); #endif } else { #ifdef DEBUG verbose("%s: *** IRREG file: '%s'\n", ARGV0, file_name); #endif } return (0); }
void CLASS apply_profile (const char *input, const char *output) { char *prof; cmsHPROFILE hInProfile=0, hOutProfile=0; cmsHTRANSFORM hTransform; FILE *fp; unsigned size; #ifndef USE_LCMS2 cmsErrorAction (LCMS_ERROR_SHOW); #endif if (strcmp (input, "embed")) hInProfile = cmsOpenProfileFromFile (input, "r"); else if (profile_length) { #ifndef LIBRAW_LIBRARY_BUILD prof = (char *) malloc (profile_length); merror (prof, "apply_profile()"); fseek (ifp, profile_offset, SEEK_SET); fread (prof, 1, profile_length, ifp); hInProfile = cmsOpenProfileFromMem (prof, profile_length); free (prof); #else hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length); #endif } else { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE; #endif #ifdef DCRAW_VERBOSE fprintf (stderr,_("%s has no embedded profile.\n"), ifname); #endif } if (!hInProfile) { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE; #endif return; } if (!output) hOutProfile = cmsCreate_sRGBProfile(); else if ((fp = fopen (output, "rb"))) { fread (&size, 4, 1, fp); fseek (fp, 0, SEEK_SET); oprof = (unsigned *) malloc (size = ntohl(size)); merror (oprof, "apply_profile()"); fread (oprof, 1, size, fp); fclose (fp); if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { free (oprof); oprof = 0; } } #ifdef DCRAW_VERBOSE else fprintf (stderr,_("Cannot open file %s!\n"), output); #endif if (!hOutProfile) { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE; #endif goto quit; } #ifdef DCRAW_VERBOSE if (verbose) fprintf (stderr,_("Applying color profile...\n")); #endif #ifdef LIBRAW_LIBRARY_BUILD RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2); #endif hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); cmsDoTransform (hTransform, image, image, width*height); raw_color = 1; /* Don't use rgb_cam with a profile */ cmsDeleteTransform (hTransform); cmsCloseProfile (hOutProfile); quit: cmsCloseProfile (hInProfile); #ifdef LIBRAW_LIBRARY_BUILD RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2); #endif }
static int read_dir(const char *dir_name, int opts, OSMatch *restriction) { size_t dir_size; char f_name[PATH_MAX + 2]; short is_nfs; DIR *dp; struct dirent *entry; f_name[PATH_MAX + 1] = '\0'; /* Directory should be valid */ if ((dir_name == NULL) || ((dir_size = strlen(dir_name)) > PATH_MAX)) { merror(NULL_ERROR, ARGV0); return (-1); } /* Should we check for NFS? */ if(syscheck.skip_nfs) { is_nfs = IsNFS(dir_name); if(is_nfs != 0) { // Error will be -1, and 1 means skipped return(is_nfs); } } /* Open the directory given */ dp = opendir(dir_name); if (!dp) { if (errno == ENOTDIR) { if (read_file(dir_name, opts, restriction) == 0) { return (0); } } #ifdef WIN32 int di = 0; char *(defaultfilesn[]) = { "C:\\autoexec.bat", "C:\\config.sys", "C:\\WINDOWS/System32/eventcreate.exe", "C:\\WINDOWS/System32/eventtriggers.exe", "C:\\WINDOWS/System32/tlntsvr.exe", "C:\\WINDOWS/System32/Tasks", NULL }; while (defaultfilesn[di] != NULL) { if (strcmp(defaultfilesn[di], dir_name) == 0) { break; } di++; } if (defaultfilesn[di] == NULL) { merror("%s: WARN: Error opening directory: '%s': %s ", ARGV0, dir_name, strerror(errno)); } #else merror("%s: WARN: Error opening directory: '%s': %s ", ARGV0, dir_name, strerror(errno)); #endif /* WIN32 */ return (-1); } /* Check for real time flag */ if (opts & CHECK_REALTIME) { #if defined(INOTIFY_ENABLED) || defined(WIN32) realtime_adddir(dir_name); #else merror("%s: WARN: realtime monitoring request on unsupported system for '%s'", ARGV0, dir_name ); #endif } while ((entry = readdir(dp)) != NULL) { char *s_name; /* Ignore . and .. */ if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { continue; } strncpy(f_name, dir_name, PATH_MAX); s_name = f_name; s_name += dir_size; /* Check if the file name is already null terminated */ if (*(s_name - 1) != '/') { *s_name++ = '/'; } *s_name = '\0'; strncpy(s_name, entry->d_name, PATH_MAX - dir_size - 2); /* Check integrity of the file */ read_file(f_name, opts, restriction); } closedir(dp); return (0); }
/** main **/ int main(int argc, char **argv) { char *dir = DEFAULTDIR; char *group = GROUPGLOBAL; char *user = USER; char *agent_id = NULL; int gid = 0; int uid = 0; int c = 0, info_agent = 0, update_rootcheck = 0, list_agents = 0, show_last = 0, resolved_only = 0; int active_only = 0, csv_output = 0; char shost[512]; /* Setting the name */ OS_SetName(ARGV0); /* user arguments */ if(argc < 2) { helpmsg(); } while((c = getopt(argc, argv, "VhqrDdLlcsu:i:")) != -1) { switch(c){ case 'V': print_version(); break; case 'h': helpmsg(); break; case 'D': nowDebug(); break; case 'l': list_agents++; break; case 's': csv_output = 1; break; case 'c': active_only++; break; case 'r': resolved_only = 1; break; case 'q': resolved_only = 2; break; case 'L': show_last = 1; break; case 'i': info_agent++; if(!optarg) { merror("%s: -u needs an argument",ARGV0); helpmsg(); } agent_id = optarg; break; case 'u': if(!optarg) { merror("%s: -u needs an argument",ARGV0); helpmsg(); } agent_id = optarg; update_rootcheck = 1; break; default: helpmsg(); break; } } /* Getting the group name */ gid = Privsep_GetGroup(group); uid = Privsep_GetUser(user); if(gid < 0) { ErrorExit(USER_ERROR, ARGV0, user, group); } /* Setting the group */ if(Privsep_SetGroup(gid) < 0) { ErrorExit(SETGID_ERROR,ARGV0, group); } /* Chrooting to the default directory */ if(Privsep_Chroot(dir) < 0) { ErrorExit(CHROOT_ERROR, ARGV0, dir); } /* Inside chroot now */ nowChroot(); /* Setting the user */ if(Privsep_SetUser(uid) < 0) { ErrorExit(SETUID_ERROR, ARGV0, user); } /* Getting servers hostname */ memset(shost, '\0', 512); if(gethostname(shost, 512 -1) != 0) { strncpy(shost, "localhost", 32); return(0); } /* Listing available agents. */ if(list_agents) { if(!csv_output) { printf("\nOSSEC HIDS %s. List of available agents:", ARGV0); printf("\n ID: 000, Name: %s (server), IP: 127.0.0.1, " "Active/Local\n", shost); } else { printf("000,%s (server),127.0.0.1,Active/Local,\n", shost); } print_agents(1, active_only, csv_output); printf("\n"); exit(0); } /* Update rootcheck database. */ if(update_rootcheck) { /* Cleaning all agents (and server) db. */ if(strcmp(agent_id, "all") == 0) { DIR *sys_dir; struct dirent *entry; sys_dir = opendir(ROOTCHECK_DIR); if(!sys_dir) { ErrorExit("%s: Unable to open: '%s'", ARGV0, ROOTCHECK_DIR); } while((entry = readdir(sys_dir)) != NULL) { FILE *fp; char full_path[OS_MAXSTR +1]; /* Do not even attempt to delete . and .. :) */ if((strcmp(entry->d_name,".") == 0)|| (strcmp(entry->d_name,"..") == 0)) { continue; } snprintf(full_path, OS_MAXSTR,"%s/%s", ROOTCHECK_DIR, entry->d_name); fp = fopen(full_path, "w"); if(fp) { fclose(fp); } if(entry->d_name[0] == '.') { unlink(full_path); } } closedir(sys_dir); printf("\n** Policy and auditing database updated.\n\n"); exit(0); } else if((strcmp(agent_id, "000") == 0) || (strcmp(agent_id, "local") == 0)) { char final_dir[1024]; FILE *fp; snprintf(final_dir, 1020, "/%s/rootcheck", ROOTCHECK_DIR); fp = fopen(final_dir, "w"); if(fp) { fclose(fp); } unlink(final_dir); printf("\n** Policy and auditing database updated.\n\n"); exit(0); } /* Database from remote agents. */ else { int i; keystore keys; OS_ReadKeys(&keys); i = OS_IsAllowedID(&keys, agent_id); if(i < 0) { printf("\n** Invalid agent id '%s'.\n", agent_id); helpmsg(); } /* Deleting syscheck */ delete_rootcheck(keys.keyentries[i]->name, keys.keyentries[i]->ip->ip, 0); printf("\n** Policy and auditing database updated.\n\n"); exit(0); } } /* Printing information from an agent. */ if(info_agent) { int i; char final_ip[128 +1]; char final_mask[128 +1]; keystore keys; if((strcmp(agent_id, "000") == 0) || (strcmp(agent_id, "local") == 0)) { if(!csv_output) printf("\nPolicy and auditing events for local system '%s - %s':\n", shost, "127.0.0.1"); print_rootcheck(NULL, NULL, NULL, resolved_only, csv_output, show_last); } else { OS_ReadKeys(&keys); i = OS_IsAllowedID(&keys, agent_id); if(i < 0) { printf("\n** Invalid agent id '%s'.\n", agent_id); helpmsg(); } /* Getting netmask from ip. */ final_ip[128] = '\0'; final_mask[128] = '\0'; getNetmask(keys.keyentries[i]->ip->netmask, final_mask, 128); snprintf(final_ip, 128, "%s%s",keys.keyentries[i]->ip->ip, final_mask); if(!csv_output) printf("\nPolicy and auditing events for agent " "'%s (%s) - %s':\n", keys.keyentries[i]->name, keys.keyentries[i]->id, final_ip); print_rootcheck(keys.keyentries[i]->name, keys.keyentries[i]->ip->ip, NULL, resolved_only, csv_output, show_last); } exit(0); } printf("\n** Invalid argument combination.\n"); helpmsg(); return(0); }
/* check_rc_files: * Read the file pointer specified (rootkit_files) * and check if the configured file is there */ void check_rc_files(char *basedir, FILE *fp) { char buf[OS_SIZE_1024 +1]; char file_path[OS_SIZE_1024 +1]; char *file; char *name; char *link; int _errors = 0; int _total = 0; debug1("%s: DEBUG: Starting on check_rc_files", ARGV0); while(fgets(buf, OS_SIZE_1024, fp) != NULL) { char *nbuf; /* Removing end of line */ nbuf = strchr(buf, '\n'); if(nbuf) { *nbuf = '\0'; } /* Assigning buf to be used */ nbuf = buf; /* Excluding commented lines or blanked ones */ while(*nbuf != '\0') { if(*nbuf == ' ' || *nbuf == '\t') { nbuf++; continue; } else if(*nbuf == '#') goto newline; else break; } if(*nbuf == '\0') goto newline; /* File now may be valid */ file = nbuf; name = nbuf; /* Getting the file and the rootkit name */ while(*nbuf != '\0') { if(*nbuf == ' ' || *nbuf == '\t') { /* Setting the limit for the file */ *nbuf = '\0'; nbuf++; break; } else { nbuf++; } } if(*nbuf == '\0') goto newline; /* Some ugly code to remove spaces and \t */ while(*nbuf != '\0') { if(*nbuf == '!') { nbuf++; if(*nbuf == ' ' || *nbuf == '\t') { nbuf++; name = nbuf; break; } } else if(*nbuf == ' ' || *nbuf == '\t') { nbuf++; continue; } else { goto newline; } } /* Getting the link (if present) */ link = strchr(nbuf, ':'); if(link) { *link = '\0'; link++; if(*link == ':') { link++; } } /* Cleaning any space of \t at the end */ nbuf = strchr(nbuf, ' '); if(nbuf) { *nbuf = '\0'; } nbuf = strchr(nbuf, '\t'); if(nbuf) { *nbuf = '\0'; } _total++; /* Checking if it is a file to search everywhere */ if(*file == '*') { if(rk_sys_count >= MAX_RK_SYS) { merror(MAX_RK_MSG, ARGV0, MAX_RK_SYS); } else { /* Removing * / from the file */ file++; if(*file == '/') file++; /* Memory assignment */ rk_sys_file[rk_sys_count] = strdup(file); rk_sys_name[rk_sys_count] = strdup(name); if(!rk_sys_name[rk_sys_count] || !rk_sys_file[rk_sys_count] ) { merror(MEM_ERROR, ARGV0); if(rk_sys_file[rk_sys_count]) free(rk_sys_file[rk_sys_count]); if(rk_sys_name[rk_sys_count]) free(rk_sys_name[rk_sys_count]); rk_sys_file[rk_sys_count] = NULL; rk_sys_name[rk_sys_count] = NULL; } rk_sys_count++; /* Always assigning the last as NULL */ rk_sys_file[rk_sys_count] = NULL; rk_sys_name[rk_sys_count] = NULL; } continue; } snprintf(file_path, OS_SIZE_1024, "%s/%s",basedir, file); /* Checking if file exists */ if(is_file(file_path)) { char op_msg[OS_SIZE_1024 +1]; _errors = 1; snprintf(op_msg, OS_SIZE_1024, "Rootkit '%s' detected " "by the presence of file '%s'.",name, file_path); notify_rk(ALERT_ROOTKIT_FOUND, op_msg); } newline: continue; } if(_errors == 0) { char op_msg[OS_SIZE_1024 +1]; snprintf(op_msg,OS_SIZE_1024,"No presence of public rootkits detected." " Analyzed %d files.", _total); notify_rk(ALERT_OK, op_msg); } }
/* Signs a log file */ void OS_SignLog(const char *logfile, const char *logfile_old, int log_missing) { os_md5 mf_sum; os_md5 mf_sum_old; os_sha1 sf_sum; os_sha1 sf_sum_old; char logfilesum[OS_FLSIZE +1]; char logfilesum_old[OS_FLSIZE +1]; FILE *fp; /* Clearing the memory */ memset(logfilesum, '\0', OS_FLSIZE +1); memset(logfilesum_old, '\0', OS_FLSIZE +1); /* Setting the umask */ umask(0027); /* Creating the checksum file names */ snprintf(logfilesum, OS_FLSIZE, "%s.sum", logfile); snprintf(logfilesum_old, OS_FLSIZE, "%s.sum", logfile_old); /* generating md5 of the old file */ if(OS_MD5_File(logfilesum_old, mf_sum_old) < 0) { merror("%s: No previous md5 checksum found: '%s'. " "Starting over.", ARGV0, logfilesum_old); strncpy(mf_sum_old, "none", 6); } /* generating sha1 of the old file. */ if(OS_SHA1_File(logfilesum_old, sf_sum_old) < 0) { merror("%s: No previous sha1 checksum found: '%s'. " "Starting over.", ARGV0, logfilesum_old); strncpy(sf_sum_old, "none", 6); } /* Generating md5 of the current file */ if(OS_MD5_File(logfile, mf_sum) < 0) { if(log_missing) merror("%s: File '%s' not found. MD5 checksum skipped.", ARGV0, logfile); strncpy(mf_sum, "none", 6); } /* Generating sha1 of the current file */ if(OS_SHA1_File(logfile, sf_sum) < 0) { if(log_missing) merror("%s: File '%s' not found. SHA1 checksum skipped.", ARGV0, logfile); strncpy(sf_sum, "none", 6); } fp = fopen(logfilesum, "w"); if(!fp) { merror(FOPEN_ERROR, ARGV0, logfilesum, errno, strerror(errno)); return; } fprintf(fp, "Current checksum:\n"); fprintf(fp, "MD5 (%s) = %s\n", logfile, mf_sum); fprintf(fp, "SHA1 (%s) = %s\n\n", logfile, sf_sum); fprintf(fp, "Chained checksum:\n"); fprintf(fp, "MD5 (%s) = %s\n", logfilesum_old, mf_sum_old); fprintf(fp, "SHA1 (%s) = %s\n\n", logfilesum_old, sf_sum_old); fclose(fp); return; }
/** void WinExecdRun(char *exec_msg) */ void WinExecdRun(char *exec_msg) { time_t curr_time; int i,j; int timeout_value; int added_before = 0; char **timeout_args; char *tmp_msg = NULL; char *name; char *command; char *cmd_user; char *cmd_ip; char buffer[OS_MAXSTR + 1]; timeout_data *timeout_entry; /* Currently time */ curr_time = time(0); /* Getting application name */ name = exec_msg; /* Zeroing the name */ tmp_msg = strchr(exec_msg, ' '); if(!tmp_msg) { merror(EXECD_INV_MSG, ARGV0, exec_msg); return; } *tmp_msg = '\0'; tmp_msg++; /* Getting user. */ cmd_user = tmp_msg; tmp_msg = strchr(tmp_msg, ' '); if(!tmp_msg) { merror(EXECD_INV_MSG, ARGV0, cmd_user); return; } *tmp_msg = '\0'; tmp_msg++; /* Getting ip. */ cmd_ip = tmp_msg; tmp_msg = strchr(tmp_msg, ' '); if(!tmp_msg) { merror(EXECD_INV_MSG, ARGV0, cmd_ip); return; } *tmp_msg = '\0'; tmp_msg++; /* Getting the command to execute (valid name) */ command = GetCommandbyName(name, &timeout_value); if(!command) { ReadExecConfig(); command = GetCommandbyName(name, &timeout_value); if(!command) { merror(EXEC_INV_NAME, ARGV0, name); return; } } /* Command not present. */ if(command[0] == '\0') return; /* Allocating memory for the timeout argument */ os_calloc(MAX_ARGS+2, sizeof(char *), timeout_args); /* Adding initial variables to the timeout cmd */ snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"", command, DELETE_ENTRY, cmd_user, cmd_ip, tmp_msg); os_strdup(buffer, timeout_args[0]); timeout_args[1] = NULL; /* Getting size for the strncmp */ i = 0, j = 0; while(buffer[i] != '\0') { if(buffer[i] == ' ') j++; i++; if(j == 4) break; } /* Check this command was already executed. */ timeout_node = OSList_GetFirstNode(timeout_list); added_before = 0; while(timeout_node) { timeout_data *list_entry; list_entry = (timeout_data *)timeout_node->data; if(strncmp(list_entry->command[0], timeout_args[0], i) == 0) { /* Means we executed this command before * and we don't need to add it again. */ added_before = 1; /* updating the timeout */ list_entry->time_of_addition = curr_time; break; } /* Continue with the next entry in timeout list*/ timeout_node = OSList_GetNextNode(timeout_list); } /* If it wasn't added before, do it now */ if(!added_before) { snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"", command, ADD_ENTRY, cmd_user, cmd_ip, tmp_msg); /* executing command */ ExecCmd_Win32(buffer); /* We don't need to add to the list if the timeout_value == 0 */ if(timeout_value) { /* Creating the timeout entry */ os_calloc(1, sizeof(timeout_data), timeout_entry); timeout_entry->command = timeout_args; timeout_entry->time_of_addition = curr_time; timeout_entry->time_to_block = timeout_value; /* Adding command to the timeout list */ if(!OSList_AddData(timeout_list, timeout_entry)) { merror(LIST_ADD_ERROR, ARGV0); FreeTimeoutEntry(timeout_entry); } } /* If no timeout, we still need to free it in here */ else { char **ss_ta = timeout_args; while(*timeout_args) { os_free(*timeout_args); *timeout_args = NULL; timeout_args++; } os_free(ss_ta); } } /* We didn't add it to the timeout list */ else { char **ss_ta = timeout_args; /* Clear the timeout arguments */ while(*timeout_args) { os_free(*timeout_args); *timeout_args = NULL; timeout_args++; } os_free(ss_ta); } }