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);
86 /* check if month contains an umlaut and repair
87 * umlaute are non-ASCII and use 2 slots in the char array
88 * repair to only one slot so we can detect the correct date format in the next step
91 if (pieces[1] == (char) 195) {
92 if (pieces[2] == (char) 164) {
100 /* Checking for the syslog date format.
101 * ( ex: Dec 29 10:00:01
102 * or 2007-06-14T15:48:55-04:00 for syslog-ng isodate
103 * or 2009-05-22T09:36:46.214994-07:00 for rsyslog )
108 (pieces[3] == ' ') &&
109 (pieces[6] == ' ') &&
110 (pieces[9] == ':') &&
111 (pieces[12] == ':') &&
112 (pieces[15] == ' ') && (lf->log+=16)
117 (pieces[4] == '-') &&
118 (pieces[7] == '-') &&
119 (pieces[10] == 'T') &&
120 (pieces[13] == ':') &&
121 (pieces[16] == ':') &&
124 ((pieces[22] == ':') &&
125 (pieces[25] == ' ') && (lf->log+=26)) ||
127 ((pieces[19] == '.') &&
128 (pieces[29] == ':') && (lf->log+=32))
134 /* Checking for an extra space in here */
140 pieces = lf->hostname = lf->log;
143 /* Checking for a valid hostname */
144 while(isValidChar(*pieces) == 1)
150 /* Checking if it is a syslog without hostname (common on Solaris. */
151 if(*pieces == ':' && pieces[1] == ' ')
153 /* Getting solaris 8/9 messages without hostname.
154 * In these cases, the process_name should be there.
155 * http://www.ossec.net/wiki/index.php/Log_Samples_Solaris
157 lf->program_name = lf->hostname;
160 /* Ending the program name string. */
168 /* Extracting the hostname */
169 else if(*pieces != ' ')
171 /* Invalid hostname */
177 /* Ending the hostname string */
181 /* Moving pieces to the beginning of the log message */
186 /* Getting program_name */
187 lf->program_name = pieces;
190 /* Extracting program_name */
194 * p_name[pid]: [ID xx facility.severity]
195 * auth|security:info p_name:
198 while(isValidChar(*pieces) == 1)
204 /* Checking for the first format: p_name: */
205 if((*pieces == ':') && (pieces[1] == ' '))
211 /* Checking for the second format: p_name[pid]: */
212 else if((*pieces == '[') && (isdigit((int)pieces[1])))
216 while(isdigit((int)*pieces))
219 if((*pieces == ']')&& (pieces[1] == ':')&& (pieces[2] == ' '))
223 /* Some systems are not terminating the program name with
224 * the ':'. Working around this in here..
226 else if((*pieces == ']') && (pieces[1] == ' '))
232 /* Fixing for some weird log formats. */
234 while(isdigit((int)*pieces))
242 lf->program_name = NULL;
246 else if((*pieces == '|') && islower((int)pieces[1]))
250 /* Removing facility */
251 while(isalnum((int)*pieces))
257 /* Removing severity. */
259 while(isalnum((int)*pieces))
265 lf->program_name = pieces;
268 /* Getting program name again. */
269 while(isValidChar(*pieces) == 1)
272 /* Checking for the first format: p_name: */
273 if((*pieces == ':') && (pieces[1] == ' '))
279 /* Checking for the second format: p_name[pid]: */
280 else if((*pieces == '[') && (isdigit((int)pieces[1])))
284 while(isdigit((int)*pieces))
287 if((*pieces == ']') && (pieces[1] == ':') &&
301 lf->program_name = NULL;
308 lf->program_name = NULL;
314 lf->program_name = NULL;
319 /* Removing [ID xx facility.severity] */
322 /* Setting log after program name */
325 if((pieces[0] == '[') &&
326 (pieces[1] == 'I') &&
327 (pieces[2] == 'D') &&
332 /* Going after the ] */
333 pieces = strchr(pieces, ']');
342 /* Getting program name size */
345 lf->p_name_size = strlen(lf->program_name);
349 /* xferlog date format
350 * Mon Apr 17 18:27:14 2006 1 64.160.42.130
352 else if((loglen > 28) &&
355 (pieces[10] == ' ')&&
356 (pieces[13] == ':')&&
357 (pieces[16] == ':')&&
358 (pieces[19] == ' ')&&
359 (pieces[24] == ' ')&&
362 /* Moving log to the beginning of the message */
367 /* Checking for snort date format
368 * ex: 01/28-09:13:16.240702 [**]
370 else if( (loglen > 24) &&
371 (pieces[2] == '/') &&
372 (pieces[5] == '-') &&
373 (pieces[8] == ':') &&
374 (pieces[11]== ':') &&
375 (pieces[14]== '.') &&
376 (pieces[21] == ' ') )
381 /* Checking for suricata (new) date format
382 * ex: 01/28/1979-09:13:16.240702 [**]
384 else if( (loglen > 26) &&
385 (pieces[2] == '/') &&
386 (pieces[5] == '/') &&
387 (pieces[10] == '-') &&
388 (pieces[13] == ':') &&
389 (pieces[16]== ':') &&
390 (pieces[19]== '.') &&
391 (pieces[26] == ' ') )
397 /* Checking for apache log format */
398 /* [Fri Feb 11 18:06:35 2004] [warn] */
399 else if( (loglen > 27) &&
400 (pieces[0] == '[') &&
401 (pieces[4] == ' ') &&
402 (pieces[8] == ' ') &&
403 (pieces[11]== ' ') &&
404 (pieces[14]== ':') &&
405 (pieces[17]== ':') &&
406 (pieces[20]== ' ') &&
412 /* Checking for the osx asl log format.
414 * [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]
415 * [Time 2006.11.02 14:02:11 UTC] [Facility auth] [Sender sshd] [PID 856]
416 [Message refused connect from 59.124.44.34] [Level 4] [UID -2] [GID -2]
417 [Host robert-wyatts-emac]
419 else if((loglen > 26) &&
420 (pieces[0] == '[') &&
421 (pieces[1] == 'T') &&
422 (pieces[5] == ' ') &&
423 (pieces[10] == '.') &&
424 (pieces[13] == '.') &&
425 (pieces[16] == ' ') &&
428 /* Do not read more than 1 message entry -> log tampering */
429 short unsigned int done_message = 0;
432 /* Removing the date */
435 /* Getting the desired values */
436 pieces = strchr(lf->log, '[');
441 /* Getting the sender (set to program name) */
442 if((strncmp(pieces, "Sender ", 7) == 0) &&
443 (lf->program_name == NULL))
446 lf->program_name = pieces;
448 /* Getting the closing brackets */
449 pieces = strchr(pieces, ']');
454 /* Setting program_name size */
455 lf->p_name_size = strlen(lf->program_name);
459 /* Invalid program name */
462 lf->program_name = NULL;
467 /* Getting message */
468 else if((strncmp(pieces, "Message ", 8) == 0) &&
476 /* Getting the closing brackets */
477 pieces = strchr(pieces, ']');
483 /* Invalid log closure */
490 /* Getting hostname */
491 else if(strncmp(pieces, "Host ", 5) == 0)
494 lf->hostname = pieces;
496 /* Getting the closing brackets */
497 pieces = strchr(pieces, ']');
504 /* Invalid hostname */
512 /* Getting next entry */
513 pieces = strchr(pieces, '[');
517 /* Checking for squid date format
518 * 1140804070.368 11623
519 * seconds from 00:00:00 1970-01-01 UTC
521 else if((loglen > 32) &&
522 (pieces[0] == '1') &&
523 (isdigit((int)pieces[1])) &&
524 (isdigit((int)pieces[2])) &&
525 (isdigit((int)pieces[3])) &&
526 (pieces[10] == '.') &&
527 (isdigit((int)pieces[13])) &&
528 (pieces[14] == ' ') &&
529 ((pieces[21] == ' ')||(pieces[22] == ' ')))
533 /* We need to start at the size of the event */
534 while(*lf->log == ' ')
541 /* Every message must be in the format
542 * hostname->location or
543 * (agent) ip->location.
547 /* Setting hostname for local messages */
548 if(lf->location[0] == '(')
550 /* Messages from an agent */
551 lf->hostname = lf->location;
553 else if(lf->hostname == NULL)
555 lf->hostname = __shost;
559 /* Setting up the event data */
561 p = localtime(&c_time);
565 /* Assign hour, day, year and month values */
566 lf->day = p->tm_mday;
567 lf->year = p->tm_year+1900;
568 strncpy(lf->mon,month[p->tm_mon],3);
569 snprintf(lf->hour, 9, "%02d:%02d:%02d",
576 /* Setting the global hour/weekday */
577 __crt_hour = p->tm_hour;
578 __crt_wday = p->tm_wday;
585 print_out("**Phase 1: Completed pre-decoding.");
586 print_out(" full event: '%s'", lf->full_log);
587 print_out(" hostname: '%s'", lf->hostname);
588 print_out(" program_name: '%s'", lf->program_name);
589 print_out(" log: '%s'", lf->log);