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