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