Imported Upstream version 2.7
[ossec-hids.git] / src / shared / read-alert.c
1 /* @(#) $Id: ./src/shared/read-alert.c, 2011/11/09 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All right reserved.
6  *
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
10  * Foundation
11  *
12  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 /* File monitoring functions */
18
19 #include "shared.h"
20 #include "read-alert.h"
21
22
23 /* ** Alert xyz: email active-response ** */
24
25 #define ALERT_BEGIN     "** Alert"
26 #define ALERT_BEGIN_SZ  8
27 #define RULE_BEGIN      "Rule: "
28 #define RULE_BEGIN_SZ   6
29 #define SRCIP_BEGIN     "Src IP: "
30 #define SRCIP_BEGIN_SZ  8
31 #define GEOIP_BEGIN_SRC "Src Location: "
32 #define GEOIP_BEGIN_SRC_SZ  14
33 #define GEOIP_BEGIN_DST "Dst Location: "
34 #define GEOIP_BEGIN_DST_SZ  14
35 #define SRCPORT_BEGIN     "Src Port: "
36 #define SRCPORT_BEGIN_SZ  10
37 #define DSTIP_BEGIN     "Dst IP: "
38 #define DSTIP_BEGIN_SZ  8
39 #define DSTPORT_BEGIN     "Dst Port: "
40 #define DSTPORT_BEGIN_SZ  10
41 #define USER_BEGIN      "User: "
42 #define USER_BEGIN_SZ   6
43 #define ALERT_MAIL      "mail"
44 #define ALERT_MAIL_SZ   4
45 #define ALERT_AR        "active-response"
46 #define OLDMD5_BEGIN      "Old md5sum was: "
47 #define OLDMD5_BEGIN_SZ   16
48 #define NEWMD5_BEGIN      "New md5sum is : "
49 #define NEWMD5_BEGIN_SZ   16
50 #define OLDSHA1_BEGIN     "Old sha1sum was: "
51 #define OLDSHA1_BEGIN_SZ  17
52 #define NEWSHA1_BEGIN     "New sha1sum is : "
53 #define NEWSHA1_BEGIN_SZ  17
54
55
56 /** void FreeAlertData(alert_data *al_data)
57  * Free alert data.
58  */
59 void FreeAlertData(alert_data *al_data)
60 {
61     char **p;
62
63     if(al_data->alertid)
64     {
65         free(al_data->alertid);
66         al_data->alertid = NULL;
67     }
68     if(al_data->date)
69     {
70         free(al_data->date);
71         al_data->date = NULL;
72     }
73     if(al_data->location)
74     {
75         free(al_data->location);
76         al_data->location = NULL;
77     }
78     if(al_data->comment)
79     {
80         free(al_data->comment);
81         al_data->comment = NULL;
82     }
83     if(al_data->group)
84     {
85         free(al_data->group);
86         al_data->group = NULL;
87     }
88     if(al_data->srcip)
89     {
90         free(al_data->srcip);
91         al_data->srcip = NULL;
92     }
93     if(al_data->dstip)
94     {
95         free(al_data->dstip);
96         al_data->dstip = NULL;
97     }
98     if(al_data->user)
99     {
100         free(al_data->user);
101         al_data->user = NULL;
102     }
103     if(al_data->filename)
104     {
105         free(al_data->filename);
106         al_data->filename = NULL;
107     }
108     if(al_data->old_md5)
109     {
110         free(al_data->old_md5);
111         al_data->old_md5 = NULL;
112     }
113     if(al_data->new_md5)
114     {
115         free(al_data->new_md5);
116         al_data->new_md5 = NULL;
117     }
118     if(al_data->old_sha1)
119     {
120         free(al_data->old_sha1);
121         al_data->old_sha1 = NULL;
122     }
123     if(al_data->new_sha1)
124     {
125         free(al_data->new_sha1);
126         al_data->new_sha1 = NULL;
127     }
128     if(al_data->log)
129     {
130         p = al_data->log;
131
132         while(*(p))
133         {
134             free(*(p));
135             *(p) = NULL;
136             p++;
137         }
138         free(al_data->log);
139         al_data->log = NULL;
140     }
141 #ifdef GEOIP
142     if (al_data->geoipdatasrc)
143     {
144         free(al_data->geoipdatasrc);
145         al_data->geoipdatasrc = NULL;
146     }
147     if (al_data->geoipdatadst)
148     {
149         free(al_data->geoipdatadst);
150         al_data->geoipdatadst = NULL;
151     }
152 #endif
153     free(al_data);
154     al_data = NULL;
155 }
156
157
158 /** alert_data *GetAlertData(FILE *fp)
159  * Returns alert data for the file specified
160  */
161 alert_data *GetAlertData(int flag, FILE *fp)
162 {
163     int _r = 0, log_size = 0, issyscheck = 0;
164     char *p;
165
166     char *alertid = NULL;
167     char *date = NULL;
168     char *comment = NULL;
169     char *location = NULL;
170     char *srcip = NULL;
171     char *dstip = NULL;
172     char *user = NULL;
173     char *group = NULL;
174     char *filename = NULL;
175     char *old_md5 = NULL;
176     char *new_md5 = NULL;
177     char *old_sha1 = NULL;
178     char *new_sha1 = NULL;
179     char **log = NULL;
180 #ifdef GEOIP
181     char *geoipdatasrc = NULL;
182     char *geoipdatadst = NULL;
183 #endif
184     int level, rule, srcport = 0, dstport = 0;
185
186
187     char str[OS_BUFFER_SIZE+1];
188     str[OS_BUFFER_SIZE]='\0';
189
190
191     while(fgets(str, OS_BUFFER_SIZE, fp) != NULL)
192     {
193
194         /* Enf of alert */
195         if(strcmp(str, "\n") == 0 && log_size > 0)
196         {
197             /* Found in here */
198             if(_r == 2)
199             {
200                 alert_data *al_data;
201                 os_calloc(1, sizeof(alert_data), al_data);
202                 al_data->alertid = alertid;
203                 al_data->level = level;
204                 al_data->rule = rule;
205                 al_data->location = location;
206                 al_data->comment = comment;
207                 al_data->group = group;
208                 al_data->log = log;
209                 al_data->srcip = srcip;
210                 al_data->srcport = srcport;
211                 al_data->dstip = dstip;
212                 al_data->dstport = dstport;
213                 al_data->user = user;
214                 al_data->date = date;
215                 al_data->filename = filename;
216 #ifdef GEOIP
217                 al_data->geoipdatasrc = geoipdatasrc;
218                 al_data->geoipdatadst = geoipdatadst;
219 #endif
220                 al_data->old_md5 = old_md5;
221                 al_data->new_md5 = new_md5;
222                 al_data->old_sha1 = old_sha1;
223                 al_data->new_sha1 = new_sha1;
224
225
226                 return(al_data);
227             }
228             _r = 0;
229         }
230
231
232         /* Checking for the header */
233         if(strncmp(ALERT_BEGIN, str, ALERT_BEGIN_SZ) == 0)
234         {
235             char *m;
236             int z = 0;
237             p = str + ALERT_BEGIN_SZ + 1;
238
239             m = strstr(p, ":");
240             if (!m)
241             {
242                 continue;
243             }
244
245             z = strlen(p) - strlen(m);
246             os_realloc(alertid, (z + 1)*sizeof(char *), alertid);
247             strncpy(alertid, p, z);
248             alertid[z] = '\0';
249
250             /* Searching for email flag */
251             p = strchr(p, ' ');
252             if(!p)
253             {
254                 continue;
255             }
256
257             p++;
258
259
260             /* Checking for the flags */
261             if((flag & CRALERT_MAIL_SET) &&
262                (strncmp(ALERT_MAIL, p, ALERT_MAIL_SZ) != 0))
263             {
264                 continue;
265             }
266
267             p = strchr(p, '-');
268             if(p)
269             {
270                 p++;
271                 os_strdup(p, group);
272
273                 /* Cleaning new line from group */
274                 os_clearnl(group, p);
275                 if(group != NULL && strstr(group, "syscheck") != NULL)
276                 {
277                     issyscheck = 1;
278                 }
279             }
280
281
282             /* Searching for active-response flag */
283             _r = 1;
284             continue;
285         }
286
287         if(_r < 1)
288             continue;
289
290
291         /*** Extract information from the event ***/
292
293         /* r1 means: 2006 Apr 13 16:15:17 /var/log/auth.log */
294         if(_r == 1)
295         {
296             /* Clear new line */
297             os_clearnl(str, p);
298
299             p = strchr(str, ':');
300             if(p)
301             {
302                 p = strchr(p, ' ');
303                 if(p)
304                 {
305                     *p = '\0';
306                     p++;
307                 }
308                 else
309                 {
310                     /* If p is null it is because strchr failed */
311                     merror("ZZZ: 1() Merror date or location not NULL");
312                     _r = 0;
313                     goto l_error;
314                 }
315             }
316
317
318             /* If not, str is date and p is the location */
319             if(date || location)
320                 merror("ZZZ Merror date or location not NULL");
321
322             os_strdup(str, date);
323             os_strdup(p, location);
324             _r = 2;
325             log_size = 0;
326             continue;
327         }
328
329
330         else if(_r == 2)
331         {
332             /* Rule begin */
333             if(strncmp(RULE_BEGIN, str, RULE_BEGIN_SZ) == 0)
334             {
335                 os_clearnl(str,p);
336
337                 p = str + RULE_BEGIN_SZ;
338                 rule = atoi(p);
339
340                 p = strchr(p, ' ');
341                 if(p)
342                 {
343                     p++;
344                     p = strchr(p, ' ');
345                     if(p)
346                         p++;
347                 }
348
349                 if(!p)
350                     goto l_error;
351
352                 level = atoi(p);
353
354                 /* Getting the comment */
355                 p = strchr(p, '\'');
356                 if(!p)
357                     goto l_error;
358
359                 p++;
360                 os_strdup(p, comment);
361
362                 /* Must have the closing \' */
363                 p = strrchr(comment, '\'');
364                 if(p)
365                 {
366                     *p = '\0';
367                 }
368                 else
369                 {
370                     goto l_error;
371                 }
372             }
373
374             /* srcip */
375             else if(strncmp(SRCIP_BEGIN, str, SRCIP_BEGIN_SZ) == 0)
376             {
377                 os_clearnl(str,p);
378
379                 p = str + SRCIP_BEGIN_SZ;
380                 os_strdup(p, srcip);
381             }
382 #ifdef GEOIP
383             /* GeoIP Source Location */
384             else if (strncmp(GEOIP_BEGIN_SRC, str, GEOIP_BEGIN_SRC_SZ) == 0)
385             {
386                 os_clearnl(str,p);
387                 p = str + GEOIP_BEGIN_SRC_SZ;
388                 os_strdup(p, geoipdatasrc);
389             }
390 #endif
391             /* srcport */
392             else if(strncmp(SRCPORT_BEGIN, str, SRCPORT_BEGIN_SZ) == 0)
393             {
394                 os_clearnl(str,p);
395
396                 p = str + SRCPORT_BEGIN_SZ;
397                 srcport = atoi(p);
398             }
399             /* dstip */
400             else if(strncmp(DSTIP_BEGIN, str, DSTIP_BEGIN_SZ) == 0)
401             {
402                 os_clearnl(str,p);
403
404                 p = str + DSTIP_BEGIN_SZ;
405                 os_strdup(p, dstip);
406             }
407 #ifdef GEOIP
408             /* GeoIP Destination Location */
409             else if (strncmp(GEOIP_BEGIN_DST, str, GEOIP_BEGIN_DST_SZ) == 0)
410             {
411                 os_clearnl(str,p);
412                 p = str + GEOIP_BEGIN_DST_SZ;
413                 os_strdup(p, geoipdatadst);
414             }
415 #endif
416             /* dstport */
417             else if(strncmp(DSTPORT_BEGIN, str, DSTPORT_BEGIN_SZ) == 0)
418             {
419                 os_clearnl(str,p);
420
421                 p = str + DSTPORT_BEGIN_SZ;
422                 dstport = atoi(p);
423             }
424             /* username */
425             else if(strncmp(USER_BEGIN, str, USER_BEGIN_SZ) == 0)
426             {
427                 os_clearnl(str,p);
428
429                 p = str + USER_BEGIN_SZ;
430                 os_strdup(p, user);
431             }
432             /* Old MD5 */
433             else if(strncmp(OLDMD5_BEGIN, str, OLDMD5_BEGIN_SZ) == 0)
434             {
435                 os_clearnl(str,p);
436
437                 p = str + OLDMD5_BEGIN_SZ;
438                 os_strdup(p, old_md5);
439             }
440             /* New MD5 */
441             else if(strncmp(NEWMD5_BEGIN, str, NEWMD5_BEGIN_SZ) == 0)
442             {
443                 os_clearnl(str,p);
444
445                 p = str + NEWMD5_BEGIN_SZ;
446                 os_strdup(p, new_md5);
447             }
448             /* Old SHA1 */
449             else if(strncmp(OLDSHA1_BEGIN, str, OLDSHA1_BEGIN_SZ) == 0)
450             {
451                 os_clearnl(str,p);
452
453                 p = str + OLDSHA1_BEGIN_SZ;
454                 os_strdup(p, old_sha1);
455             }
456             /* New SHA1 */
457             else if(strncmp(NEWSHA1_BEGIN, str, NEWSHA1_BEGIN_SZ) == 0)
458             {
459                 os_clearnl(str,p);
460
461                 p = str + NEWSHA1_BEGIN_SZ;
462                 os_strdup(p, new_sha1);
463             }
464             /* It is a log message */
465             else if(log_size < 20)
466             {
467                 os_clearnl(str,p);
468
469                 if(str != NULL && issyscheck == 1)
470                 {
471                     if(strncmp(str, "Integrity checksum changed for: '",33) == 0)
472                     {
473                         filename = strdup(str+33);
474                         if(filename)
475                         {
476                             filename[strlen(filename) -1] = '\0';
477                         }
478                     }
479                     issyscheck = 0;
480                 }
481
482                 os_realloc(log, (log_size +2)*sizeof(char *), log);
483                 os_strdup(str, log[log_size]);
484                 log_size++;
485                 log[log_size] = NULL;
486             }
487         }
488
489         continue;
490         l_error:
491
492         /* Freeing the memory */
493         _r = 0;
494         if(date)
495         {
496             free(date);
497             date = NULL;
498         }
499         if(location)
500         {
501             free(location);
502             location = NULL;
503         }
504         if(comment)
505         {
506             free(comment);
507             comment = NULL;
508         }
509         if(srcip)
510         {
511             free(srcip);
512             srcip = NULL;
513         }
514 #ifdef GEOIP
515         if(geoipdatasrc)
516         {
517             free(geoipdatasrc);
518             geoipdatasrc = NULL;
519         }
520         if(geoipdatadst)
521         {
522             free(geoipdatadst);
523             geoipdatadst = NULL;
524         }
525 #endif
526         if(user)
527         {
528             free(user);
529             user = NULL;
530         }
531         if(filename)
532         {
533             free(filename);
534             filename = NULL;
535         }
536         if(group)
537         {
538             free(group);
539             group = NULL;
540         }
541         if(old_md5)
542         {
543             free(old_md5);
544             old_md5 = NULL;
545         }
546
547         if(new_md5)
548         {
549             free(new_md5);
550             new_md5 = NULL;
551         }
552
553         if(old_sha1)
554         {
555             free(old_sha1);
556             old_sha1 = NULL;
557         }
558
559         if(new_sha1)
560         {
561             free(new_sha1);
562             new_sha1 = NULL;
563         }
564         while(log_size > 0)
565         {
566             log_size--;
567             if(log[log_size])
568             {
569                 free(log[log_size]);
570                 log[log_size] = NULL;
571             }
572         }
573     }
574
575     if(alertid)
576         {
577                 free(alertid);
578                 alertid = NULL;
579         }
580
581     /* We need to clean end of file before returning */
582     clearerr(fp);
583     return(NULL);
584 }
585
586
587 /* EOF */