Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / dodiff.c
1 /* @(#) $Id: ./src/analysisd/dodiff.c, 2012/07/23 dcid Exp $
2  */
3
4 /* Copyright (C) 2010 Trend Micro Inc.
5  * All rights 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
18 #include "eventinfo.h"
19 #include "shared.h"
20
21 char flastcontent[OS_SIZE_8192 +1];
22 char *fmsglast = "Previous output:";
23
24 static int _add2last(char *str, int strsize, char *file)
25 {
26     FILE *fp;
27
28     fp = fopen(file, "w");
29     if(!fp)
30     {
31         /* Try to create the directories. */
32         char *dirrule = NULL;
33         char *diragent = NULL;
34
35         dirrule = strrchr(file, '/');
36         if(!dirrule)
37         {
38             merror("%s: ERROR: Invalid file name to diff: %s",
39                    ARGV0, file);
40             return(0);
41         }
42         *dirrule = '\0';
43
44         diragent = strrchr(file, '/');
45         if(!diragent)
46         {
47             merror("%s: ERROR: Invalid file name to diff (2): %s",
48                    ARGV0, file);
49             return(0);
50         }
51         *diragent = '\0';
52
53         /* Checking if the diragent exists. */
54         if(IsDir(file) != 0)
55         {
56             if(mkdir(file, 0770) == -1)
57             {
58                 merror(MKDIR_ERROR, ARGV0, file);
59                 return(0);
60             }
61         }
62         *diragent = '/';
63
64         if(IsDir(file) != 0)
65         {
66             if(mkdir(file, 0770) == -1)
67             {
68                 merror(MKDIR_ERROR, ARGV0, file);
69                 return(0);
70             }
71         }
72         *dirrule = '/';
73
74         fp = fopen(file, "w");
75         if(!fp)
76         {
77             merror(FOPEN_ERROR, ARGV0, file);
78             return(0);
79         }
80     }
81
82     fwrite(str, strsize + 1, 1, fp);
83     fclose(fp);
84     return(1);
85 }
86
87
88 int doDiff(RuleInfo *currently_rule, Eventinfo *lf)
89 {
90     int date_of_change;
91     char *htpt = NULL;
92     char flastfile[OS_SIZE_2048 +1];
93     char fdifffile[OS_SIZE_2048 +1];
94     char flastcontent[OS_SIZE_8192 +1];
95
96
97     /* Cleaning up global. */
98     flastcontent[0] = '\0';
99     flastcontent[OS_SIZE_8192] = '\0';
100     currently_rule->last_events[0] = NULL;
101
102
103
104     if(lf->hostname[0] == '(')
105     {
106         htpt = strchr(lf->hostname, ')');
107         if(htpt)
108         {
109             *htpt = '\0';
110         }
111         snprintf(flastfile, OS_SIZE_2048, "%s/%s/%d/%s", DIFF_DIR, lf->hostname+1,
112                  currently_rule->sigid, DIFF_LAST_FILE);
113
114         if(htpt)
115         {
116             *htpt = ')';
117         }
118         htpt = NULL;
119     }
120     else
121     {
122         snprintf(flastfile, OS_SIZE_2048, "%s/%s/%d/%s", DIFF_DIR, lf->hostname,
123                  currently_rule->sigid, DIFF_LAST_FILE);
124     }
125
126     /* lf->size can't be too long. */
127     if(lf->size >= OS_SIZE_8192)
128     {
129         merror("%s: ERROR: event size (%d) too long for diff.", ARGV0, lf->size);
130         return(0);
131     }
132
133
134     /* Checking if last diff exists. */
135     date_of_change = File_DateofChange(flastfile);
136     if(date_of_change <= 0)
137     {
138         if(!_add2last(lf->log, lf->size, flastfile))
139         {
140             merror("%s: ERROR: unable to create last file: %s", ARGV0, flastfile);
141             return(0);
142         }
143         return(0);
144     }
145     else
146     {
147         FILE *fp;
148         int n;
149         fp = fopen(flastfile,"r");
150         if(!fp)
151         {
152             merror(FOPEN_ERROR, ARGV0, flastfile);
153             return(0);
154         }
155
156         n = fread(flastcontent, 1, OS_SIZE_8192, fp);
157         if(n > 0)
158         {
159             flastcontent[n] = '\0';
160         }
161         else
162         {
163             merror("%s: ERROR: read error on %s", ARGV0, flastfile);
164             fclose(fp);
165             return(0);
166         }
167         fclose(fp);
168     }
169
170     /* Nothing changed. */
171     if(strcmp(flastcontent, lf->log) == 0)
172     {
173         return(0);
174     }
175
176
177     /* File was modified. */
178     if(lf->hostname[0] == '(')
179     {
180         htpt = strchr(lf->hostname, ')');
181         if(htpt)
182         {
183             *htpt = '\0';
184         }
185         snprintf(fdifffile, OS_SIZE_2048, "%s/%s/%d/state.%d", DIFF_DIR, lf->hostname+1,
186                  currently_rule->sigid, date_of_change);
187
188         if(htpt)
189         {
190             *htpt = ')';
191         }
192         htpt = NULL;
193     }
194     else
195     {
196         snprintf(fdifffile, OS_SIZE_2048, "%s/%s/%d/state.%d", DIFF_DIR, lf->hostname,
197                  currently_rule->sigid, date_of_change);
198     }
199
200     rename(flastfile, fdifffile);
201     if(!_add2last(lf->log, lf->size, flastfile))
202     {
203         merror("%s: ERROR: unable to create last file: %s", ARGV0, flastfile);
204     }
205
206     currently_rule->last_events[0] = fmsglast;
207     currently_rule->last_events[1] = flastcontent;
208     return(1);
209
210 }
211
212
213
214 /* EOF */