source: branches/samhain-2_2-branch/src/sh_prelude.c@ 197

Last change on this file since 197 was 40, checked in by rainer, 18 years ago

Fix for tickets #13, #14, #15, #16, #17

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