Imported Upstream version 2.3
[ossec-hids.git] / src / analysisd / prelude.c
1 /* @(#) $Id: prelude.c,v 1.14 2009/11/09 20:18:52 dcid Exp $ */
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 3) as published by the FSF - Free Software
9  * Foundation
10  */
11
12
13 #ifdef PRELUDE
14
15 #include <libprelude/prelude.h>
16 #include <libprelude/prelude-log.h>
17 #include <libprelude/idmef-message-print.h>
18
19 #include "prelude.h"
20 #include "shared.h"
21 #include "eventinfo.h"
22
23 #define DEFAULT_ANALYZER_NAME "OSSEC"
24 #define ANALYZER_CLASS "Host IDS, File Integrity Checker, Log Analyzer"
25 #define ANALYZER_MODEL "Ossec"
26 #define ANALYZER_MANUFACTURER __site
27 #define ANALYZER_VERSION __version
28
29
30 /*
31  * Ossec to Prelude
32  */
33
34
35 /** OSSEC to prelude severity mapping. **/
36 char *(ossec2prelude_sev[])={"info","info","info","info",
37                              "low","low","low","low",
38                              "medium", "medium", "medium", "medium",
39                              "high", "high", "high", "high", "high"};
40                 
41
42 /* Prelude client */
43 static prelude_client_t *prelude_client;
44
45
46 void prelude_idmef_debug(idmef_message_t *idmef)
47 {
48         prelude_io_t *pio;
49
50         prelude_io_new(&pio);
51         prelude_io_set_file_io(pio, stderr);
52         idmef_message_print(idmef, pio);
53         prelude_io_destroy(pio);
54 }
55
56
57
58 static int 
59 add_idmef_object(idmef_message_t *msg, const char *object, const char *value)
60 {
61     int ret = 0;
62     idmef_value_t *val;
63     idmef_path_t *path;
64
65     /* Can value be null? better check in here.  */
66     if(value == NULL)
67     {
68         return(0);
69     }
70
71     ret = idmef_path_new_fast(&path, object);
72     if(ret < 0)
73     {
74         return(-1);
75     }
76
77     ret = idmef_value_new_from_path(&val, path, value);
78     if(ret < 0) 
79     {
80         idmef_path_destroy(path);
81         return(-1);
82     }
83
84     ret = idmef_path_set(path, msg, val);
85     if(ret < 0) 
86     {
87         merror("%s: OSSEC2Prelude: IDMEF: Cannot add object '%s': %s.", 
88                ARGV0, object, prelude_strerror(ret));
89     }
90
91     idmef_value_destroy(val);
92     idmef_path_destroy(path);
93
94     return(ret);
95 }
96
97
98 static int
99 setup_analyzer(idmef_analyzer_t *analyzer)
100 {
101     int ret;
102     prelude_string_t *string;
103
104     ret = idmef_analyzer_new_model(analyzer, &string);
105     if ( ret < 0 )
106         goto err;
107     prelude_string_set_constant(string, ANALYZER_MODEL);
108
109     ret = idmef_analyzer_new_class(analyzer, &string);
110     if ( ret < 0 )
111         goto err;
112     prelude_string_set_constant(string, ANALYZER_CLASS);
113
114     ret = idmef_analyzer_new_manufacturer(analyzer, &string);
115     if ( ret < 0 )
116         goto err;
117     prelude_string_set_constant(string, ANALYZER_MANUFACTURER);
118
119     ret = idmef_analyzer_new_version(analyzer, &string);
120     if ( ret < 0 )
121         goto err;
122     prelude_string_set_constant(string, ANALYZER_VERSION);
123
124
125     return 0;
126
127     err:
128     merror("%s: OSSEC2Prelude: %s: IDMEF error: %s.",
129             ARGV0, prelude_strsource(ret), prelude_strerror(ret));
130
131     return -1;
132 }
133
134
135
136 void prelude_start(char *profile, int argc, char **argv)
137 {
138     int ret;
139     prelude_client = NULL;
140
141
142     ret = prelude_init(&argc, argv);
143     if (ret < 0) 
144     {
145         merror("%s: %s: Unable to initialize the Prelude library: %s.",
146                ARGV0, prelude_strsource(ret), prelude_strerror(ret));
147         return;
148     }
149
150     ret = prelude_client_new(&prelude_client, 
151                              profile!=NULL?profile:DEFAULT_ANALYZER_NAME);
152     if (!prelude_client) 
153     {
154         merror("%s: %s: Unable to create a prelude client object: %s.",
155                ARGV0, prelude_strsource(ret), prelude_strerror(ret));
156
157         return;
158     }
159
160
161     ret = setup_analyzer(prelude_client_get_analyzer(prelude_client));
162     if(ret < 0) 
163     {
164         merror("%s: %s: Unable to setup analyzer: %s",
165                ARGV0, prelude_strsource(ret), prelude_strerror(ret));
166
167         prelude_client_destroy(prelude_client, 
168                                PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
169
170         return;
171     }
172
173
174     ret = prelude_client_set_flags(prelude_client, 
175           prelude_client_get_flags(prelude_client) 
176           | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER);
177     if(ret < 0)
178     {
179         merror("%s: %s: Unable to set prelude client flags: %s.",
180                ARGV0, prelude_strsource(ret), prelude_strerror(ret)); 
181     }
182
183
184     /* Setting uid and gid of ossec. */
185     prelude_client_profile_set_uid(prelude_client_get_profile(prelude_client),
186                                    Privsep_GetUser(USER));
187     prelude_client_profile_set_gid(prelude_client_get_profile(prelude_client),
188                                    Privsep_GetGroup(GROUPGLOBAL));
189
190
191     ret = prelude_client_start(prelude_client);
192     if (ret < 0) 
193     {
194         merror("%s: %s: Unable to initialize prelude client: %s.",
195                ARGV0, prelude_strsource(ret), prelude_strerror(ret));
196
197         prelude_client_destroy(prelude_client, 
198                                PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
199
200         return;
201     }
202
203
204     return;
205
206 }
207
208
209
210 void OS_PreludeLog(Eventinfo *lf)
211 {
212     int ret;
213     idmef_message_t *idmef;
214
215     
216     /* Generate prelude alert */
217     ret = idmef_message_new(&idmef);
218     if ( ret < 0 )
219     {
220         merror("%s: OSSEC2Prelude: Cannot create IDMEF message", ARGV0);
221         return;
222     }
223
224     
225     add_idmef_object(idmef, "alert.assessment.impact.description", 
226                             lf->generated_rule->comment);
227     
228     add_idmef_object(idmef, "alert.assessment.impact.severity", 
229                             (lf->generated_rule->level > 15) ? "high": 
230                             ossec2prelude_sev[lf->generated_rule->level]);
231                     
232     add_idmef_object(idmef, "alert.assessment.impact.completion", "succeeded");
233     
234     add_idmef_object(idmef, "alert.classification.text", 
235                             lf->generated_rule->comment);
236     
237
238     /* Setting source info. */
239     add_idmef_object(idmef, "alert.source(0).Spoofed", "no");
240     add_idmef_object(idmef, "alert.source(0).Node.Address(0).address", 
241                             lf->srcip);
242     add_idmef_object(idmef, "alert.source(0).Service.port", lf->srcport);
243
244     if(lf->srcuser)
245     {
246         add_idmef_object(idmef, "alert.source(0).User.UserId(0).name", lf->srcuser);
247     }
248
249
250     /* Setting target */
251     add_idmef_object(idmef, "alert.target(0).Service.name", lf->program_name);
252     add_idmef_object(idmef, "alert.target(0).Spoofed", "no");
253
254     if(lf->dstip)
255     {
256         add_idmef_object(idmef, "alert.target(0).Node.Address(0).address", 
257                                 lf->dstip);
258     }
259     else
260     {
261         char *tmp_str;
262         char new_prelude_target[256];
263
264         new_prelude_target[255] = '\0';
265         strncpy(new_prelude_target, lf->hostname, 255);
266
267         /* The messages can have the file, so we need to remove it.
268          * formats can be:
269          * enigma->/var/log/authlog
270          * (esqueleto2) 192.168.2.99->/var/log/squid/access.log
271          */
272         tmp_str = strstr(new_prelude_target, "->");
273         if(tmp_str)
274         {
275             *tmp_str = '\0';
276         }
277         add_idmef_object(idmef, "alert.target(0).Node.Address(0).address", 
278                                 new_prelude_target);
279     }
280     add_idmef_object(idmef, "alert.target(0).Service.name", lf->hostname);
281     add_idmef_object(idmef, "alert.target(0).Service.port", lf->dstport);
282
283     if(lf->dstuser)
284     {
285         add_idmef_object(idmef, "alert.target(0).User.category", "2");
286         add_idmef_object(idmef, "alert.target(0).User.UserId(0).name", lf->dstuser);
287     }
288
289
290     /* Setting source file. */
291     add_idmef_object(idmef, "alert.additional_data(0).type", "string");
292     add_idmef_object(idmef, "alert.additional_data(0).meaning", "Source file");
293     add_idmef_object(idmef, "alert.additional_data(0).data", lf->location);
294     
295
296     /* Setting full log. */
297     add_idmef_object(idmef, "alert.additional_data(1).type", "string");
298     add_idmef_object(idmef, "alert.additional_data(1).meaning", "Full Log");
299     add_idmef_object(idmef, "alert.additional_data(1).data", lf->full_log);
300
301     idmef_alert_set_analyzer(idmef_message_get_alert(idmef),
302                              idmef_analyzer_ref
303                              (prelude_client_get_analyzer(prelude_client)),
304                              IDMEF_LIST_PREPEND);
305
306     prelude_client_send_idmef(prelude_client, idmef);
307     idmef_message_destroy(idmef);
308 }
309
310
311
312 #endif /* PRELUDE */
313
314 /* EOF */