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