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