Imported Upstream version 2.5.1
[ossec-hids.git] / src / analysisd / decoders / hostinfo.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 /* Hostinfo decoder */
14
15
16 #include "config.h"
17 #include "os_regex/os_regex.h"
18 #include "eventinfo.h"
19 #include "alerts/alerts.h"
20
21
22 #define HOSTINFO_FILE   "/queue/fts/hostinfo"
23 #define HOST_HOST       "Host: "
24 #define HOST_PORT       " open ports: "
25
26 #define HOST_CHANGED    "Host information changed."
27 #define HOST_NEW        "New host information added."
28 #define PREV_OPEN       "Previously"
29
30
31 /** Global variables **/
32 int hi_err = 0;
33 int id_new = 0;
34 int id_mod = 0;
35 char _hi_buf[OS_MAXSTR +1];
36 FILE *_hi_fp = NULL;
37
38
39 /* Hostinfo decoder */
40 OSDecoderInfo *hostinfo_dec = NULL;
41
42
43
44 /* Check if the string matches.
45  */
46 static char *__go_after(char *x, char *y)
47 {
48     int x_s;
49     int y_s;
50
51     /* X and Y must be not null */
52     if(!x || !y)
53         return(NULL);
54
55     x_s = strlen(x);
56     y_s = strlen(y);
57
58     if(x_s <= y_s)
59     {
60         return(NULL);
61     }
62
63     /* String does not match */
64     if(strncmp(x,y,y_s) != 0)
65     {
66         return(NULL);
67     }
68
69     x+=y_s;
70
71     return(x);
72 }
73
74
75
76 /* HostinfoInit
77  * Initialize the necessary information to process the host information
78  */
79 void HostinfoInit()
80 {
81     hi_err = 0;
82
83
84     /* Zeroing decoder */
85     os_calloc(1, sizeof(OSDecoderInfo), hostinfo_dec);
86     hostinfo_dec->id = getDecoderfromlist(HOSTINFO_MOD);
87     hostinfo_dec->type = OSSEC_RL;
88     hostinfo_dec->name = HOSTINFO_MOD;
89     hostinfo_dec->fts = 0;
90     id_new = getDecoderfromlist(HOSTINFO_NEW);
91     id_mod = getDecoderfromlist(HOSTINFO_MOD);
92
93
94
95     /* Opening HOSTINFO_FILE */
96     snprintf(_hi_buf,OS_SIZE_1024, "%s", HOSTINFO_FILE);
97     
98
99     /* r+ to read and write. Do not truncate */
100     _hi_fp = fopen(_hi_buf,"r+");
101     if(!_hi_fp)
102     {
103         /* try opening with a w flag, file probably does not exist */
104         _hi_fp = fopen(_hi_buf, "w");
105         if(_hi_fp)
106         {
107             fclose(_hi_fp);
108             _hi_fp = fopen(_hi_buf, "r+");
109         }
110     }
111     if(!_hi_fp)
112     {
113         merror(FOPEN_ERROR, ARGV0, _hi_buf);
114         return;
115     }
116
117     
118     /* clearing the buffer */
119     memset(_hi_buf, '\0', OS_MAXSTR +1);
120
121     return;
122 }
123
124
125
126 /* HI_File
127  * Return the file pointer to be used
128  */
129 FILE *HI_File()
130 {
131     if(_hi_fp)
132     {
133         fseek(_hi_fp, 0, SEEK_SET);
134         return(_hi_fp);
135     }
136
137     return(NULL);
138 }
139
140
141
142 /* Special decoder for Hostinformation
143  * Not using the default rendering tools for simplicity
144  * and to be less resource intensive.
145  */
146 int DecodeHostinfo(Eventinfo *lf)
147 {
148     int changed = 0;
149     int bf_size;
150     
151     char *ip;
152     char *portss;
153     char *tmpstr;
154
155     char buffer[OS_MAXSTR + 1];
156     char opened[OS_MAXSTR + 1];
157     FILE *fp;
158
159     
160     /* Checking maximum number of errors */
161     if(hi_err > 30)
162     {
163         merror("%s: Too many errors handling host information db. "
164                "Ignoring it.", ARGV0);
165         return(0);
166     }
167                 
168
169     /* Zeroing buffers */
170     buffer[OS_MAXSTR] = '\0';
171     opened[OS_MAXSTR] = '\0';
172     fp = HI_File();
173     if(!fp)
174     {
175         merror("%s: Error handling host information database.",ARGV0);
176         hi_err++; /* Increment hi error */
177
178         return(0);
179     }
180
181
182     /* Copying log to buffer */
183     strncpy(buffer,lf->log, OS_MAXSTR);
184     
185     
186     /* Getting ip */
187     tmpstr = __go_after(buffer, HOST_HOST);
188     if(!tmpstr)
189     {
190         merror("%s: Error handling host information database.",ARGV0);
191         hi_err++;
192
193         return(0);
194     }
195
196     
197     /* Setting ip */
198     ip = tmpstr;
199     tmpstr = strchr(tmpstr, ',');
200     if(!tmpstr)
201     {
202         merror("%s: Error handling host information database.",ARGV0);
203         hi_err++;
204
205         return(0);
206     }
207     *tmpstr = '\0';
208     tmpstr++;
209     portss = tmpstr;
210
211
212     /* Getting ip only information -- to store */
213     tmpstr = strchr(ip, ' ');
214     if(tmpstr)
215     {
216         *tmpstr = '\0';
217     }
218     bf_size = strlen(ip);
219     
220     
221     /* Reads the file and search for a possible
222      * entry
223      */
224     while(fgets(_hi_buf, OS_MAXSTR -1, fp) != NULL)
225     {
226         /* Ignore blank lines and lines with a comment */
227         if(_hi_buf[0] == '\n' || _hi_buf[0] == '#')
228         {
229             continue;
230         }
231
232         /* Removing new line */
233         tmpstr = strchr(_hi_buf, '\n');
234         if(tmpstr)
235             *tmpstr = '\0';    
236
237
238         /* Checking for ip */
239         if(strncmp(ip, _hi_buf, bf_size) == 0)
240         {
241             /* Cannot use strncmp to avoid errors with crafted files */    
242             if(strcmp(portss, _hi_buf + bf_size) == 0)
243             {
244                 return(0);
245             }
246             else
247             {
248                 char *tmp_ports;
249
250                 tmp_ports = _hi_buf + (bf_size +1);
251                 snprintf(opened, OS_MAXSTR, "%s %s", PREV_OPEN, tmp_ports);
252                 changed = 1;
253             }
254         }
255     }                
256
257     
258     /* Adding the new entry at the end of the file */
259     fseek(fp, 0, SEEK_END);
260     fprintf(fp,"%s%s\n", ip, portss);
261
262
263     /* Setting decoder */
264     lf->decoder_info = hostinfo_dec;
265
266     
267     /* Setting comment */
268     if(changed == 1)
269     {
270         hostinfo_dec->id = id_mod;
271         //lf->generated_rule->last_events[0] = opened;
272     }
273     else
274     {
275         hostinfo_dec->id = id_new;
276     }
277     
278
279     return(1);
280 }
281
282
283
284 /* EOF */