Imported Upstream version 2.5.1
[ossec-hids.git] / src / analysisd / decoders / rootcheck.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All right 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
12
13 /* Rootcheck decoder */
14
15
16 #include "config.h"
17 #include "os_regex/os_regex.h"
18 #include "eventinfo.h"
19 #include "alerts/alerts.h"
20 #include "decoder.h"
21
22
23 #define ROOTCHECK_DIR    "/queue/rootcheck"
24
25
26 /** Global variables **/
27 char *rk_agent_ips[MAX_AGENTS];
28 FILE *rk_agent_fps[MAX_AGENTS];
29
30 int rk_err;
31
32 /* Rootcheck decoder */
33 OSDecoderInfo *rootcheck_dec = NULL;
34
35
36 /* SyscheckInit
37  * Initialize the necessary information to process the syscheck information
38  */
39 void RootcheckInit()
40 {
41     int i = 0;
42
43     rk_err = 0;
44     
45     for(;i<MAX_AGENTS;i++)
46     {
47         rk_agent_ips[i] = NULL;
48         rk_agent_fps[i] = NULL;
49     }
50
51
52     /* Zeroing decoder */
53     os_calloc(1, sizeof(OSDecoderInfo), rootcheck_dec);
54     rootcheck_dec->id = getDecoderfromlist(ROOTCHECK_MOD);
55     rootcheck_dec->type = OSSEC_RL;
56     rootcheck_dec->name = ROOTCHECK_MOD;
57     rootcheck_dec->fts = 0;
58
59     debug1("%s: RootcheckInit completed.", ARGV0);
60     
61     return;
62 }
63
64
65 /* RK_File
66  * Return the file pointer to be used
67  */
68 FILE *RK_File(char *agent, int *agent_id)
69 {
70     int i = 0;
71     char rk_buf[OS_SIZE_1024 +1];
72
73     while(rk_agent_ips[i] != NULL)
74     {
75         if(strcmp(rk_agent_ips[i],agent) == 0)
76         {
77             /* pointing to the beginning of the file */
78             fseek(rk_agent_fps[i],0, SEEK_SET);
79             *agent_id = i;
80             return(rk_agent_fps[i]);
81         }
82         
83         i++;    
84     }
85
86     /* If here, our agent wasn't found */
87     rk_agent_ips[i] = strdup(agent);
88
89     if(rk_agent_ips[i] != NULL)
90     {
91         snprintf(rk_buf,OS_SIZE_1024, "%s/%s", ROOTCHECK_DIR,agent);
92         
93         /* r+ to read and write. Do not truncate */
94         rk_agent_fps[i] = fopen(rk_buf,"r+");
95         if(!rk_agent_fps[i])
96         {
97             /* try opening with a w flag, file probably does not exist */
98             rk_agent_fps[i] = fopen(rk_buf, "w");
99             if(rk_agent_fps[i])
100             {
101                 fclose(rk_agent_fps[i]);
102                 rk_agent_fps[i] = fopen(rk_buf, "r+");
103             }
104         }
105         if(!rk_agent_fps[i])
106         {
107             merror(FOPEN_ERROR, ARGV0, rk_buf);
108             
109             free(rk_agent_ips[i]);
110             rk_agent_ips[i] = NULL;
111
112             return(NULL);
113         }
114
115         /* Returning the opened pointer (the beginning of it) */
116         fseek(rk_agent_fps[i],0, SEEK_SET);
117         *agent_id = i;
118         return(rk_agent_fps[i]);
119     }
120
121     else
122     {
123         merror(MEM_ERROR,ARGV0);
124         return(NULL);
125     }
126
127     return(NULL);
128 }
129
130
131 /* Special decoder for rootcheck
132  * Not using the default rendering tools for simplicity
133  * and to be less resource intensive
134  */
135 int DecodeRootcheck(Eventinfo *lf)
136 {
137     int agent_id;
138
139     char *tmpstr;
140     char rk_buf[OS_SIZE_2048 +1];
141
142     FILE *fp;
143
144     fpos_t fp_pos;
145
146     /* Zeroing rk_buf */
147     rk_buf[0] = '\0';
148     rk_buf[OS_SIZE_2048] = '\0';
149
150     fp = RK_File(lf->location, &agent_id);
151
152     if(!fp)
153     {
154         merror("%s: Error handling rootcheck database.",ARGV0);
155         rk_err++; /* Increment rk error */
156
157         return(0);
158     }
159
160     /* Getting initial position */
161     if(fgetpos(fp, &fp_pos) == -1)
162     {
163         merror("%s: Error handling rootcheck database (fgetpos).",ARGV0);
164         return(0);
165     }
166                                     
167
168     /* Reads the file and search for a possible
169      * entry
170      */
171     while(fgets(rk_buf, OS_SIZE_2048 -1, fp) != NULL)
172     {
173         /* Ignore blank lines and lines with a comment */
174         if(rk_buf[0] == '\n' || rk_buf[0] == '#')
175         {
176             if(fgetpos(fp, &fp_pos) == -1)
177             {
178                 merror("%s: Error handling rootcheck database "
179                        "(fgetpos2).",ARGV0);
180                 return(0);
181             }
182             continue;
183         }
184
185         /* Removing new line */
186         tmpstr = strchr(rk_buf, '\n');
187         if(tmpstr)
188         {
189             *tmpstr = '\0';    
190         }
191
192         
193         /* Old format without the time stampts */
194         if(rk_buf[0] != '!')
195         {
196             /* Cannot use strncmp to avoid errors with crafted files */    
197             if(strcmp(lf->log, rk_buf) == 0)
198             {
199                 rootcheck_dec->fts = 0;
200                 lf->decoder_info = rootcheck_dec;
201                 return(1);
202             }
203         }
204         /* New format */
205         else
206         {
207             /* Going past time: !1183431603!1183431603  (last, first saw) */
208             tmpstr = rk_buf + 23;
209             
210             /* Matches, we need to upgrade last time saw */
211             if(strcmp(lf->log, tmpstr) == 0)
212             {
213                 fsetpos(fp, &fp_pos);
214                 fprintf(fp, "!%d", lf->time);
215                 rootcheck_dec->fts = 0;
216                 lf->decoder_info = rootcheck_dec;        
217                 return(1);
218             }
219         }
220
221         /* Getting current position */
222         if(fgetpos(fp, &fp_pos) == -1)
223         {
224             merror("%s: Error handling rootcheck database (fgetpos3).",ARGV0);
225             return(0);
226         }
227     }                
228
229     
230     /* Adding the new entry at the end of the file */
231     fseek(fp, 0, SEEK_END);
232     fprintf(fp,"!%d!%d %s\n",lf->time, lf->time, lf->log);
233     fflush(fp);
234
235     rootcheck_dec->fts = 0;
236     rootcheck_dec->fts |= FTS_DONE;
237     lf->decoder_info = rootcheck_dec;
238     return(1); 
239 }
240
241
242 /* EOF */