3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
11 * License details at the LICENSE file included with OSSEC or
12 * online at: http://www.ossec.net/en/licensing.html
17 #include "os_regex/os_regex.h"
21 #include "eventinfo.h"
22 #include "analysisd.h"
27 /* To translante between month (int) to month (char) */
28 char *(month[])={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
29 "Sep","Oct","Nov","Dec"};
34 /* OS_CleanMSG v0.3: 2006/03/04
35 * Format a received message in the
36 * Eventinfo structure.
38 int OS_CleanMSG(char *msg, Eventinfo *lf)
44 /* The message is formated in the following way:
45 * id:location:message.
49 /* Ignoring the id of the message in here */
54 /* Setting pieces as the message */
55 pieces = strchr(msg, ':');
58 merror(FORMAT_ERROR, ARGV0);
66 os_strdup(msg, lf->location);
69 /* Getting the log length */
70 loglen = strlen(pieces) + 1;
73 /* Assigning the values in the strucuture (lf->full_log) */
74 os_malloc((2*loglen) +1, lf->full_log);
77 /* Setting the whole message at full_log */
78 strncpy(lf->full_log, pieces, loglen);
81 /* Log is the one used for parsing in the decoders and rules */
82 lf->log = lf->full_log+loglen;
83 strncpy(lf->log, pieces, loglen);
87 /* Checking for the syslog date format.
88 * ( ex: Dec 29 10:00:01
89 * or 2007-06-14T15:48:55-04:00 for syslog-ng isodate
90 * or 2009-05-22T09:36:46.214994-07:00 for rsyslog )
98 (pieces[12] == ':') &&
99 (pieces[15] == ' ') && (lf->log+=16)
104 (pieces[4] == '-') &&
105 (pieces[7] == '-') &&
106 (pieces[10] == 'T') &&
107 (pieces[13] == ':') &&
108 (pieces[16] == ':') &&
111 ((pieces[22] == ':') &&
112 (pieces[25] == ' ') && (lf->log+=26)) ||
114 ((pieces[19] == '.') &&
115 (pieces[29] == ':') && (lf->log+=32))
121 /* Checking for an extra space in here */
127 pieces = lf->hostname = lf->log;
130 /* Checking for a valid hostname */
131 while(isValidChar(*pieces) == 1)
137 /* Checking if it is a syslog without hostname (common on Solaris. */
138 if(*pieces == ':' && pieces[1] == ' ')
140 /* Getting solaris 8/9 messages without hostname.
141 * In these cases, the process_name should be there.
142 * http://www.ossec.net/wiki/index.php/Log_Samples_Solaris
144 lf->program_name = lf->hostname;
147 /* Ending the program name string. */
155 /* Extracting the hostname */
156 else if(*pieces != ' ')
158 /* Invalid hostname */
164 /* Ending the hostname string */
168 /* Moving pieces to the beginning of the log message */
173 /* Getting program_name */
174 lf->program_name = pieces;
177 /* Extracting program_name */
181 * p_name[pid]: [ID xx facility.severity]
182 * auth|security:info p_name:
185 while(isValidChar(*pieces) == 1)
191 /* Checking for the first format: p_name: */
192 if((*pieces == ':') && (pieces[1] == ' '))
198 /* Checking for the second format: p_name[pid]: */
199 else if((*pieces == '[') && (isdigit((int)pieces[1])))
203 while(isdigit((int)*pieces))
206 if((*pieces == ']')&& (pieces[1] == ':')&& (pieces[2] == ' '))
210 /* Some systems are not terminating the program name with
211 * the ':'. Working around this in here..
213 else if((*pieces == ']') && (pieces[1] == ' '))
219 /* Fixing for some weird log formats. */
221 while(isdigit((int)*pieces))
229 lf->program_name = NULL;
233 else if((*pieces == '|') && islower((int)pieces[1]))
237 /* Removing facility */
238 while(isalnum((int)*pieces))
244 /* Removing severity. */
246 while(isalnum((int)*pieces))
252 lf->program_name = pieces;
255 /* Getting program name again. */
256 while(isValidChar(*pieces) == 1)
259 /* Checking for the first format: p_name: */
260 if((*pieces == ':') && (pieces[1] == ' '))
266 /* Checking for the second format: p_name[pid]: */
267 else if((*pieces == '[') && (isdigit((int)pieces[1])))
271 while(isdigit((int)*pieces))
274 if((*pieces == ']') && (pieces[1] == ':') &&
288 lf->program_name = NULL;
295 lf->program_name = NULL;
301 lf->program_name = NULL;
306 /* Removing [ID xx facility.severity] */
309 /* Setting log after program name */
312 if((pieces[0] == '[') &&
313 (pieces[1] == 'I') &&
314 (pieces[2] == 'D') &&
319 /* Going after the ] */
320 pieces = strchr(pieces, ']');
329 /* Getting program name size */
332 lf->p_name_size = strlen(lf->program_name);
336 /* xferlog date format
337 * Mon Apr 17 18:27:14 2006 1 64.160.42.130
339 else if((loglen > 28) &&
342 (pieces[10] == ' ')&&
343 (pieces[13] == ':')&&
344 (pieces[16] == ':')&&
345 (pieces[19] == ' ')&&
346 (pieces[24] == ' ')&&
349 /* Moving log to the beginning of the message */
354 /* Checking for snort date format
355 * ex: 01/28-09:13:16.240702 [**]
357 else if( (loglen > 24) &&
358 (pieces[2] == '/') &&
359 (pieces[5] == '-') &&
360 (pieces[8] == ':') &&
361 (pieces[11]== ':') &&
362 (pieces[14]== '.') &&
363 (pieces[21] == ' ') )
368 /* Checking for apache log format */
369 /* [Fri Feb 11 18:06:35 2004] [warn] */
370 else if( (loglen > 27) &&
371 (pieces[0] == '[') &&
372 (pieces[4] == ' ') &&
373 (pieces[8] == ' ') &&
374 (pieces[11]== ' ') &&
375 (pieces[14]== ':') &&
376 (pieces[17]== ':') &&
377 (pieces[20]== ' ') &&
383 /* Checking for the osx asl log format.
385 * [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]
386 * [Time 2006.11.02 14:02:11 UTC] [Facility auth] [Sender sshd] [PID 856]
387 [Message refused connect from 59.124.44.34] [Level 4] [UID -2] [GID -2]
388 [Host robert-wyatts-emac]
390 else if((loglen > 26) &&
391 (pieces[0] == '[') &&
392 (pieces[1] == 'T') &&
393 (pieces[5] == ' ') &&
394 (pieces[10] == '.') &&
395 (pieces[13] == '.') &&
396 (pieces[16] == ' ') &&
399 /* Do not read more than 1 message entry -> log tampering */
400 short unsigned int done_message = 0;
403 /* Removing the date */
406 /* Getting the desired values */
407 pieces = strchr(lf->log, '[');
412 /* Getting the sender (set to program name) */
413 if((strncmp(pieces, "Sender ", 7) == 0) &&
414 (lf->program_name == NULL))
417 lf->program_name = pieces;
419 /* Getting the closing brackets */
420 pieces = strchr(pieces, ']');
425 /* Setting program_name size */
426 lf->p_name_size = strlen(lf->program_name);
430 /* Invalid program name */
433 lf->program_name = NULL;
438 /* Getting message */
439 else if((strncmp(pieces, "Message ", 8) == 0) &&
447 /* Getting the closing brackets */
448 pieces = strchr(pieces, ']');
454 /* Invalid log closure */
461 /* Getting hostname */
462 else if(strncmp(pieces, "Host ", 5) == 0)
465 lf->hostname = pieces;
467 /* Getting the closing brackets */
468 pieces = strchr(pieces, ']');
475 /* Invalid hostname */
483 /* Getting next entry */
484 pieces = strchr(pieces, '[');
488 /* Checking for squid date format
489 * 1140804070.368 11623
490 * seconds from 00:00:00 1970-01-01 UTC
492 else if((loglen > 32) &&
493 (pieces[0] == '1') &&
494 (pieces[10] == '.') &&
495 (pieces[14] == ' ') &&
496 (isdigit((int)pieces[13])) &&
497 (isdigit((int)pieces[1])) &&
498 ((pieces[21] == ' ')||(pieces[22] == ' ')))
502 /* We need to start at the size of the event */
503 while(*lf->log == ' ')
510 /* Every message must be in the format
511 * hostname->location or
512 * (agent) ip->location.
516 /* Setting hostname for local messages */
517 if(lf->location[0] == '(')
519 /* Messages from an agent */
520 lf->hostname = lf->location;
522 else if(lf->hostname == NULL)
524 lf->hostname = __shost;
528 /* Setting up the event data */
530 p = localtime(&c_time);
534 /* Assign hour, day, year and month values */
535 lf->day = p->tm_mday;
536 lf->year = p->tm_year+1900;
537 strncpy(lf->mon,month[p->tm_mon],3);
538 snprintf(lf->hour, 9, "%02d:%02d:%02d",
545 /* Setting the global hour/weekday */
546 __crt_hour = p->tm_hour;
547 __crt_wday = p->tm_wday;
554 print_out("**Phase 1: Completed pre-decoding.");
555 print_out(" full event: '%s'", lf->full_log);
556 print_out(" hostname: '%s'", lf->hostname);
557 print_out(" program_name: '%s'", lf->program_name);
558 print_out(" log: '%s'", lf->log);