/* Start the event logging for windows */ void win_startel(char *evt_log) { int entries_count = 0; /* Maximum size */ if (el_last == 9) { merror(EVTLOG_DUP, ARGV0, evt_log); return; } /* Create the DLL hash */ if (!dll_hash) { dll_hash = OSHash_Create(); if (!dll_hash) { merror("%s: ERROR: Unable to create DLL hash.", ARGV0); } } /* Start event log -- going to last available record */ if ((entries_count = startEL(evt_log, &el[el_last])) < 0) { merror(INV_EVTLOG, ARGV0, evt_log); return; } else { readel(&el[el_last], 0); } el_last++; }
/** void readel(os_el *el) * Reads the event log. */ void readel(os_el *el, int printit) { DWORD _evtid = 65535; DWORD nstr; DWORD user_size; DWORD domain_size; DWORD read, needed; int size_left; int str_size; int id; char mbuffer[BUFFER_SIZE +1]; LPSTR sstr = NULL; char *tmp_str = NULL; char *category; char *source; char *computer_name; char *descriptive_msg; char el_user[OS_FLSIZE +1]; char el_domain[OS_FLSIZE +1]; char el_string[OS_MAXSTR +1]; char final_msg[OS_MAXSTR +1]; LPSTR el_sstring[OS_FLSIZE +1]; /* Er must point to the mbuffer */ el->er = (EVENTLOGRECORD *) &mbuffer; /* Zeroing the values */ el_string[OS_MAXSTR] = '\0'; el_user[OS_FLSIZE] = '\0'; el_domain[OS_FLSIZE] = '\0'; final_msg[OS_MAXSTR] = '\0'; el_sstring[0] = NULL; el_sstring[OS_FLSIZE] = NULL; /* Event log is not open */ if(!el->h) { return; } /* Reading the event log */ while(ReadEventLog(el->h, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, 0, el->er, BUFFER_SIZE -1, &read, &needed)) { if(!printit) { /* Setting er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; continue; } while(read > 0) { /* We need to initialize every variable before the loop */ category = el_getCategory(el->er->EventType); source = (LPSTR) ((LPBYTE) el->er + sizeof(EVENTLOGRECORD)); computer_name = source + strlen(source) + 1; descriptive_msg = NULL; /* Getting event id. */ id = (int)el->er->EventID & _evtid; /* Initialing domain/user size */ user_size = 255; domain_size = 255; el_domain[0] = '\0'; el_user[0] = '\0'; /* We must have some description */ if(el->er->NumStrings) { size_left = OS_MAXSTR - OS_SIZE_1024; sstr = (LPSTR)((LPBYTE)el->er + el->er->StringOffset); el_string[0] = '\0'; for (nstr = 0;nstr < el->er->NumStrings;nstr++) { str_size = strlen(sstr); if(size_left > 1) { strncat(el_string, sstr, size_left); } tmp_str = strchr(el_string, '\0'); if(tmp_str) { *tmp_str = ' '; tmp_str++; *tmp_str = '\0'; } else { merror("%s: Invalid application string (size+)", ARGV0); } size_left-=str_size + 2; if(nstr <= 92) { el_sstring[nstr] = (LPSTR)sstr; el_sstring[nstr +1] = NULL; } sstr = strchr( (LPSTR)sstr, '\0'); if(sstr) sstr++; else break; } /* Get a more descriptive message (if available) */ if(isVista && strcmp(el->name, "Security") == 0) { descriptive_msg = el_vista_getMessage(id, el_sstring); } else { descriptive_msg = el_getMessage(el->er, el->name, source, el_sstring); } if(descriptive_msg != NULL) { /* Remove any \n or \r */ /* Replace tabs from the argument field to spaces. * So whenever we have option:\tvalue\t, it will * become option: value\t */ tmp_str = descriptive_msg; while(*tmp_str != '\0') { if(*tmp_str == '\n') *tmp_str = ' '; else if(*tmp_str == '\r') *tmp_str = ' '; else if((*tmp_str == ':') && (tmp_str[1] == '\t')) { tmp_str[1] = ' '; tmp_str++; } tmp_str++; } } } else { strncpy(el_string, "(no message)", 128); } /* Getting username */ if(el->er->UserSidLength) { SID_NAME_USE account_type; if(!LookupAccountSid(NULL, (SID *)((LPSTR)el->er + el->er->UserSidOffset), el_user, &user_size, el_domain, &domain_size, &account_type)) { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else if(isVista && strcmp(el->name, "Security") == 0) { int uid_array_id = -1; switch(id) { case 4624: uid_array_id = 5; break; case 4634: uid_array_id = 1; break; case 4647: uid_array_id = 1; break; case 4769: uid_array_id = 0; break; } if((uid_array_id >= 0) && el_sstring[uid_array_id] && el_sstring[uid_array_id +1]) { strncpy(el_user, el_sstring[uid_array_id], OS_FLSIZE); strncpy(el_domain, el_sstring[uid_array_id +1], OS_FLSIZE); } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } } else { strncpy(el_user, "(no user)", 255); strncpy(el_domain, "no domain", 255); } if(printit) { DWORD _evtid = 65535; int id = (int)el->er->EventID & _evtid; final_msg[OS_MAXSTR - OS_LOG_HEADER] = '\0'; final_msg[OS_MAXSTR - OS_LOG_HEADER -1] = '\0'; snprintf(final_msg, OS_MAXSTR - OS_LOG_HEADER -1, "WinEvtLog: %s: %s(%d): %s: %s: %s: %s: %s", el->name, category, id, source, el_user, el_domain, computer_name, descriptive_msg != NULL?descriptive_msg:el_string); if(SendMSG(logr_queue, final_msg, "WinEvtLog", LOCALFILE_MQ) < 0) { merror(QUEUE_SEND, ARGV0); } } if(descriptive_msg != NULL) { LocalFree(descriptive_msg); } /* Changing the point to the er */ read -= el->er->Length; el->er = (EVENTLOGRECORD *)((LPBYTE) el->er + el->er->Length); } /* Setting er to the beginning of the buffer */ el->er = (EVENTLOGRECORD *)&mbuffer; } id = GetLastError(); if(id == ERROR_HANDLE_EOF) { return; } /* Event log was cleared. */ else if(id == ERROR_EVENTLOG_FILE_CHANGED) { char msg_alert[512 +1]; msg_alert[512] = '\0'; merror("%s: WARN: Event log cleared: '%s'", ARGV0, el->name); /* Send message about cleared */ snprintf(msg_alert, 512, "ossec: Event log cleared: '%s'", el->name); SendMSG(logr_queue, msg_alert, "WinEvtLog", LOCALFILE_MQ); /* Closing the event log and reopenning. */ CloseEventLog(el->h); el->h = NULL; /* Reopening. */ if(startEL(el->name, el) < 0) { merror("%s: ERROR: Unable to reopen event log '%s'", ARGV0, el->name); } } else { debug1("%s: WARN: Error reading event log: %d", ARGV0, id); } }
/** void win_startel() * Starts the event logging for windows */ void win_startel(char *evt_log) { startEL(evt_log, &el[el_last]); readel(&el[el_last],1); el_last++; }