source: trunk/src/sh_prelude.c@ 22

Last change on this file since 22 was 22, checked in by rainer, 19 years ago

Minor code revisions.

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