source: trunk/src/sh_prelude.c@ 118

Last change on this file since 118 was 108, checked in by rainer, 17 years ago

Patch for sh_prelude (deinit, exit on failure if daemon), as requested by Yoann V.

File size: 31.9 KB
RevLine 
[1]1/*
2 *
3 * Copyright (C) 2005 Yoann Vandoorselaere, Prelude IDS Technologies
4 * Rainer Wichmann
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22/*
23 * 28/04/2005 : R.W.:
24 * move libprelude 0.8 code to seperate file
25 *
26 * 23/04/2005 : R.W.:
27 * include libprelude 0.9 code from Yoann Vandoorselaere
28 */
[36]29
30
31/*
32 * for strptime()
33 */
34#define _GNU_SOURCE 1
35
[1]36#include "config_xor.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <sys/types.h>
41
42#if TIME_WITH_SYS_TIME
43
44# include <sys/time.h>
45# include <time.h>
46
47#else
48
49# if HAVE_SYS_TIME_H
50# include <sys/time.h>
51# else
52# include <time.h>
53# endif
54
55#endif
56
57#include <unistd.h>
58#include <syslog.h>
59#include <pwd.h>
60
[20]61int sh_argc_store;
62char ** sh_argv_store;
63
[1]64#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
65
66
67/*
68 * _() macros are samhain specific; they are used to replace string
69 * constants at runtime. This is part of the samhain stealth mode
70 * (fill string constants with encoded strings, decode at runtime).
71 */
72#define FIL__ _("sh_prelude.c")
73
74
75#include <libprelude/idmef.h>
76#include <libprelude/prelude.h>
77
78/*
79 * includes for samhain-specific functions (sl_strstr, sh_error_handle)
80 */
[108]81#include "samhain.h"
[1]82#include "sh_cat.h"
83#include "sh_error_min.h"
84#include "sh_prelude.h"
85
86/*
87 * When SH_USE_XML is set, value are formated using name="value".
88 * Otherwise, value is formatted using the format name=<value>.
89 */
90#ifdef SH_USE_XML
91# define VALUE_DELIM_START '"'
92# define VALUE_DELIM_END '"'
93#else
94# define VALUE_DELIM_START '<'
95# define VALUE_DELIM_END '>'
96#endif
97
98#define IDMEF_ANALYZER_MODEL _("Samhain")
99#define IDMEF_ANALYZER_CLASS _("Integrity Checker")
100#define IDMEF_ANALYZER_VERSION VERSION
[106]101#define IDMEF_ANALYZER_MANUFACTURER _("http://www.la-samhna.de/samhain/")
[1]102
103
104
105/*
106 * 0 = not initialized; -1 = failed; 1 = initialized
107 */
108static int initialized = 0;
109static int ready_for_init = 0;
110
111static char *profile = NULL;
112static prelude_client_t *client = NULL;
113
114static int severity_map[1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH] = {
115 /* 0: unused (?) */ 0,
116 /* 1: INFO */ 0,
117 /* 2: LOW */ SH_ERR_ALL|SH_ERR_INFO,
118 /* 3: MEDIUM */ SH_ERR_NOTICE|SH_ERR_WARN|SH_ERR_STAMP|SH_ERR_ERR,
119 /* 4: HIGH */ SH_ERR_SEVERE|SH_ERR_FATAL
120};
121
122/* returns 0/tiger, 1/sha1, or 2/md5
123 */
124extern int sh_tiger_get_hashtype(void);
125
126static void clear_and_set (int setpos, int flag)
127{
128 unsigned int i;
129 /* clear everywhere, and set at correct position */
130 for (i = 1; i < (1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH); ++i)
131 severity_map[i] &= ~flag;
132 severity_map[setpos] |= flag;
133 return;
134}
135
[22]136static int set_prelude_severity_int (const char * str, int prelude_sev)
[1]137{
[22]138 char * p;
139 char * dup = strdup (str);
[1]140
[26]141 if (!dup)
142 return -1;
143
[22]144 p = strtok (dup, ", \t");
[1]145 if (p) {
146 do {
147 if (0 == strcmp (p, _("alert")))
148 clear_and_set (prelude_sev, SH_ERR_FATAL);
149 else if (0 == strcmp (p, _("crit")))
150 clear_and_set (prelude_sev, SH_ERR_SEVERE);
151 else if (0 == strcmp (p, _("err")))
152 clear_and_set (prelude_sev, SH_ERR_ERR);
153 else if (0 == strcmp (p, _("mark")))
154 clear_and_set (prelude_sev, SH_ERR_STAMP);
155 else if (0 == strcmp (p, _("warn")))
156 clear_and_set (prelude_sev, SH_ERR_WARN);
157 else if (0 == strcmp (p, _("notice")))
158 clear_and_set (prelude_sev, SH_ERR_NOTICE);
159 else if (0 == strcmp (p, _("debug")))
160 clear_and_set (prelude_sev, SH_ERR_ALL);
161 else if (0 == strcmp (p, _("info")))
162 clear_and_set (prelude_sev, SH_ERR_INFO);
[26]163 else {
164 free (dup);
[1]165 return -1;
[26]166 }
[1]167 p = strtok (NULL, ", \t");
168 } while (p);
169 }
[22]170 free(dup);
[1]171 return 0;
172}
173
[22]174int sh_prelude_map_info (const char * str)
[1]175{
176 return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_INFO));
177}
[22]178int sh_prelude_map_low (const char * str)
[1]179{
180 return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_LOW));
181}
[22]182int sh_prelude_map_medium (const char * str)
[1]183{
184 return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_MEDIUM));
185}
[22]186int sh_prelude_map_high (const char * str)
[1]187{
188 return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_HIGH));
189}
190
191static idmef_impact_severity_t map_severity (int sam_sev)
192{
193 int i;
194 int max = 1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH;
195 idmef_impact_severity_t retval = IDMEF_IMPACT_SEVERITY_MEDIUM;
196
197 for (i = 0; i < max; ++i) {
198 if (severity_map[i] & sam_sev) {
199 retval = (idmef_impact_severity_t) i;
200 }
201 }
202 return retval;
203}
204
205static char *do_get_value(char *ptr, char delim_start, char delim_end)
206{
207 char *ret = NULL;
208
209 ptr = strchr(ptr, delim_start);
210 if ( ! ptr )
211 return NULL;
212
213 ret = ++ptr;
214
215 ptr = strchr(ptr, delim_end);
216 if ( ! ptr )
217 return NULL;
218
219 *ptr = '\0';
220 ret = strdup(ret);
221 *ptr = delim_end;
222
223 return ret;
224}
225
226
227
228static char *get_value(char *msg, const char *toktmp, const char *toksuffix)
229{
230 char *ptr, tok[128];
231
232 snprintf(tok, sizeof(tok), "%s%s=", toktmp, (toksuffix) ? toksuffix : "");
233
234 ptr = strstr(msg, tok);
235 if ( ! ptr )
236 return NULL;
237
238 return do_get_value(ptr, VALUE_DELIM_START, VALUE_DELIM_END);
239}
240
241
242
243static char *get_time_value(char *msg, const char *toktmp, const char *toksuffix)
244{
245
246 char *ret, *ptr, tok[128];
247
248 snprintf(tok, sizeof(tok), "%s%s=", toktmp, (toksuffix) ? toksuffix : "");
249
250 ptr = strstr(msg, tok);
251 if ( ! ptr )
252 return NULL;
253
254#ifndef SH_USE_XML
255 ret = do_get_value(ptr, '[', ']');
256#else
257 ret = do_get_value(ptr, VALUE_DELIM_START, VALUE_DELIM_END);
258#endif
259
260 return ret;
261}
262
263
264
265
266#if 0
267void debug_print_message(idmef_message_t *msg)
268{
269 int ret;
270 prelude_io_t *fd;
271
272 ret = prelude_io_new(&fd);
273 if ( ret < 0 )
274 return;
275
276 prelude_io_set_file_io(fd, stderr);
277 idmef_message_print(idmef, fd);
278
279 prelude_io_destroy(fd);
280}
281#endif
282
283
284
285static int idmef_time_from_samhain(idmef_time_t **time, const char *str)
286{
287 int ret;
288 char *ptr;
289 time_t utc;
290 struct tm lt;
291
292 /*
293 * Samhain stamp are encoded in UTC.
294 */
295 ptr = strptime(str, _("%Y-%m-%dT%H:%M:%S"), &lt);
296 if ( ! ptr ) {
297 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
298 _("could not format Samhain time"), _("idmef_time_from_samhain"));
299 return -1;
300 }
301
302 utc = prelude_timegm(&lt);
303
304 ret = idmef_time_new_from_time(time, &utc);
305 if ( ret < 0 )
306 return ret;
307
308 return 0;
309}
310
[22]311/* flawfinder: ignore *//* is part of name, not access() */
[1]312static void get_access_info(idmef_file_access_t *access, char * mode, int pos, int mpos)
313{
314 int got = 0;
315 int ret;
316 prelude_string_t *str;
317
318 do {
319 if ( mode[pos] == 'r' ) {
[22]320 /* flawfinder: ignore *//* is part of name, not access() */
[26]321 ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
[1]322 if ( ret < 0 )
323 return;
324 prelude_string_set_dup(str, _("read"));
325 ++got;
326 }
327 else if ( mode[pos] == 'w' ) {
[22]328 /* flawfinder: ignore *//* is part of name, not access() */
[26]329 ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
[1]330 if ( ret < 0 )
331 return;
332 prelude_string_set_dup(str, _("write"));
333 ++got;
334 }
335 else if ( mode[pos] == 'x' || mode[pos] == 's' || mode[pos] == 't') {
[22]336 /* flawfinder: ignore *//* is part of name, not access() */
[26]337 ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
[1]338 if ( ret < 0 )
339 return;
340
341 if ( mode[pos] == 'x' && mode[0] == 'd' )
342 prelude_string_set_dup(str, _("search"));
343
344 else if ( mode[pos] == 'x' || mode[pos] == 't' )
345 prelude_string_set_dup(str, _("execute"));
346
347 else /* 's' */
348 prelude_string_set_dup(str, _("executeAs"));
349 ++got;
350 }
351 ++pos;
352 } while (pos <= mpos);
353
354 if ( got == 0 ) {
[22]355 /* flawfinder: ignore *//* is part of name, not access() */
[26]356 ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
[1]357 if ( ret < 0 )
358 return;
359 prelude_string_set_dup(str, _("noAccess"));
360 }
361 return;
362}
363
364
365static void get_file_infos(idmef_target_t *target, char *msg,
366 idmef_file_category_t category)
367{
368 int ret;
369 int hashtype = 0;
370 char *ptr;
371 idmef_time_t *time;
372 idmef_file_t *file;
373 idmef_inode_t *inode;
374 prelude_string_t *str;
375 idmef_checksum_t *checksum;
[22]376 idmef_file_access_t *access; /* flawfinder: ignore */
[1]377 idmef_user_id_t *userid;
378 const char *suffix = (category == IDMEF_FILE_CATEGORY_CURRENT) ? "_new" : "_old";
379 char *mode = NULL;
380
[26]381 ret = idmef_target_new_file(target, &file, IDMEF_LIST_APPEND);
[1]382 if ( ret < 0 )
383 return;
384 idmef_file_set_category(file, category);
385
386 ptr = get_value(msg, _("path"), NULL);
387 if ( ptr ) {
388 /*
389 * In term of IDMEF, this is the full path,
390 * including the name.
391 */
392 ret = idmef_file_new_path(file, &str);
[36]393 if ( ret < 0 ) {
394 free(ptr);
[1]395 return;
[36]396 }
[1]397 prelude_string_set_nodup(str, ptr);
398
399 ptr = strrchr(ptr, '/');
400 if ( ptr ) {
401 ret = idmef_file_new_name(file, &str);
[40]402 if ( ret == 0 ) {
403 prelude_string_set_dup(str, ptr + 1);
404 }
[1]405 }
406 }
407
408 ptr = get_value(msg, _("size"), suffix);
409 if ( ptr ) {
410 idmef_file_set_data_size(file, strtoul(ptr, NULL, 10));
411 free(ptr);
412 }
413
414 ptr = get_time_value(msg, _("mtime"), suffix);
415 if ( ptr ) {
416 ret = idmef_time_from_samhain(&time, ptr);
[40]417 if ( ret == 0 ) {
418 idmef_file_set_modify_time(file, time);
[36]419 }
[1]420 free(ptr);
421 }
422
423 ptr = get_time_value(msg, _("ctime"), suffix);
424 if ( ptr ) {
425 ret = idmef_time_from_samhain(&time, ptr);
[40]426 if ( ret == 0 ) {
427 idmef_file_set_create_time(file, time);
[36]428 }
[1]429 free(ptr);
430 }
431
432 ptr = get_value(msg, _("inode"), suffix);
433 if ( ptr ) {
434 ret = idmef_file_new_inode(file, &inode);
[40]435 if ( ret == 0 ) {
436 char * dev = get_value(msg, _("dev"), suffix);
437 if (dev) {
438 char * q = strchr(dev, ',');
439 if (*q) {
440 *q = '\0'; ++q;
441 idmef_inode_set_major_device(inode, strtoul(dev, NULL, 0));
442 idmef_inode_set_minor_device(inode, strtoul( q, NULL, 0));
443 }
444 free(dev);
445 }
446 idmef_inode_set_number(inode, strtoul(ptr, NULL, 10));
[36]447 }
[1]448 free(ptr);
449 }
450
451 ptr = get_value(msg, _("chksum"), suffix);
452 if ( ptr ) {
[26]453 ret = idmef_file_new_checksum(file, &checksum, IDMEF_LIST_APPEND);
[36]454 if ( ret < 0 ) {
[40]455 free(ptr);
456 goto get_mode;
[36]457 }
[1]458
459 hashtype = sh_tiger_get_hashtype();
460
461 if (hashtype == 0)
[40]462 idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_TIGER);
[1]463
[40]464 else if (hashtype == 1)
465 idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_SHA1);
466
467 else if (hashtype == 2)
468 idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_MD5);
469
470 else
471 idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_TIGER);
[1]472
473
[40]474 ret = idmef_checksum_new_value(checksum, &str);
475 if ( ret < 0 ) {
476 free(ptr);
477 goto get_mode;
[36]478 }
[1]479
480 /* will be freed on destroy()
481 */
[40]482 prelude_string_set_nodup(str, ptr);
483 }
[1]484
[40]485 get_mode:
486
[1]487 mode = get_value(msg, _("mode"), suffix);
488 if ( mode ) {
[22]489 /* flawfinder: ignore *//* is part of name, not access() */
[26]490 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
[1]491 if ( ret < 0 )
[40]492 goto get_owner;
[1]493
[22]494 /* flawfinder: ignore *//* is part of name, not access() */
[1]495 ret = idmef_file_access_new_user_id(access, &userid);
496 if ( ret < 0 )
[40]497 goto get_owner;
[1]498 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_OTHER_PRIVS);
499
[22]500 /* flawfinder: ignore *//* is part of name, not access() */
[1]501 get_access_info ( access, mode, 7, 9 );
502 }
[40]503
504 get_owner:
[1]505
506 ptr = get_value(msg, _("owner"), suffix);
507 if ( ptr ) {
[40]508 char * uid;
[1]509
[22]510 /* flawfinder: ignore *//* is part of name, not access() */
[26]511 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
[36]512 if ( ret < 0 ) {
513 free(ptr);
[40]514 goto get_group;
[36]515 }
[1]516
[22]517 /* flawfinder: ignore *//* is part of name, not access() */
[1]518 ret = idmef_file_access_new_user_id(access, &userid);
[36]519 if ( ret < 0 ) {
520 free(ptr);
[40]521 goto get_group;
[36]522 }
[1]523 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_USER_PRIVS);
524
525 ret = idmef_user_id_new_name(userid, &str);
[36]526 if ( ret < 0 ) {
527 free(ptr);
[40]528 goto get_group;
[36]529 }
[1]530 prelude_string_set_nodup(str, ptr);
531
[40]532 uid = get_value(msg, _("iowner"), suffix);
533 if ( ! uid )
534 goto get_group;
[1]535
[40]536 idmef_user_id_set_number(userid, strtoul(uid, NULL, 0));
[1]537
538 if ( mode ) {
[22]539 /* flawfinder: ignore *//* is part of name, not access() */
[1]540 get_access_info ( access, mode, 1, 3 );
541 }
[40]542
543 free(uid);
[1]544 }
545
[40]546 get_group:
547
[1]548 ptr = get_value(msg, _("group"), suffix);
549 if ( ptr ) {
[40]550 char *gid;
[1]551
[22]552 /* flawfinder: ignore *//* is part of name, not access() */
[26]553 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
[36]554 if ( ret < 0 ) {
555 free(ptr);
556 goto mode_free;
557 }
[1]558
[36]559 ret = idmef_file_access_new_user_id(access, &userid);/* flawfinder: ignore *//* is part of name, not access() */
560 if ( ret < 0 ) {
561 free(ptr);
562 goto mode_free;
563 }
564
[1]565 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_GROUP_PRIVS);
566
567 ret = idmef_user_id_new_name(userid, &str);
[36]568 if ( ret < 0 ) {
569 free(ptr);
570 goto mode_free;
571 }
[1]572
573 prelude_string_set_nodup(str, ptr);
574
[40]575 gid = get_value(msg, _("igroup"), suffix);
576 if ( ! gid )
[36]577 goto mode_free;
[1]578
[40]579 idmef_user_id_set_number(userid, strtoul(gid, NULL, 0));
[1]580
581 if ( mode ) {
[22]582 get_access_info ( access, mode, 4, 6 ); /* flawfinder: ignore */
[1]583 }
[40]584
585 free(gid);
[1]586 }
587
[36]588 mode_free:
589
[1]590 if ( mode ) {
591 free ( mode );
592 }
[36]593
594 return;
[1]595}
596
597
598
599static int map_policy_to_class(char *msg, unsigned long msgid, idmef_impact_t *impact, prelude_string_t *out)
600{
601 char *ptr;
602 int ret, i;
603 struct tbl {
604 unsigned int msgid;
605 const char *name;
606 idmef_impact_type_t type;
607 } tbl[] = {
608
609#ifdef SH_USE_UTMP
610 { MSG_UT_LG1X, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
611 { MSG_UT_LG1A, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
612 { MSG_UT_LG1B, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
613 { MSG_UT_LG2X, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
614 { MSG_UT_LG2A, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
615 { MSG_UT_LG2B, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
616 { MSG_UT_LG3X, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
617 { MSG_UT_LG3A, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
618 { MSG_UT_LG3B, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
619 { MSG_UT_LG3C, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
620#endif
621
622#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
623 { MSG_FI_MISS, N_("File Missing"), IDMEF_IMPACT_TYPE_FILE },
624 { MSG_FI_MISS2, N_("File Missing"), IDMEF_IMPACT_TYPE_FILE },
625 { MSG_FI_ADD, N_("File Added"), IDMEF_IMPACT_TYPE_FILE },
626 { MSG_FI_ADD2, N_("File Added"), IDMEF_IMPACT_TYPE_FILE },
627 { MSG_FI_CHAN, N_("File Modified"), IDMEF_IMPACT_TYPE_FILE },
628 { MSG_FI_NODIR, N_("File found where directory was expected"), IDMEF_IMPACT_TYPE_FILE },
629#endif
630
631#ifdef SH_USE_KERN
632 { MSG_KERN_POLICY, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
633 { MSG_KERN_POL_CO, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
634 { MSG_KERN_PROC, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
635 { MSG_KERN_GATE, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
636 { MSG_KERN_IDT, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
637 { MSG_KERN_SYSCALL, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
638#endif
639
640#ifdef SH_USE_SUIDCHK
641 { MSG_SUID_POLICY, N_("SUID/SGID File Detected"), IDMEF_IMPACT_TYPE_FILE },
642#endif
643 /*
644 * This must be the last table entry
645 */
646 { 0, NULL, IDMEF_IMPACT_TYPE_OTHER },
647 };
648
649 for ( i = 0; tbl[i].name != NULL; i++ ) {
650 if ( tbl[i].msgid != msgid )
651 continue;
652
653 idmef_impact_set_type(impact, tbl[i].type);
654 return prelude_string_cat(out, _(tbl[i].name));
655 }
656
657 /* some other message
658 */
659 ptr = get_value(msg, _("msg"), NULL);
660 if ( ! ptr ) {
661 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
662 _("could not format Samhain message"), _("map_policy_to_class"));
663 return -1;
664 }
665
666 ret = prelude_string_cat(out, ptr);
667 free(ptr);
668
669 return ret;
670}
671
672
673
674static int get_login_info(char *msg, idmef_alert_t *alert)
675{
676 int ret;
677 char *ptr, *ip;
678 idmef_user_t *user;
679 idmef_node_t *node;
680 struct passwd *pw;
681 prelude_string_t *str;
682 idmef_user_id_t *user_id;
683 idmef_address_t *address;
684 idmef_target_t *target = idmef_alert_get_next_target(alert, NULL);
685 idmef_source_t *source = idmef_alert_get_next_source(alert, NULL);
686
687 ip = ptr = get_value(msg, _("ip"), NULL);
688 if ( ptr ) {
689 if ( ! source ) {
[26]690 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
[1]691 if ( ret < 0 ) {
692 free(ptr);
693 return ret;
694 }
695 }
696
697 ret = idmef_source_new_node(source, &node);
698 if ( ret < 0 ) {
699 free(ptr);
700 return ret;
701 }
702
[26]703 ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
[1]704 if ( ret < 0 ) {
705 free(ptr);
706 return ret;
707 }
708
709 ret = idmef_address_new_address(address, &str);
710 if ( ret < 0 ) {
711 free(ptr);
712 return ret;
713 }
714
715 prelude_string_set_nodup(str, ptr);
716 }
717
718 ptr = get_value(msg, _("host"), NULL);
719 if ( ptr ) {
720 if ( ip && strcmp(ptr, ip) == 0 )
721 free(ptr);
722 else {
723 if ( ! source ) {
[26]724 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
[1]725 if ( ret < 0 ) {
726 free(ptr);
727 return ret;
728 }
729 }
730
731 ret = idmef_source_new_node(source, &node);
732 if ( ret < 0 ) {
733 free(ptr);
734 return ret;
735 }
736
737 ret = idmef_node_new_name(node, &str);
738 if ( ret < 0 ) {
739 free(ptr);
740 return ret;
741 }
742
743 prelude_string_set_nodup(str, ptr);
744 }
745 }
746
747 ptr = get_value(msg, _("name"), NULL);
748 if ( ptr ) {
749 ret = idmef_target_new_user(target, &user);
750 if ( ret < 0 ) {
751 free(ptr);
752 return ret;
753 }
754
755 idmef_user_set_category(user, IDMEF_USER_CATEGORY_OS_DEVICE);
756
[26]757 ret = idmef_user_new_user_id(user, &user_id, IDMEF_LIST_APPEND);
[1]758 if ( ret < 0 ) {
759 free(ptr);
760 return ret;
761 }
762
763 idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_TARGET_USER);
764
765 pw = getpwnam(ptr);
766 if ( pw )
767 idmef_user_id_set_number(user_id, pw->pw_uid);
768
769 ret = idmef_user_id_new_name(user_id, &str);
770 if ( ret < 0 ) {
771 free(ptr);
772 return ret;
773 }
774 prelude_string_set_nodup(str, ptr);
775
776 ptr = get_value(msg, _("tty"), NULL);
777 if ( ptr ) {
778 ret = idmef_user_id_new_tty(user_id, &str);
779 if ( ret < 0 ) {
780 free(ptr);
781 return ret;
782 }
783
784 prelude_string_set_nodup(str, ptr);
785 }
786 }
787
788 ptr = get_time_value(msg, _("time"), NULL);
789 if ( ptr ) {
790 idmef_time_t *time;
791
792 ret = idmef_time_from_samhain(&time, ptr);
793 free(ptr);
794
795 if ( ret < 0 )
796 return ret;
797
798 idmef_alert_set_detect_time(alert, time);
799 }
800
801 return 0;
802}
803
804
805static int samhain_alert_prelude(int priority, int sh_class,
806 char *message, unsigned long msgid)
807{
808 int ret;
809 idmef_time_t *time;
810 idmef_alert_t *alert;
811 idmef_message_t *idmef;
812 idmef_classification_t *classification;
813 idmef_assessment_t *assessment;
814 idmef_additional_data_t *data;
815 idmef_impact_t *impact;
816 idmef_target_t *target;
817 idmef_confidence_t *confidence;
818 prelude_string_t *str;
819
[15]820 if ( !client || sh_class == STAMP)
[1]821 return 0;
822
823 ret = idmef_message_new(&idmef);
824 if ( ret < 0 )
825 goto err;
826
827 ret = idmef_message_new_alert(idmef, &alert);
828 if ( ret < 0 )
829 goto err;
830
[26]831 idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(client)), IDMEF_LIST_PREPEND);
[1]832
833 ret = idmef_time_new_from_gettimeofday(&time);
834 if ( ret < 0 )
835 goto err;
836 idmef_alert_set_detect_time(alert, time);
837
838 ret = idmef_time_new_from_gettimeofday(&time);
839 if ( ret < 0 )
840 goto err;
841 idmef_alert_set_create_time(alert, time);
842
843 ret = idmef_alert_new_classification(alert, &classification);
844 if ( ret < 0 )
845 goto err;
846
[26]847 ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND);
[1]848 if ( ret < 0 )
849 goto err;
850
851 idmef_target_set_decoy(target, IDMEF_TARGET_DECOY_NO);
852
853 if ( idmef_analyzer_get_node(prelude_client_get_analyzer(client)) ) {
854 idmef_node_ref(idmef_analyzer_get_node(prelude_client_get_analyzer(client)));
855 idmef_target_set_node(target, idmef_analyzer_get_node(prelude_client_get_analyzer(client)));
856 }
857
858 if ( strstr(message, _("path=")) ) {
[2]859#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
[1]860 if ( msgid != MSG_FI_ADD && msgid != MSG_FI_ADD2 )
861 get_file_infos(target, message, IDMEF_FILE_CATEGORY_ORIGINAL);
[2]862#endif
[1]863
864 get_file_infos(target, message, IDMEF_FILE_CATEGORY_CURRENT);
865 }
866
867 ret = idmef_alert_new_assessment(alert, &assessment);
868 if ( ret < 0 )
869 goto err;
870
871 ret = idmef_assessment_new_impact(assessment, &impact);
872 if ( ret < 0 )
873 goto err;
874
875 ret = idmef_classification_new_text(classification, &str);
876 if ( ret < 0 )
877 goto err;
878
879 ret = get_login_info(message, alert);
880 if ( ret < 0 )
881 goto err;
882
883 map_policy_to_class(message, msgid, impact, str);
884
885#if 0
886 if ( priority == SH_ERR_SEVERE || priority == SH_ERR_FATAL )
887 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_HIGH);
888
889 else if ( priority == SH_ERR_ALL || priority == SH_ERR_INFO || priority == SH_ERR_NOTICE )
890 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_LOW);
891
892 else
893 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_MEDIUM);
894#endif
895 idmef_impact_set_severity(impact, map_severity(priority));
896
897 idmef_impact_set_completion(impact, IDMEF_IMPACT_COMPLETION_SUCCEEDED);
898
899 ret = idmef_assessment_new_confidence(assessment, &confidence);
900 if ( ret < 0 )
901 goto err;
902
903 idmef_confidence_set_rating(confidence, IDMEF_CONFIDENCE_RATING_HIGH);
904
[26]905 ret = idmef_alert_new_additional_data(alert, &data, IDMEF_LIST_APPEND);
[1]906 if ( ret < 0 )
907 goto err;
908
909 ret = idmef_additional_data_new_meaning(data, &str);
910 if ( ret < 0 )
911 goto err;
912
913 prelude_string_set_dup(str, _("Message generated by Samhain"));
914 idmef_additional_data_set_type(data, IDMEF_ADDITIONAL_DATA_TYPE_STRING);
915 idmef_additional_data_set_string_ref(data, message);
916
917 /* debug_print_message(idmef); */
918
919 prelude_client_send_idmef(client, idmef);
920 idmef_message_destroy(idmef);
921
922 return 0;
923
924 err:
925 idmef_message_destroy(idmef);
926 return -1;
927}
928
929
930int sh_prelude_alert(int priority, int sh_class, char *message, long msgflags, unsigned long msgid)
931{
932 int ret;
933
934 (void) msgflags; /* fix compiler warning */
935
[15]936 if ( initialized < 1 )
[1]937 return -1;
938
939 ret = samhain_alert_prelude(priority, sh_class, message, msgid);
940 if ( ret < 0 ) {
941 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
942 _("Problem with IDMEF for prelude-ids support: alert lost"),
943 _("sh_prelude_alert"));
944 }
945
946 return ret;
947}
948
949
950
[22]951int sh_prelude_set_profile(const char *arg)
[1]952{
953 if ( profile ) {
954 free(profile);
955 profile = NULL;
956 }
957
958 if ( arg ) {
959 profile = strdup(arg);
960 if ( ! profile )
961 return -1;
962 }
963
964 return 0;
965}
966
[86]967/* Allow initialization of prelude; to be called
968 * after forking the daemon. Delays heartbeat
969 * start after config read until it is safe.
970 */
[1]971void sh_prelude_reset(void)
972{
973 extern void sh_error_init_prelude();
974
975 ready_for_init = 1;
976 sh_error_init_prelude();
977 return;
978}
979
980
981
982void sh_prelude_stop(void)
983{
984 if (initialized < 1)
985 return;
[108]986
987 if (sh.flag.isdaemon == S_TRUE)
988 prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
989 else
990 prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS);
991
[15]992 client = NULL;
[108]993
994 prelude_deinit();
995
[1]996 initialized = 0;
997 return;
998}
999
1000
1001
1002int sh_prelude_init(void)
1003{
1004 int ret;
1005 prelude_string_t *str;
1006 idmef_analyzer_t *analyzer;
1007 prelude_client_flags_t flags;
[20]1008#ifdef SH_NOFAILOVER
1009 prelude_connection_pool_t *pool;
1010 prelude_connection_pool_flags_t conn_flags;
1011#endif
[1]1012
1013 if (ready_for_init == 0)
1014 return initialized;
1015
1016 if (initialized > 0)
1017 return initialized;
1018
1019 prelude_thread_init(NULL);
[20]1020 prelude_init(&sh_argc_store, sh_argv_store);
[1]1021
1022 ret = prelude_client_new(&client, profile ? profile : _("samhain"));
1023 if ( ret < 0 ) {
1024 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1025 _("Failed to initialize Prelude"), _("sh_prelude_init"));
1026 initialized = -1;
1027 return -1;
1028 }
1029
1030 /*
1031 * Enable automatic heartbeat sending.
1032 */
1033 flags = prelude_client_get_flags(client);
1034 ret = prelude_client_set_flags(client, flags | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER);
1035
1036 analyzer = prelude_client_get_analyzer(client);
1037
1038 ret = idmef_analyzer_new_model(analyzer, &str);
1039 prelude_string_set_dup(str, IDMEF_ANALYZER_MODEL);
1040
1041 ret = idmef_analyzer_new_class(analyzer, &str);
1042 prelude_string_set_dup(str, IDMEF_ANALYZER_CLASS);
1043
1044 ret = idmef_analyzer_new_version(analyzer, &str);
1045 prelude_string_set_dup(str, IDMEF_ANALYZER_VERSION);
1046
[20]1047#ifdef SH_NOFAILOVER
1048 pool = prelude_client_get_connection_pool(client);
1049 conn_flags = prelude_connection_pool_get_flags(pool);
1050
1051 conn_flags &= ~PRELUDE_CONNECTION_POOL_FLAGS_FAILOVER;
1052 prelude_connection_pool_set_flags(pool, conn_flags);
1053#endif
1054
[1]1055 ret = prelude_client_start(client);
1056 if ( ret < 0 ) {
1057 prelude_perror(ret, _("error starting prelude client"));
1058
1059 if ( prelude_client_is_setup_needed(ret) )
1060 prelude_client_print_setup_error(client);
1061
1062 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1063 _("Failed to start Prelude"), _("sh_prelude_init"));
1064 initialized = -1;
1065 return -1;
1066 }
1067
1068 initialized = 1;
1069 return 1;
1070}
1071
1072/* HAVE_LIBPRELUDE_9 */
1073#endif
1074
Note: See TracBrowser for help on using the repository browser.