Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / alerts / log.c
1 /* @(#) $Id: ./src/analysisd/alerts/log.c, 2012/03/30 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 "log.h"
16 #include "alerts.h"
17 #include "getloglocation.h"
18 #include "rules.h"
19 #include "eventinfo.h"
20 #include "config.h"
21
22 #ifdef GEOIP
23 /* GeoIP Stuff */
24 #include "GeoIP.h"
25 #include "GeoIPCity.h"
26
27 #define RFC1918_10     (167772160 & 4278190080)        /* 10/8 */
28 #define RFC1918_172    (2886729728 & 4293918720)       /* 172.17/12 */
29 #define RFC1918_192    (3232235520 & 4294901760)       /* 192.168/16 */
30 #define NETMASK_8      4278190080      /* 255.0.0.0    */
31 #define NETMASK_12     4293918720      /* 255.240.0.0  */
32 #define NETMASK_16     4294901760      /* 255.255.0.0  */
33
34 static const char * _mk_NA( const char * p ){
35         return p ? p : "N/A";
36 }
37
38 /* StrIP2Long */
39 /* Convert an dot-quad IP address into long format
40  */
41 unsigned long StrIP2Int(char *ip) {
42         unsigned int c1,c2,c3,c4;
43        /* IP address is not coming from user input -> We can trust it */
44        /* only minimal checking is performed */
45         int len = strlen(ip);
46         if ((len < 7) || (len > 15)) return 0;
47
48         sscanf(ip, "%d.%d.%d.%d", &c1, &c2, &c3, &c4);
49         return((unsigned long)c4+c3*256+c2*256*256+c1*256*256*256);
50 }
51
52
53 /* GeoIPLookup */
54 /* Use the GeoIP API to locate an IP address
55  */
56 char *GeoIPLookup(char *ip)
57 {
58         GeoIP   *gi;
59         GeoIPRecord     *gir;
60         char buffer[OS_SIZE_1024 +1];
61         unsigned long longip;
62
63         /* Dumb way to detect an IPv6 address */
64         if (strchr(ip, ':')) {
65                 /* Use the IPv6 DB */
66                 gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
67                 if (gi == NULL) {
68                         merror(INVALID_GEOIP_DB, ARGV0, Config.geoip6_db_path);
69                         return("Unknown");
70                 }
71                 gir = GeoIP_record_by_name_v6(gi, (const char *)ip);
72         }
73         else {
74                 /* Use the IPv4 DB */
75                 /* If we have a RFC1918 IP, do not perform a DB lookup (performance) */
76                 longip = StrIP2Int(ip);
77                 if (longip == 0 ) return("Unknown");
78                 if ((longip & NETMASK_8)  == RFC1918_10 ||
79                     (longip & NETMASK_12) == RFC1918_172 ||
80                     (longip & NETMASK_16) == RFC1918_192) return("");
81
82                 gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
83                 if (gi == NULL) {
84                         merror(INVALID_GEOIP_DB, ARGV0, Config.geoip_db_path);
85                         return("Unknown");
86                 }
87                 gir = GeoIP_record_by_name(gi, (const char *)ip);
88         }
89         if (gir != NULL) {
90                 sprintf(buffer,"%s,%s,%s",
91                                 _mk_NA(gir->country_code),
92                                 _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
93                                 _mk_NA(gir->city)
94                 );
95                 GeoIP_delete(gi);
96                 return(buffer);
97         }
98         GeoIP_delete(gi);
99         return("Unknown");
100 }
101 #endif /* GEOIP */
102
103 /* Drop/allow patterns */
104 OSMatch FWDROPpm;
105 OSMatch FWALLOWpm;
106
107
108 /* OS_Store: v0.2, 2005/02/10 */
109 /* Will store the events in a file
110  * The string must be null terminated and contain
111  * any necessary new lines, tabs, etc.
112  *
113  */
114 void OS_Store(Eventinfo *lf)
115 {
116     if(strcmp(lf->location, "ossec-keepalive") == 0)
117     {
118         return;
119     }
120     if(strstr(lf->location, "->ossec-keepalive") != NULL)
121     {
122         return;
123     }
124
125     fprintf(_eflog,
126             "%d %s %02d %s %s%s%s %s\n",
127             lf->year,
128             lf->mon,
129             lf->day,
130             lf->hour,
131             lf->hostname != lf->location?lf->hostname:"",
132             lf->hostname != lf->location?"->":"",
133             lf->location,
134             lf->full_log);
135
136     fflush(_eflog);
137     return;     
138 }
139
140
141
142 void OS_LogOutput(Eventinfo *lf)
143 {
144 #ifdef GEOIP
145     char geoip_msg_src[OS_SIZE_1024 +1];
146     char geoip_msg_dst[OS_SIZE_1024 +1];
147     geoip_msg_src[0] = '\0';
148     geoip_msg_dst[0] = '\0';
149     if (Config.loggeoip) {
150         if (lf->srcip) { strncpy(geoip_msg_src, GeoIPLookup(lf->srcip), OS_SIZE_1024); }
151         if (lf->dstip) { strncpy(geoip_msg_dst, GeoIPLookup(lf->dstip), OS_SIZE_1024); }
152     }
153 #endif
154     printf(
155            "** Alert %d.%ld:%s - %s\n"
156             "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
157             "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
158             lf->time,
159             __crt_ftell,
160             lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
161             lf->generated_rule->group,
162             lf->year,
163             lf->mon,
164             lf->day,
165             lf->hour,
166             lf->hostname != lf->location?lf->hostname:"",
167             lf->hostname != lf->location?"->":"",
168             lf->location,
169             lf->generated_rule->sigid,
170             lf->generated_rule->level,
171             lf->generated_rule->comment,
172
173             lf->srcip == NULL?"":"\nSrc IP: ",
174             lf->srcip == NULL?"":lf->srcip,
175
176 #ifdef GEOIP
177             (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
178             (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
179 #else
180             "",
181             "",
182 #endif
183
184             lf->srcport == NULL?"":"\nSrc Port: ",
185             lf->srcport == NULL?"":lf->srcport,
186
187             lf->dstip == NULL?"":"\nDst IP: ",
188             lf->dstip == NULL?"":lf->dstip,
189
190 #ifdef GEOIP
191             (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
192             (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
193 #else
194             "",
195             "",
196 #endif
197
198             lf->dstport == NULL?"":"\nDst Port: ",
199             lf->dstport == NULL?"":lf->dstport,
200
201             lf->dstuser == NULL?"":"\nUser: ",
202             lf->dstuser == NULL?"":lf->dstuser,
203
204             lf->full_log);
205
206
207     /* Printing the last events if present */
208     if(lf->generated_rule->last_events)
209     {
210         char **lasts = lf->generated_rule->last_events;
211         while(*lasts)
212         {
213             printf("%.1256s\n",*lasts);
214             lasts++;
215         }
216         lf->generated_rule->last_events[0] = NULL;
217     }
218
219     printf("\n");
220
221     fflush(stdout);
222     return;     
223 }
224
225
226
227 /* OS_Log: v0.3, 2006/03/04 */
228 /* _writefile: v0.2, 2005/02/09 */
229 void OS_Log(Eventinfo *lf)
230 {
231 #ifdef GEOIP
232     char geoip_msg_src[OS_SIZE_1024 +1];
233     char geoip_msg_dst[OS_SIZE_1024 +1];
234     geoip_msg_src[0] = '\0';
235     geoip_msg_dst[0] = '\0';
236     if (Config.loggeoip) {
237         if (lf->srcip) { strncpy(geoip_msg_src, GeoIPLookup(lf->srcip), OS_SIZE_1024 ); }
238         if (lf->dstip) { strncpy(geoip_msg_dst, GeoIPLookup(lf->dstip), OS_SIZE_1024 ); }
239     }
240 #endif
241     /* Writting to the alert log file */
242     fprintf(_aflog,
243             "** Alert %d.%ld:%s - %s\n"
244             "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
245             "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
246             lf->time,
247             __crt_ftell,
248             lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
249             lf->generated_rule->group,
250             lf->year,
251             lf->mon,
252             lf->day,
253             lf->hour,
254             lf->hostname != lf->location?lf->hostname:"",
255             lf->hostname != lf->location?"->":"",
256             lf->location,
257             lf->generated_rule->sigid,
258             lf->generated_rule->level,
259             lf->generated_rule->comment,
260
261             lf->srcip == NULL?"":"\nSrc IP: ",
262             lf->srcip == NULL?"":lf->srcip,
263
264 #ifdef GEOIP
265             (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
266             (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
267 #else
268             "",
269             "",
270 #endif
271
272             lf->srcport == NULL?"":"\nSrc Port: ",
273             lf->srcport == NULL?"":lf->srcport,
274
275             lf->dstip == NULL?"":"\nDst IP: ",
276             lf->dstip == NULL?"":lf->dstip,
277
278 #ifdef GEOIP
279             (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
280             (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
281 #else
282             "",
283             "",
284 #endif
285
286             lf->dstport == NULL?"":"\nDst Port: ",
287             lf->dstport == NULL?"":lf->dstport,
288
289             lf->dstuser == NULL?"":"\nUser: ",
290             lf->dstuser == NULL?"":lf->dstuser,
291
292             lf->full_log);
293
294
295     /* Printing the last events if present */
296     if(lf->generated_rule->last_events)
297     {
298         char **lasts = lf->generated_rule->last_events;
299         while(*lasts)
300         {
301             fprintf(_aflog,"%.1256s\n",*lasts);
302             lasts++;
303         }
304         lf->generated_rule->last_events[0] = NULL;
305     }
306
307     fprintf(_aflog,"\n");
308
309     fflush(_aflog);
310     return;     
311 }
312
313
314
315 void OS_InitFwLog()
316 {
317     /* Initializing fw log regexes */
318     if(!OSMatch_Compile(FWDROP, &FWDROPpm, 0))
319     {
320         ErrorExit(REGEX_COMPILE, ARGV0, FWDROP,
321                 FWDROPpm.error);
322     }
323
324     if(!OSMatch_Compile(FWALLOW, &FWALLOWpm, 0))
325     {
326         ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
327                 FWALLOWpm.error);
328     }
329
330 }
331
332
333 /* FW_Log: v0.1, 2005/12/30 */
334 int FW_Log(Eventinfo *lf)
335 {
336     /* If we don't have the srcip or the
337      * action, there is no point in going
338      * forward over here
339      */
340     if(!lf->action || !lf->srcip || !lf->dstip || !lf->srcport ||
341        !lf->dstport || !lf->protocol)
342     {
343         return(0);
344     }
345
346
347     /* Setting the actions */
348     switch(*lf->action)
349     {
350         /* discard, drop, deny, */
351         case 'd':
352         case 'D':
353         /* reject, */
354         case 'r':
355         case 'R':
356         /* block */
357         case 'b':
358         case 'B':
359             os_free(lf->action);
360             os_strdup("DROP", lf->action);
361             break;
362         /* Closed */
363         case 'c':
364         case 'C':
365         /* Teardown */
366         case 't':
367         case 'T':
368             os_free(lf->action);
369             os_strdup("CLOSED", lf->action);
370             break;
371         /* allow, accept, */
372         case 'a':
373         case 'A':
374         /* pass/permitted */
375         case 'p':
376         case 'P':
377         /* open */
378         case 'o':
379         case 'O':
380             os_free(lf->action);
381             os_strdup("ALLOW", lf->action);
382             break;
383         default:
384             if(OSMatch_Execute(lf->action,strlen(lf->action),&FWDROPpm))
385             {
386                 os_free(lf->action);
387                 os_strdup("DROP", lf->action);
388             }
389             if(OSMatch_Execute(lf->action,strlen(lf->action),&FWALLOWpm))
390             {
391                 os_free(lf->action);
392                 os_strdup("ALLOW", lf->action);
393             }
394             else
395             {
396                 os_free(lf->action);
397                 os_strdup("UNKNOWN", lf->action);
398             }
399             break;
400     }
401
402
403     /* log to file */
404     fprintf(_fflog,
405             "%d %s %02d %s %s%s%s %s %s %s:%s->%s:%s\n",
406             lf->year,
407             lf->mon,
408             lf->day,
409             lf->hour,
410             lf->hostname != lf->location?lf->hostname:"",
411             lf->hostname != lf->location?"->":"",
412             lf->location,
413             lf->action,
414             lf->protocol,
415             lf->srcip,
416             lf->srcport,
417             lf->dstip,
418             lf->dstport);
419
420     fflush(_fflog);
421
422     return(1);
423 }
424
425 /* EOF */