1 /* @(#) $Id: ./src/analysisd/cleanevent.c, 2011/09/08 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
12 * License details at the LICENSE file included with OSSEC or
13 * online at: http://www.ossec.net/en/licensing.html
18 #include "os_regex/os_regex.h"
22 #include "eventinfo.h"
23 #include "analysisd.h"
28 /* To translante between month (int) to month (char) */
29 char *(month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
30 "Sep","Oct","Nov","Dec"};
35 /* OS_CleanMSG v0.3: 2006/03/04
36 * Format a received message in the
37 * Eventinfo structure.
39 int OS_CleanMSG(char *msg, Eventinfo *lf)
45 /* The message is formated in the following way:
46 * id:location:message.
50 /* Ignoring the id of the message in here */
55 /* Setting pieces as the message */
56 pieces = strchr(msg, ':');
59 merror(FORMAT_ERROR, ARGV0);
67 os_strdup(msg, lf->location);
70 /* Getting the log length */
71 loglen = strlen(pieces) + 1;
74 /* Assigning the values in the strucuture (lf->full_log) */
75 os_malloc((2*loglen) +1, lf->full_log);
78 /* Setting the whole message at full_log */
79 strncpy(lf->full_log, pieces, loglen);
82 /* Log is the one used for parsing in the decoders and rules */
83 lf->log = lf->full_log+loglen;
84 strncpy(lf->log, pieces, loglen);
88 /* Checking for the syslog date format.
89 * ( ex: Dec 29 10:00:01
90 * or 2007-06-14T15:48:55-04:00 for syslog-ng isodate
91 * or 2009-05-22T09:36:46.214994-07:00 for rsyslog )
99 (pieces[12] == ':') &&
100 (pieces[15] == ' ') && (lf->log+=16)
105 (pieces[4] == '-') &&
106 (pieces[7] == '-') &&
107 (pieces[10] == 'T') &&
108 (pieces[13] == ':') &&
109 (pieces[16] == ':') &&
112 ((pieces[22] == ':') &&
113 (pieces[25] == ' ') && (lf->log+=26)) ||
115 ((pieces[19] == '.') &&
116 (pieces[29] == ':') && (lf->log+=32))
122 /* Checking for an extra space in here */
128 pieces = lf->hostname = lf->log;
131 /* Checking for a valid hostname */
132 while(isValidChar(*pieces) == 1)
138 /* Checking if it is a syslog without hostname (common on Solaris. */
139 if(*pieces == ':' && pieces[1] == ' ')
141 /* Getting solaris 8/9 messages without hostname.
142 * In these cases, the process_name should be there.
143 * http://www.ossec.net/wiki/index.php/Log_Samples_Solaris
145 lf->program_name = lf->hostname;
148 /* Ending the program name string. */
156 /* Extracting the hostname */
157 else if(*pieces != ' ')
159 /* Invalid hostname */
165 /* Ending the hostname string */
169 /* Moving pieces to the beginning of the log message */
174 /* Getting program_name */
175 lf->program_name = pieces;
178 /* Extracting program_name */
182 * p_name[pid]: [ID xx facility.severity]
183 * auth|security:info p_name:
186 while(isValidChar(*pieces) == 1)
192 /* Checking for the first format: p_name: */
193 if((*pieces == ':') && (pieces[1] == ' '))
199 /* Checking for the second format: p_name[pid]: */
200 else if((*pieces == '[') && (isdigit((int)pieces[1])))
204 while(isdigit((int)*pieces))
207 if((*pieces == ']')&& (pieces[1] == ':')&& (pieces[2] == ' '))
211 /* Some systems are not terminating the program name with
212 * the ':'. Working around this in here..
214 else if((*pieces == ']') && (pieces[1] == ' '))
220 /* Fixing for some weird log formats. */
222 while(isdigit((int)*pieces))
230 lf->program_name = NULL;
234 else if((*pieces == '|') && islower((int)pieces[1]))
238 /* Removing facility */
239 while(isalnum((int)*pieces))
245 /* Removing severity. */
247 while(isalnum((int)*pieces))
253 lf->program_name = pieces;
256 /* Getting program name again. */
257 while(isValidChar(*pieces) == 1)
260 /* Checking for the first format: p_name: */
261 if((*pieces == ':') && (pieces[1] == ' '))
267 /* Checking for the second format: p_name[pid]: */
268 else if((*pieces == '[') && (isdigit((int)pieces[1])))
272 while(isdigit((int)*pieces))
275 if((*pieces == ']') && (pieces[1] == ':') &&
289 lf->program_name = NULL;
296 lf->program_name = NULL;
302 lf->program_name = NULL;
307 /* Removing [ID xx facility.severity] */
310 /* Setting log after program name */
313 if((pieces[0] == '[') &&
314 (pieces[1] == 'I') &&
315 (pieces[2] == 'D') &&
320 /* Going after the ] */
321 pieces = strchr(pieces, ']');
330 /* Getting program name size */
333 lf->p_name_size = strlen(lf->program_name);
337 /* xferlog date format
338 * Mon Apr 17 18:27:14 2006 1 64.160.42.130
340 else if((loglen > 28) &&
343 (pieces[10] == ' ')&&
344 (pieces[13] == ':')&&
345 (pieces[16] == ':')&&
346 (pieces[19] == ' ')&&
347 (pieces[24] == ' ')&&
350 /* Moving log to the beginning of the message */
355 /* Checking for snort date format
356 * ex: 01/28-09:13:16.240702 [**]
358 else if( (loglen > 24) &&
359 (pieces[2] == '/') &&
360 (pieces[5] == '-') &&
361 (pieces[8] == ':') &&
362 (pieces[11]== ':') &&
363 (pieces[14]== '.') &&
364 (pieces[21] == ' ') )
369 /* Checking for apache log format */
370 /* [Fri Feb 11 18:06:35 2004] [warn] */
371 else if( (loglen > 27) &&
372 (pieces[0] == '[') &&
373 (pieces[4] == ' ') &&
374 (pieces[8] == ' ') &&
375 (pieces[11]== ' ') &&
376 (pieces[14]== ':') &&
377 (pieces[17]== ':') &&
378 (pieces[20]== ' ') &&
384 /* Checking for the osx asl log format.
386 * [Time 2006.12.28 15:53:55 UTC] [Facility auth] [Sender sshd] [PID 483] [Message error: PAM: Authentication failure for username from 192.168.0.2] [Level 3] [UID -2] [GID -2] [Host Hostname]
387 * [Time 2006.11.02 14:02:11 UTC] [Facility auth] [Sender sshd] [PID 856]
388 [Message refused connect from 59.124.44.34] [Level 4] [UID -2] [GID -2]
389 [Host robert-wyatts-emac]
391 else if((loglen > 26) &&
392 (pieces[0] == '[') &&
393 (pieces[1] == 'T') &&
394 (pieces[5] == ' ') &&
395 (pieces[10] == '.') &&
396 (pieces[13] == '.') &&
397 (pieces[16] == ' ') &&
400 /* Do not read more than 1 message entry -> log tampering */
401 short unsigned int done_message = 0;
404 /* Removing the date */
407 /* Getting the desired values */
408 pieces = strchr(lf->log, '[');
413 /* Getting the sender (set to program name) */
414 if((strncmp(pieces, "Sender ", 7) == 0) &&
415 (lf->program_name == NULL))
418 lf->program_name = pieces;
420 /* Getting the closing brackets */
421 pieces = strchr(pieces, ']');
426 /* Setting program_name size */
427 lf->p_name_size = strlen(lf->program_name);
431 /* Invalid program name */
434 lf->program_name = NULL;
439 /* Getting message */
440 else if((strncmp(pieces, "Message ", 8) == 0) &&
448 /* Getting the closing brackets */
449 pieces = strchr(pieces, ']');
455 /* Invalid log closure */
462 /* Getting hostname */
463 else if(strncmp(pieces, "Host ", 5) == 0)
466 lf->hostname = pieces;
468 /* Getting the closing brackets */
469 pieces = strchr(pieces, ']');
476 /* Invalid hostname */
484 /* Getting next entry */
485 pieces = strchr(pieces, '[');
489 /* Checking for squid date format
490 * 1140804070.368 11623
491 * seconds from 00:00:00 1970-01-01 UTC
493 else if((loglen > 32) &&
494 (pieces[0] == '1') &&
495 (pieces[10] == '.') &&
496 (pieces[14] == ' ') &&
497 (isdigit((int)pieces[13])) &&
498 (isdigit((int)pieces[1])) &&
499 ((pieces[21] == ' ')||(pieces[22] == ' ')))
503 /* We need to start at the size of the event */
504 while(*lf->log == ' ')
511 /* Every message must be in the format
512 * hostname->location or
513 * (agent) ip->location.
517 /* Setting hostname for local messages */
518 if(lf->location[0] == '(')
520 /* Messages from an agent */
521 lf->hostname = lf->location;
523 else if(lf->hostname == NULL)
525 lf->hostname = __shost;
529 /* Setting up the event data */
531 p = localtime(&c_time);
535 /* Assign hour, day, year and month values */
536 lf->day = p->tm_mday;
537 lf->year = p->tm_year+1900;
538 strncpy(lf->mon,month[p->tm_mon],3);
539 snprintf(lf->hour, 9, "%02d:%02d:%02d",
546 /* Setting the global hour/weekday */
547 __crt_hour = p->tm_hour;
548 __crt_wday = p->tm_wday;
555 print_out("**Phase 1: Completed pre-decoding.");
556 print_out(" full event: '%s'", lf->full_log);
557 print_out(" hostname: '%s'", lf->hostname);
558 print_out(" program_name: '%s'", lf->program_name);
559 print_out(" log: '%s'", lf->log);