source: trunk/src/sh_prelude.c@ 38

Last change on this file since 38 was 37, checked in by rainer, 18 years ago

stat() -> lstat() in sh_prelude.c

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