source: trunk/src/sh_prelude.c@ 27

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

Prelude patch by Yoann.

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