Imported Upstream version 2.7
[ossec-hids.git] / src / logcollector / read_nmapg.c
1 /* @(#) $Id: ./src/logcollector/read_nmapg.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 #include "shared.h"
15 #include "logcollector.h"
16
17
18 #define NMAPG_HOST  "Host: "
19 #define NMAPG_PORT  "Ports:"
20 #define NMAPG_OPEN  "open/"
21 #define NMAPG_STAT  "Status:"
22
23
24
25 /** Function Prototypes **/
26 static char *__go_after(char *x, char *y);
27 static char *__get_port(char *str, char *proto, char *port, int msize);
28
29
30
31 /* Get port and protocol.
32  */
33 static char *__get_port(char *str, char *proto, char *port, int msize)
34 {
35     int filtered = 0;
36     char *p, *q;
37
38
39     /* Removing white spaces */
40     while(*str == ' ')
41     {
42         str++;
43     }
44
45
46     /* Getting port */
47     p = strchr(str, '/');
48     if(!p)
49         return(NULL);
50     *p = '\0';
51     p++;
52
53
54     /* Getting port */
55     strncpy(port, str, msize);
56     port[msize -1] = '\0';
57
58
59
60     /* Checking if the port is open */
61     q = __go_after(p, NMAPG_OPEN);
62     if(!q)
63     {
64         /* Port is not open */
65         filtered = 1;
66         q = p;
67
68
69         /* Going to the start of protocol field */
70         p = strchr(q, '/');
71         if(!p)
72             return(NULL);
73         p++;
74     }
75     else
76     {
77         p = q;
78     }
79
80
81
82     /* Getting protocol */
83     str = p;
84     p = strchr(str, '/');
85     if(!p)
86     {
87         return(NULL);
88     }
89     *p = '\0';
90     p++;
91
92
93     strncpy(proto, str, msize);
94     proto[msize -1] = '\0';
95
96
97     /* Setting proto to null if port is not open */
98     if(filtered)
99         proto[0] = '\0';
100
101
102     /* Removing slashes */
103     if(*p == '/')
104     {
105         p++;
106         q = p;
107         p = strchr(p, ',');
108         if(p)
109         {
110             return(p);
111         }
112
113         return(q);
114     }
115
116
117     return(NULL);
118 }
119
120
121 /* Check if the string matches.
122  */
123 static char *__go_after(char *x, char *y)
124 {
125     int x_s;
126     int y_s;
127
128     /* X and Y must be not null */
129     if(!x || !y)
130         return(NULL);
131
132     x_s = strlen(x);
133     y_s = strlen(y);
134
135     if(x_s <= y_s)
136     {
137         return(NULL);
138     }
139
140     /* String does not match */
141     if(strncmp(x,y,y_s) != 0)
142     {
143         return(NULL);
144     }
145
146     x+=y_s;
147
148     return(x);
149 }
150
151
152 /* Read Nmap grepable files */
153 void *read_nmapg(int pos, int *rc, int drop_it)
154 {
155     int final_msg_s;
156     int need_clear = 0;
157
158     char str[OS_MAXSTR + 1];
159     char final_msg[OS_MAXSTR + 1];
160     char buffer[OS_MAXSTR + 1];
161     char port[17];
162     char proto[17];
163
164     char *ip = NULL;
165     char *p;
166     char *q;
167
168     *rc = 0;
169     str[OS_MAXSTR] = '\0';
170     final_msg[OS_MAXSTR] = '\0';
171     buffer[OS_MAXSTR] = '\0';
172
173     port[16] = '\0';
174     proto[16] = '\0';
175
176     while(fgets(str, OS_MAXSTR -OS_LOG_HEADER, logff[pos].fp) != NULL)
177     {
178         /* If need clear is set, we need to clear the line */
179         if(need_clear)
180         {
181             if((q = strchr(str, '\n')) != NULL)
182             {
183                 need_clear = 0;
184             }
185             continue;
186         }
187
188         /* Removing \n at the end of the string */
189         if ((q = strchr(str, '\n')) != NULL)
190         {
191             *q = '\0';
192         }
193         else
194         {
195             need_clear = 1;
196         }
197
198
199         /* Do not get commented lines */
200         if((str[0] == '#') || (str[0] == '\0'))
201         {
202             continue;
203         }
204
205
206         /* Getting host */
207         q = __go_after(str, NMAPG_HOST);
208         if(!q)
209         {
210             goto file_error;
211         }
212
213
214         /* Getting ip/hostname */
215         p = strchr(q, ')');
216         if(!p)
217         {
218             goto file_error;
219         }
220
221
222         /* Setting the valid ip */
223         ip = q;
224
225
226
227         /* Getting the ports */
228         q = strchr(p, '\t');
229         if(!q)
230         {
231             goto file_error;
232         }
233         q++;
234
235
236         /* Now fixing p, to have the closing parenthesis */
237         p++;
238         *p = '\0';
239
240
241         /* q now should point to the ports */
242         p = __go_after(q, NMAPG_PORT);
243         if(!p)
244         {
245             /* Checking if no port is available */
246             p = __go_after(q, NMAPG_STAT);
247             if(p)
248             {
249                 continue;
250             }
251
252             goto file_error;
253         }
254
255
256         /* Generating final msg */
257         snprintf(final_msg, OS_MAXSTR, "Host: %s, open ports:",
258                             ip);
259         final_msg_s = OS_MAXSTR - ((strlen(final_msg) +3));
260
261
262         /* Getting port and protocol */
263         do
264         {
265             /* Avoid filling the buffer (3*port size). */
266             if(final_msg_s < 27)
267             {
268                 break;
269             }
270
271             p = __get_port(p, proto, port, 9);
272             if(!p)
273             {
274                 debug1("%s: Bad formated nmap grepable file (port).", ARGV0);
275                 break;
276             }
277
278
279             /* Port not open */
280             if(proto[0] == '\0')
281             {
282                 continue;
283             }
284
285
286             /* Adding ports */
287             snprintf(buffer, OS_MAXSTR, " %s(%s)", port, proto);
288             strncat(final_msg, buffer, final_msg_s);
289             final_msg_s-=(strlen(buffer) +2);
290
291         }while(*p == ',' && (p++));
292
293
294         if(drop_it == 0)
295         {
296             /* Sending message to queue */
297             if(SendMSG(logr_queue, final_msg, logff[pos].file,
298                         HOSTINFO_MQ) < 0)
299             {
300                 merror(QUEUE_SEND, ARGV0);
301                 if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
302                 {
303                     ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
304                 }
305             }
306         }
307
308
309         /* Getting next */
310         continue;
311
312
313         /* Handling errors */
314         file_error:
315
316         merror("%s: Bad formated nmap grepable file.", ARGV0);
317         *rc = -1;
318         return(NULL);
319
320     }
321
322
323     return(NULL);
324 }
325
326 /* EOF */