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