source: trunk/src/sh_prelude.c@ 20

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

Enable command-line parsing for prelude, and make prelude regression test safer.

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