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 <ctype.h>
41 #include <sys/types.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 #include <unistd.h>
59 #include <syslog.h>
60 #include <pwd.h>
61 
62 int     sh_argc_store;
63 char ** sh_argv_store;
64 
65 #if defined(HAVE_LIBPRELUDE)
66 
67 
68 /*
69  * _() macros are samhain specific; they are used to replace string
70  * constants at runtime. This is part of the samhain stealth mode
71  * (fill string constants with encoded strings, decode at runtime).
72  */
73 #define FIL__  _("sh_prelude.c")
74 
75 
76 #include <libprelude/idmef.h>
77 #include <libprelude/prelude.h>
78 
79 /*
80  * includes for samhain-specific functions (sl_strstr, sh_error_handle)
81  */
82 #include "samhain.h"
83 #include "sh_cat.h"
84 #include "sh_error_min.h"
85 #include "sh_prelude.h"
86 #define SH_NEED_PWD_GRP 1
87 #include "sh_static.h"
88 char * sh_util_strdup (const char * str) SH_GNUC_MALLOC;
89 /*
90  * When SH_USE_XML is set, value are formated using name="value".
91  * Otherwise, value is formatted using the format name=<value>.
92  */
93 #ifdef SH_USE_XML
94 # define VALUE_DELIM_START '"'
95 # define VALUE_DELIM_END   '"'
96 #else
97 # define VALUE_DELIM_START '<'
98 # define VALUE_DELIM_END   '>'
99 #endif
100 
101 #define IDMEF_ANALYZER_MODEL _("Samhain")
102 #define IDMEF_ANALYZER_CLASS _("Integrity Checker")
103 #define IDMEF_ANALYZER_VERSION VERSION
104 #define IDMEF_ANALYZER_MANUFACTURER _("http://www.la-samhna.de/samhain/")
105 
106 
107 
108 /*
109  * 0 = not initialized; -1 = failed; 1 = initialized
110  */
111 static int initialized = 0;
112 static int ready_for_init = 0;
113 
114 static char *profile = NULL;
115 static prelude_client_t *client = NULL;
116 
117 static int severity_map[1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH] = {
118         /* 0: unused (?) */ 0,
119         /* 1: INFO       */ 0,
120         /* 2: LOW        */ SH_ERR_ALL|SH_ERR_INFO,
121         /* 3: MEDIUM     */ SH_ERR_NOTICE|SH_ERR_WARN|SH_ERR_STAMP|SH_ERR_ERR,
122         /* 4: HIGH       */ SH_ERR_SEVERE|SH_ERR_FATAL
123 };
124 
125 /* returns 0/tiger, 1/sha1, or 2/md5
126  */
127 extern int sh_tiger_get_hashtype(void);
128 
clear_and_set(int setpos,int flag)129 static void clear_and_set (int setpos, int flag)
130 {
131         unsigned int i;
132 	/* clear everywhere, and set at correct position */
133         for (i = 1; i < (1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH); ++i)
134                 severity_map[i] &= ~flag;
135         severity_map[setpos] |= flag;
136         return;
137 }
138 
set_prelude_severity_int(const char * str,int prelude_sev)139 static int set_prelude_severity_int (const char * str, int prelude_sev)
140 {
141         char * p;
142 	char * dup = strdup (str);
143 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
144 	char * saveptr;
145 #endif
146 
147 	if (!dup)
148 	        return -1;
149 
150 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
151 	p = strtok_r (dup, ", \t", &saveptr);
152 #else
153 	p = strtok (dup, ", \t");
154 #endif
155         if (p) {
156                 do {
157                         if      (0 == strcmp (p, _("alert")))
158                                 clear_and_set (prelude_sev, SH_ERR_FATAL);
159                         else if (0 == strcmp (p, _("crit")))
160                                 clear_and_set (prelude_sev, SH_ERR_SEVERE);
161                         else if (0 == strcmp (p, _("err")))
162                                 clear_and_set (prelude_sev, SH_ERR_ERR);
163                         else if (0 == strcmp (p, _("mark")))
164 	                        clear_and_set (prelude_sev, SH_ERR_STAMP);
165                         else if (0 == strcmp (p, _("warn")))
166 	                        clear_and_set (prelude_sev, SH_ERR_WARN);
167                         else if (0 == strcmp (p, _("notice")))
168                                 clear_and_set (prelude_sev, SH_ERR_NOTICE);
169                         else if (0 == strcmp (p, _("debug")))
170 	                        clear_and_set (prelude_sev, SH_ERR_ALL);
171                         else if (0 == strcmp (p, _("info")))
172 	                        clear_and_set (prelude_sev, SH_ERR_INFO);
173                         else {
174 			        free (dup);
175 	                        return -1;
176 			}
177 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
178                         p = strtok_r (NULL, ", \t", &saveptr);
179 #else
180                         p = strtok (NULL, ", \t");
181 #endif
182                 } while (p);
183         }
184 	free(dup);
185         return 0;
186 }
187 
sh_prelude_map_info(const char * str)188 int sh_prelude_map_info (const char * str)
189 {
190         return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_INFO));
191 }
sh_prelude_map_low(const char * str)192 int sh_prelude_map_low (const char * str)
193 {
194         return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_LOW));
195 }
sh_prelude_map_medium(const char * str)196 int sh_prelude_map_medium (const char * str)
197 {
198         return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_MEDIUM));
199 }
sh_prelude_map_high(const char * str)200 int sh_prelude_map_high (const char * str)
201 {
202         return (set_prelude_severity_int(str,(int)IDMEF_IMPACT_SEVERITY_HIGH));
203 }
204 
map_severity(int sam_sev)205 static idmef_impact_severity_t map_severity (int sam_sev)
206 {
207         int i;
208         int max = 1 + (unsigned int) IDMEF_IMPACT_SEVERITY_HIGH;
209         idmef_impact_severity_t retval = IDMEF_IMPACT_SEVERITY_MEDIUM;
210 
211         for (i = 0; i < max; ++i) {
212 	        if (severity_map[i] & sam_sev) {
213 	                retval = (idmef_impact_severity_t) i;
214 	        }
215 	}
216 	return retval;
217 }
218 
do_get_value(char * ptr,char delim_start,char delim_end)219 static char *do_get_value(char *ptr, char delim_start, char delim_end)
220 {
221         char *ret = NULL;
222 #if defined(SH_WITH_SERVER)
223         int    delim_start_count = 0;
224         int    found = 0;
225 #endif
226 
227         ptr = strchr(ptr, delim_start);
228         if ( ! ptr )
229                 return NULL;
230 
231         ret = ++ptr;
232 #if defined(SH_WITH_SERVER)
233         while ((*ptr != '\0') && (!found)){
234 		if (*ptr == delim_end) {
235 		        if (delim_start_count == 0)
236 			        found = 1;
237 			delim_start_count--;
238 		}
239 		else if (*ptr == delim_start)
240 		        delim_start_count++;
241 		ptr++;
242         }
243         ptr = (found) ? ptr-1 : NULL ;
244 #else
245         ptr = strchr(ptr, delim_end);
246 #endif
247         if ( ! ptr )
248                 return NULL;
249 
250         *ptr = '\0';
251         ret = strdup(ret);
252         *ptr = delim_end;
253 
254         return ret;
255 }
256 
257 
258 
get_value(char * msg,const char * toktmp,const char * toksuffix)259 static char *get_value(char *msg, const char *toktmp, const char *toksuffix)
260 {
261         char *ptr, tok[128];
262 
263         snprintf(tok, sizeof(tok), "%s%s=", toktmp, (toksuffix) ? toksuffix : "");
264 
265         ptr = strstr(msg, tok);
266         if ( ! ptr )
267                 return NULL;
268 
269         return do_get_value(ptr, VALUE_DELIM_START, VALUE_DELIM_END);
270 }
271 
272 
273 
get_time_value(char * msg,const char * toktmp,const char * toksuffix)274 static char *get_time_value(char *msg, const char *toktmp, const char *toksuffix)
275 {
276 
277         char *ret, *ptr, tok[128];
278 
279         snprintf(tok, sizeof(tok), "%s%s=", toktmp, (toksuffix) ? toksuffix : "");
280 
281         ptr = strstr(msg, tok);
282         if ( ! ptr )
283                 return NULL;
284 
285 #ifndef SH_USE_XML
286         ret = do_get_value(ptr, '[', ']');
287 #else
288         ret = do_get_value(ptr, VALUE_DELIM_START, VALUE_DELIM_END);
289 #endif
290 
291         return ret;
292 }
293 
294 
295 
296 
297 #if 0
298 void debug_print_message(idmef_message_t *msg)
299 {
300         int ret;
301         prelude_io_t *fd;
302 
303         ret = prelude_io_new(&fd);
304         if ( ret < 0 )
305                 return;
306 
307         prelude_io_set_file_io(fd, stderr);
308         idmef_message_print(idmef, fd);
309 
310         prelude_io_destroy(fd);
311 }
312 #endif
313 
314 
315 
idmef_time_from_samhain(idmef_time_t ** time,const char * str)316 static int idmef_time_from_samhain(idmef_time_t **time, const char *str)
317 {
318         int ret;
319         char *ptr;
320         time_t utc;
321         struct tm lt;
322 
323         /*
324          * Samhain stamp are encoded in UTC.
325          */
326         ptr = strptime(str, _("%Y-%m-%dT%H:%M:%S"), &lt);
327         if ( ! ptr ) {
328                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
329                                 _("could not format Samhain time"), _("idmef_time_from_samhain"));
330                 return -1;
331         }
332 
333         utc = prelude_timegm(&lt);
334 
335         ret = idmef_time_new_from_time(time, &utc);
336         if ( ret < 0 )
337                 return ret;
338 
339         return 0;
340 }
341 
342 /* flawfinder: ignore *//* is part of name, not access() */
get_access_info(idmef_file_access_t * access,char * mode,int pos,int mpos)343 static void get_access_info(idmef_file_access_t *access, char * mode, int pos, int mpos)
344 {
345         int got = 0;
346 	int ret;
347 	prelude_string_t *str;
348 
349 	do {
350 	        if ( mode[pos] == 'r' ) {
351 			/* flawfinder: ignore *//* is part of name, not access() */
352 	                ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
353 	                if ( ret < 0 )
354 	                        return;
355 	                prelude_string_set_dup(str, _("read"));
356 	                ++got;
357 	        }
358 	        else if ( mode[pos] == 'w' ) {
359 			/* flawfinder: ignore *//* is part of name, not access() */
360 	                ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
361 	                if ( ret < 0 )
362 	                        return;
363 	                prelude_string_set_dup(str, _("write"));
364 	                ++got;
365 	        }
366 	        else if ( mode[pos] == 'x' || mode[pos] == 's' || mode[pos] == 't') {
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 
372 	                if ( mode[pos] == 'x' && mode[0] == 'd' )
373 	                        prelude_string_set_dup(str, _("search"));
374 
375                         else if ( mode[pos] == 'x' || mode[pos] == 't' )
376 	                        prelude_string_set_dup(str, _("execute"));
377 
378                         else /* 's' */
379 	                        prelude_string_set_dup(str, _("executeAs"));
380 	                ++got;
381 	        }
382 	        ++pos;
383 	} while (pos <= mpos);
384 
385 	if ( got == 0 ) {
386 	        /* flawfinder: ignore *//* is part of name, not access() */
387 	        ret = idmef_file_access_new_permission(access, &str, IDMEF_LIST_APPEND);
388 	        if ( ret < 0 )
389 	                return;
390 	        prelude_string_set_dup(str, _("noAccess"));
391 	}
392 	return;
393 }
394 
395 
get_file_infos(idmef_target_t * target,char * msg,idmef_file_category_t category)396 static void get_file_infos(idmef_target_t *target, char *msg,
397 			   idmef_file_category_t category)
398 {
399         int ret;
400         int hashtype = 0;
401         char *ptr;
402         idmef_time_t *time;
403         idmef_file_t *file;
404         idmef_inode_t *inode;
405         prelude_string_t *str;
406         idmef_checksum_t *checksum;
407         idmef_file_access_t *access; /* flawfinder: ignore */
408         idmef_user_id_t *userid;
409         const char *suffix = (category == IDMEF_FILE_CATEGORY_CURRENT) ? "_new" : "_old";
410 	char *mode = NULL;
411 
412         ret = idmef_target_new_file(target, &file, IDMEF_LIST_APPEND);
413         if ( ret < 0  )
414                 return;
415         idmef_file_set_category(file, category);
416 
417         ptr = get_value(msg, _("path"), NULL);
418         if ( ptr ) {
419                 /*
420                  * In term of IDMEF, this is the full path,
421                  * including the name.
422                  */
423                 ret = idmef_file_new_path(file, &str);
424                 if ( ret < 0 ) {
425 		        free(ptr);
426                         return;
427 		}
428                 prelude_string_set_nodup(str, ptr);
429 
430                 ptr = strrchr(ptr, '/');
431                 if ( ptr ) {
432                         ret = idmef_file_new_name(file, &str);
433                         if ( ret == 0 ) {
434 			        prelude_string_set_dup(str, ptr + 1);
435 			}
436                 }
437         }
438 
439         ptr = get_value(msg, _("size"), suffix);
440 	if ( ptr ) {
441                 idmef_file_set_data_size(file, strtoul(ptr, NULL, 10));
442                 free(ptr);
443         }
444 
445         ptr = get_time_value(msg, _("mtime"), suffix);
446         if ( ptr ) {
447                 ret = idmef_time_from_samhain(&time, ptr);
448                 if ( ret == 0 ) {
449                         idmef_file_set_modify_time(file, time);
450 		}
451                 free(ptr);
452         }
453 
454         ptr = get_time_value(msg, _("ctime"), suffix);
455         if ( ptr ) {
456                 ret = idmef_time_from_samhain(&time, ptr);
457                 if ( ret == 0 ) {
458                         idmef_file_set_create_time(file, time);
459 		}
460                 free(ptr);
461         }
462 
463         ptr = get_value(msg, _("inode"), suffix);
464         if ( ptr ) {
465                 ret = idmef_file_new_inode(file, &inode);
466                 if ( ret == 0 ) {
467 			char * dev = get_value(msg, _("dev"), suffix);
468 			if (dev) {
469 			        char * q = strchr(dev, ',');
470 				if (*q) {
471 				         *q = '\0'; ++q;
472 					 idmef_inode_set_major_device(inode, strtoul(dev, NULL, 0));
473 					 idmef_inode_set_minor_device(inode, strtoul(  q, NULL, 0));
474 				}
475 				free(dev);
476 			}
477 			idmef_inode_set_number(inode, strtoul(ptr, NULL, 10));
478 		}
479                 free(ptr);
480         }
481 
482         ptr = get_value(msg, _("chksum"), suffix);
483         if ( ptr ) {
484                 ret = idmef_file_new_checksum(file, &checksum, IDMEF_LIST_APPEND);
485                 if ( ret < 0 ) {
486 			free(ptr);
487 			goto get_mode;
488 		}
489 
490 		hashtype = sh_tiger_get_hashtype();
491 
492 		if (hashtype == 0)
493 			idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_TIGER);
494 
495 		else if (hashtype == 1)
496 			idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_SHA1);
497 
498 		else if (hashtype == 2)
499 			idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_MD5);
500 
501 		else
502 			idmef_checksum_set_algorithm(checksum, IDMEF_CHECKSUM_ALGORITHM_TIGER);
503 
504 
505 		ret = idmef_checksum_new_value(checksum, &str);
506 		if ( ret < 0 ) {
507 			free(ptr);
508 			goto get_mode;
509 		}
510 
511 		/* will be freed on destroy()
512 		 */
513 		prelude_string_set_nodup(str, ptr);
514 	}
515 
516  get_mode:
517 
518 	mode = get_value(msg, _("mode"), suffix);
519         if ( mode ) {
520 	        /* flawfinder: ignore *//* is part of name, not access() */
521                 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
522                 if ( ret < 0 )
523                         goto get_owner;
524 
525 	        /* flawfinder: ignore *//* is part of name, not access() */
526                 ret = idmef_file_access_new_user_id(access, &userid);
527                 if ( ret < 0 )
528                         goto get_owner;
529                 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_OTHER_PRIVS);
530 
531 	        /* flawfinder: ignore *//* is part of name, not access() */
532 		get_access_info ( access, mode, 7, 9 );
533         }
534 
535  get_owner:
536 
537         ptr = get_value(msg, _("owner"), suffix);
538         if ( ptr ) {
539 	        char * uid;
540 
541 	        /* flawfinder: ignore *//* is part of name, not access() */
542                 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
543                 if ( ret < 0 ) {
544                         free(ptr);
545                         goto get_group;
546 		}
547 
548 	        /* flawfinder: ignore *//* is part of name, not access() */
549                 ret = idmef_file_access_new_user_id(access, &userid);
550                 if ( ret < 0 ) {
551                         free(ptr);
552                         goto get_group;
553 		}
554                 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_USER_PRIVS);
555 
556                 ret = idmef_user_id_new_name(userid, &str);
557                 if ( ret < 0 ) {
558                         free(ptr);
559                         goto get_group;
560                 }
561                 prelude_string_set_nodup(str, ptr);
562 
563                 uid = get_value(msg, _("iowner"), suffix);
564                 if ( ! uid )
565                         goto get_group;
566 
567                 idmef_user_id_set_number(userid, strtoul(uid, NULL, 0));
568 
569 		if ( mode ) {
570 		        /* flawfinder: ignore *//* is part of name, not access() */
571 		        get_access_info ( access, mode, 1, 3 );
572 		}
573 
574 		free(uid);
575 		/* Don't free(ptr) because of prelude_string_set_nodup(str, ptr) */
576         }
577 
578  get_group:
579 
580         ptr = get_value(msg, _("group"), suffix);
581         if ( ptr ) {
582                 char *gid;
583 
584 	        /* flawfinder: ignore *//* is part of name, not access() */
585                 ret = idmef_file_new_file_access(file, &access, IDMEF_LIST_APPEND);
586                 if ( ret < 0 ) {
587                         free(ptr);
588                         goto mode_free;
589 		}
590 
591                 ret = idmef_file_access_new_user_id(access, &userid);/* flawfinder: ignore *//* is part of name, not access() */
592                 if ( ret < 0 ) {
593                         free(ptr);
594                         goto mode_free;
595 		}
596 
597                 idmef_user_id_set_type(userid, IDMEF_USER_ID_TYPE_GROUP_PRIVS);
598 
599                 ret = idmef_user_id_new_name(userid, &str);
600                 if ( ret < 0 ) {
601                         free(ptr);
602                         goto mode_free;
603 		}
604 
605                 prelude_string_set_nodup(str, ptr);
606 
607                 gid = get_value(msg, _("igroup"), suffix);
608                 if ( ! gid )
609                         goto mode_free;
610 
611                 idmef_user_id_set_number(userid, strtoul(gid, NULL, 0));
612 
613 		if ( mode ) {
614 		        get_access_info ( access, mode, 4, 6 ); /* flawfinder: ignore */
615 		}
616 
617 		free(gid);
618 		/* Don't free(ptr) because of prelude_string_set_nodup(str, ptr) */
619         }
620 
621  mode_free:
622 
623 	if ( mode ) {
624 	        free ( mode );
625 	}
626 
627 	return;
628 }
629 
630 
631 
map_policy_to_class(char * msg,unsigned long msgid,idmef_impact_t * impact,prelude_string_t * out)632 static int map_policy_to_class(char *msg, unsigned long msgid, idmef_impact_t *impact, prelude_string_t *out)
633 {
634         char *ptr;
635         int ret, i;
636         struct tbl {
637                 unsigned int msgid;
638                 const char *name;
639                 idmef_impact_type_t type;
640         } tbl[] = {
641 
642 #ifdef SH_USE_UTMP
643                 { MSG_UT_LG1X, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
644                 { MSG_UT_LG1A, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
645                 { MSG_UT_LG1B, N_("User Login"), IDMEF_IMPACT_TYPE_USER },
646                 { MSG_UT_LG2X, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
647                 { MSG_UT_LG2A, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
648                 { MSG_UT_LG2B, N_("Multiple User Login"), IDMEF_IMPACT_TYPE_USER },
649                 { MSG_UT_LG3X, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
650                 { MSG_UT_LG3A, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
651                 { MSG_UT_LG3B, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
652                 { MSG_UT_LG3C, N_("User Logout"), IDMEF_IMPACT_TYPE_USER },
653 #endif
654 
655 #if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
656                 { MSG_FI_MISS,  N_("File Missing"), IDMEF_IMPACT_TYPE_FILE },
657                 { MSG_FI_MISS2, N_("File Missing"), IDMEF_IMPACT_TYPE_FILE },
658                 { MSG_FI_ADD, N_("File Added"), IDMEF_IMPACT_TYPE_FILE },
659                 { MSG_FI_ADD2, N_("File Added"), IDMEF_IMPACT_TYPE_FILE },
660                 { MSG_FI_CHAN, N_("File Modified"), IDMEF_IMPACT_TYPE_FILE },
661                 { MSG_FI_NODIR, N_("File found where directory was expected"), IDMEF_IMPACT_TYPE_FILE },
662 #endif
663 
664 #ifdef SH_USE_KERN
665                 { MSG_KERN_POLICY, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
666                 { MSG_KERN_POL_CO, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
667                 { MSG_KERN_PROC, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
668                 { MSG_KERN_GATE, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
669                 { MSG_KERN_IDT, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
670                 { MSG_KERN_SYSCALL, N_("Kernel Modified"), IDMEF_IMPACT_TYPE_OTHER },
671 #endif
672 
673 #ifdef SH_USE_PORTCHECK
674 		{ MSG_PORT_MISS, N_("Service closed"), IDMEF_IMPACT_TYPE_OTHER },
675 		{ MSG_PORT_NEW, N_("Service opened"), IDMEF_IMPACT_TYPE_OTHER },
676 		{ MSG_PORT_RESTART, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER },
677 		{ MSG_PORT_NEWPORT, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER },
678 #endif
679 
680 #ifdef SH_USE_SUIDCHK
681                 { MSG_SUID_POLICY, N_("SUID/SGID File Detected"), IDMEF_IMPACT_TYPE_FILE },
682 #endif
683 		/*
684 		 * This must be the last table entry
685 		 */
686 		{ 0, NULL,  IDMEF_IMPACT_TYPE_OTHER },
687         };
688 
689         for ( i = 0; tbl[i].name != NULL; i++ ) {
690                 if ( tbl[i].msgid != msgid )
691                         continue;
692 
693                 idmef_impact_set_type(impact, tbl[i].type);
694                 return prelude_string_cat(out, _(tbl[i].name));
695         }
696 
697         /* some other message
698          */
699         ptr = get_value(msg, _("msg"), NULL);
700         if ( ! ptr ) {
701                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
702                                 _("could not format Samhain message"), _("map_policy_to_class"));
703                 return -1;
704         }
705 
706 #if defined(SH_WITH_SERVER)
707         /* when using yule, theres a msg=<... msg=<...> >*/
708 	while ( (msg = get_value(ptr, _("msg"), NULL)) ) {
709 	        free(ptr);
710 		ptr = msg;
711 	}
712 #endif
713 
714         ret = prelude_string_cat(out, ptr);
715         free(ptr);
716 
717         return ret;
718 }
719 
720 
721 #ifdef SH_USE_PORTCHECK
get_service_info(char * msg,idmef_alert_t * alert)722 static int get_service_info(char *msg, idmef_alert_t *alert)
723 {
724         int ret;
725 	long port;
726 	char *ptr, *new, *tmp, *ip, *srv, *protocol, *end;
727         prelude_string_t *str;
728         idmef_address_t *address;
729         idmef_node_t *node;
730 	idmef_user_t *user;
731 	idmef_process_t *process;
732         idmef_service_t *service;
733         idmef_source_t *source = idmef_alert_get_next_source(alert, NULL);
734         struct passwd *pw;
735 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
736 	struct passwd pwd;
737 	char * buffer;
738 #endif
739 
740         new = sh_util_strdup(msg);
741 
742         ptr = strstr(new, _("port: "));
743         if ( ! ptr ) {
744                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
745                                 _("malformed Samhain port check message"), _("get_service_info"));
746 		SH_FREE( new );
747                 return -1;
748         }
749 
750         ptr += 6; /* skip 'port: ', position on first byte of interface */
751         tmp = strchr(ptr, ':');
752         if ( ! tmp ) {
753                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
754                                 _("malformed Samhain port check message (no port)"), _("get_service_info"));
755 		SH_FREE( new );
756                 return -1;
757         }
758 	*tmp = '\0';
759 
760 	/* Get interface
761 	 */
762 	ip = strdup(ptr);
763         if ( ip ) {
764                 if ( ! source ) {
765                         ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
766                         if ( ret < 0 ) {
767                                 free(ip);
768 				SH_FREE( new );
769                                 return ret;
770                         }
771                 }
772 
773                 ret = idmef_source_new_node(source, &node);
774                 if ( ret < 0 ) {
775                         free(ip);
776 			SH_FREE( new );
777                         return ret;
778                 }
779 
780                 ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
781                 if ( ret < 0 ) {
782                         free(ip);
783 			SH_FREE( new );
784                         return ret;
785                 }
786 
787                 ret = idmef_address_new_address(address, &str);
788                 if ( ret < 0 ) {
789                         free(ip);
790 			SH_FREE( new );
791                         return ret;
792                 }
793 
794                 prelude_string_set_nodup(str, ip);
795         }
796 
797 	ptr = tmp;
798 	++ptr;
799         tmp = strchr(ptr, '/');
800         if ( ! tmp ) {
801                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
802                                 _("malformed Samhain port check message (no protocol)"), _("get_service_info"));
803 		SH_FREE( new );
804                 return -1;
805         }
806 	*tmp = '\0';
807 
808 	/* Get port number
809 	 */
810 	port = strtol(ptr, &end, 0);
811         if ( *ptr && *end == '\0' && port >= 0 && port < 65536) {
812 
813                 if ( ! source ) {
814                         ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
815                         if ( ret < 0 ) {
816 				SH_FREE( new );
817                                 return ret;
818                         }
819                 }
820 
821                 ret = idmef_source_new_service(source, &service);
822                 if ( ret < 0 ) {
823 			SH_FREE( new );
824                         return ret;
825                 }
826 
827 		idmef_service_set_port(service, port);
828 
829                 ret = idmef_service_new_protocol(service, &str);
830                 if ( ret < 0 ) {
831 			SH_FREE( new );
832                         return ret;
833                 }
834 
835 		++tmp;
836 		if (*tmp) {
837 		        char * tmpw = tmp;
838 			char tmpw_store;
839 			while (*tmpw && !isblank((int) *tmpw)) ++tmpw;
840 			tmpw_store = *tmpw; *tmpw = '\0';
841 		        protocol = strdup(tmp);
842 			*tmpw = tmpw_store;
843 			prelude_string_set_nodup(str, protocol);
844 		}
845 
846 	}
847 
848 	ptr = tmp;
849 	++ptr;
850         ptr = strchr(ptr, '(');
851         if ( ! ptr ) {
852                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
853                                 _("malformed Samhain port check message (no service)"), _("get_service_info"));
854 		SH_FREE( new );
855                 return -1;
856         }
857 	++ptr;
858         tmp = strchr(ptr, ')');
859         if ( ! tmp ) {
860                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
861                                 _("malformed Samhain port check message (service not closed)"), _("get_service_info"));
862 		SH_FREE( new );
863                 return -1;
864         }
865 	*tmp = '\0';
866 
867 	/* Get service
868 	 */
869 	srv = strdup(ptr);
870         if ( srv ) {
871                 if ( ! source ) {
872                         ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
873                         if ( ret < 0 ) {
874                                 free(srv);
875 				SH_FREE( new );
876                                 return ret;
877                         }
878                 }
879 
880 		if ( ! service ) {
881                         ret = idmef_source_new_service(source, &service);
882 			if ( ret < 0 ) {
883                                 free(srv);
884 				SH_FREE( new );
885 				return ret;
886 			}
887                 }
888 
889                 ret = idmef_service_new_name(service, &str);
890                 if ( ret < 0 ) {
891                         free(srv);
892 			SH_FREE( new );
893                         return ret;
894                 }
895 
896                 prelude_string_set_nodup(str, srv);
897         }
898 
899 	SH_FREE( new );
900 
901         ptr = get_value(msg, _("userid"), NULL);
902 
903         if ( ptr ) {
904 
905 	        idmef_user_id_t * user_id;
906 
907 	        ret = idmef_source_new_user(source, &user);
908                 if ( ret < 0 ) {
909                         free(ptr);
910                         return ret;
911                 }
912 
913                 idmef_user_set_category(user, IDMEF_USER_CATEGORY_APPLICATION);
914 
915                 ret = idmef_user_new_user_id(user, &user_id, IDMEF_LIST_APPEND);
916                 if ( ret < 0 ) {
917                         free(ptr);
918                         return ret;
919                 }
920 
921                 idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_CURRENT_USER);
922 
923 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
924 		buffer = SH_ALLOC(SH_PWBUF_SIZE);
925 		sh_getpwnam_r(ptr, &pwd, buffer, SH_PWBUF_SIZE, &pw);
926 #else
927 		pw = sh_getpwnam(ptr);
928 #endif
929                 if ( pw )
930                         idmef_user_id_set_number(user_id, pw->pw_uid);
931 
932                 ret = idmef_user_id_new_name(user_id, &str);
933                 if ( ret < 0 ) {
934                         free(ptr);
935 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
936 			SH_FREE(buffer);
937 #endif
938                         return ret;
939                 }
940                 prelude_string_set_nodup(str, ptr);
941 
942 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
943 		SH_FREE(buffer);
944 #endif
945 	}
946 
947 
948         ptr = get_value(msg, _("path"), NULL);
949         tmp = get_value(msg, _("pid"), NULL);
950 
951         if ( ptr ) {
952 
953                 /*
954                  * In term of IDMEF, this is the full path,
955                  * including the name.
956                  */
957                 ret = idmef_source_new_process(source, &process);
958                 if ( ret < 0 ) {
959 		        free(ptr);
960                         return ret;
961 		}
962 
963 		ret = idmef_process_new_path(process, &str);
964                 if ( ret < 0 ) {
965 		        free(ptr);
966                         return ret;
967 		}
968                 prelude_string_set_nodup(str, ptr);
969 
970 
971                 if ( NULL != strrchr(ptr, '/') ) {
972                         ret = idmef_process_new_name(process, &str);
973                         if ( ret == 0 ) {
974 			        ptr = strrchr(ptr, '/');
975 			        prelude_string_set_dup(str, ptr + 1);
976 			}
977                 } else {
978 		        ret = idmef_process_new_name(process, &str);
979                         if ( ret == 0 ) {
980 			        prelude_string_set_dup(str, ptr);
981 			}
982 		}
983 
984 		idmef_process_set_pid(process, strtoul(tmp, NULL, 0));
985         }
986 
987 	if (tmp)
988 	  free(tmp);
989 
990 	return 0;
991 }
992 #endif
993 
get_login_info(char * msg,idmef_alert_t * alert)994 static int get_login_info(char *msg, idmef_alert_t *alert)
995 {
996         int ret;
997         char *ptr, *ip;
998         idmef_user_t *user;
999         idmef_node_t *node;
1000         struct passwd *pw;
1001 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
1002 	struct passwd pwd;
1003 	char * buffer;
1004 #endif
1005         prelude_string_t *str;
1006         idmef_user_id_t *user_id;
1007         idmef_address_t *address;
1008         idmef_target_t *target = idmef_alert_get_next_target(alert, NULL);
1009         idmef_source_t *source = idmef_alert_get_next_source(alert, NULL);
1010 
1011         ip = ptr = get_value(msg, _("ip"), NULL);
1012         if ( ptr ) {
1013                 if ( ! source ) {
1014                         ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
1015                         if ( ret < 0 ) {
1016                                 free(ptr);
1017                                 return ret;
1018                         }
1019                 }
1020 
1021                 ret = idmef_source_new_node(source, &node);
1022                 if ( ret < 0 ) {
1023                         free(ptr);
1024                         return ret;
1025                 }
1026 
1027                 ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
1028                 if ( ret < 0 ) {
1029                         free(ptr);
1030                         return ret;
1031                 }
1032 
1033                 ret = idmef_address_new_address(address, &str);
1034                 if ( ret < 0 ) {
1035                         free(ptr);
1036                         return ret;
1037                 }
1038 
1039                 prelude_string_set_nodup(str, ptr);
1040         }
1041 
1042         ptr = get_value(msg, _("host"), NULL);
1043         if ( ptr ) {
1044                 if ( ip && strcmp(ptr, ip) == 0 )
1045                         free(ptr);
1046                 else {
1047                         if ( ! source ) {
1048                                 ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
1049                                 if ( ret < 0 ) {
1050                                         free(ptr);
1051                                         return ret;
1052                                 }
1053                         }
1054 
1055                         ret = idmef_source_new_node(source, &node);
1056                         if ( ret < 0 ) {
1057                                 free(ptr);
1058                                 return ret;
1059                         }
1060 
1061                         ret = idmef_node_new_name(node, &str);
1062                         if ( ret < 0 ) {
1063                                 free(ptr);
1064                                 return ret;
1065                         }
1066 
1067                         prelude_string_set_nodup(str, ptr);
1068                 }
1069         }
1070 
1071         ptr = get_value(msg, _("name"), NULL);
1072         if ( ptr ) {
1073                 ret = idmef_target_new_user(target, &user);
1074                 if ( ret < 0 ) {
1075                         free(ptr);
1076                         return ret;
1077                 }
1078 
1079                 idmef_user_set_category(user, IDMEF_USER_CATEGORY_OS_DEVICE);
1080 
1081                 ret = idmef_user_new_user_id(user, &user_id, IDMEF_LIST_APPEND);
1082                 if ( ret < 0 ) {
1083                         free(ptr);
1084                         return ret;
1085                 }
1086 
1087                 idmef_user_id_set_type(user_id, IDMEF_USER_ID_TYPE_TARGET_USER);
1088 
1089 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
1090 		buffer = SH_ALLOC(SH_PWBUF_SIZE);
1091 		sh_getpwnam_r(ptr, &pwd, buffer, SH_PWBUF_SIZE, &pw);
1092 #else
1093 		pw = sh_getpwnam(ptr);
1094 #endif
1095                 if ( pw )
1096                         idmef_user_id_set_number(user_id, pw->pw_uid);
1097 
1098                 ret = idmef_user_id_new_name(user_id, &str);
1099                 if ( ret < 0 ) {
1100                         free(ptr);
1101 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
1102 			SH_FREE(buffer);
1103 #endif
1104                         return ret;
1105                 }
1106                 prelude_string_set_nodup(str, ptr);
1107 
1108                 ptr = get_value(msg, _("tty"), NULL);
1109                 if ( ptr ) {
1110                         ret = idmef_user_id_new_tty(user_id, &str);
1111                         if ( ret < 0 ) {
1112                                 free(ptr);
1113 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
1114 				SH_FREE(buffer);
1115 #endif
1116                                 return ret;
1117                         }
1118 
1119                         prelude_string_set_nodup(str, ptr);
1120                 }
1121 #if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
1122 		SH_FREE(buffer);
1123 #endif
1124         }
1125 
1126         ptr = get_time_value(msg, _("time"), NULL);
1127         if ( ptr ) {
1128                 idmef_time_t *time;
1129 
1130                 ret = idmef_time_from_samhain(&time, ptr);
1131                 free(ptr);
1132 
1133                 if ( ret < 0 )
1134                         return ret;
1135 
1136                 idmef_alert_set_detect_time(alert, time);
1137         }
1138 
1139         return 0;
1140 }
1141 
1142 #if defined(SH_WITH_SERVER)
node_set_address(idmef_node_t * node,const char * addr)1143 static int node_set_address(idmef_node_t *node, const char *addr)
1144 {
1145         int ret;
1146 	prelude_string_t *prelude_str;
1147 	idmef_address_t *idmef_addr;
1148 
1149 	ret = prelude_string_new(&prelude_str);
1150 	if ( ret < 0 )
1151                 goto err;
1152 
1153 	ret = prelude_string_set_ref(prelude_str, addr);
1154 	if ( ret < 0 )
1155                 goto err;
1156 
1157 	ret = idmef_address_new(&idmef_addr);
1158 	if ( ret < 0 )
1159                 goto err;
1160 
1161 	idmef_address_set_category(idmef_addr, IDMEF_ADDRESS_CATEGORY_IPV4_ADDR);
1162 	idmef_address_set_address(idmef_addr, prelude_str);
1163 	idmef_node_set_address(node, idmef_addr, 0);
1164 
1165 	return 0;
1166  err:
1167         return -1;
1168 }
1169 #endif
1170 
1171 
samhain_alert_prelude(int priority,int sh_class,char * message,unsigned long msgid,char * inet_peer_ip)1172 static int samhain_alert_prelude(int priority, int sh_class,
1173 				 char *message, unsigned long msgid,
1174 				 char * inet_peer_ip)
1175 {
1176         int ret;
1177         idmef_time_t *time;
1178         idmef_alert_t *alert;
1179         idmef_message_t *idmef;
1180         idmef_classification_t *classification;
1181         idmef_assessment_t *assessment;
1182         idmef_additional_data_t *data;
1183         idmef_impact_t *impact;
1184         idmef_target_t *target;
1185         idmef_confidence_t *confidence;
1186         prelude_string_t *str;
1187 #if defined(SH_WITH_SERVER)
1188         idmef_node_t *node;
1189 #else
1190 	(void) inet_peer_ip;
1191 #endif
1192 
1193         if ( !client || sh_class == STAMP)
1194                 return 0;
1195 
1196         ret = idmef_message_new(&idmef);
1197         if ( ret < 0 )
1198                 goto err;
1199 
1200         ret = idmef_message_new_alert(idmef, &alert);
1201         if ( ret < 0 )
1202                 goto err;
1203 
1204         idmef_alert_set_analyzer(alert, idmef_analyzer_ref(prelude_client_get_analyzer(client)), IDMEF_LIST_PREPEND);
1205 
1206         ret = idmef_time_new_from_gettimeofday(&time);
1207         if ( ret < 0 )
1208                 goto err;
1209         idmef_alert_set_detect_time(alert, time);
1210 
1211         ret = idmef_time_new_from_gettimeofday(&time);
1212         if ( ret < 0 )
1213                 goto err;
1214         idmef_alert_set_create_time(alert, time);
1215 
1216         ret = idmef_alert_new_classification(alert, &classification);
1217         if ( ret < 0 )
1218                 goto err;
1219 
1220         ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND);
1221         if ( ret < 0 )
1222                 goto err;
1223 
1224         idmef_target_set_decoy(target, IDMEF_TARGET_DECOY_NO);
1225 
1226 #if defined(SH_WITH_SERVER)
1227         if ( inet_peer_ip != NULL){
1228                 ret = idmef_target_new_node(target, &node);
1229 		if ( ret < 0 )
1230                           goto err;
1231 
1232 		ret = node_set_address(node, inet_peer_ip);
1233 		if ( ret < 0 )
1234                           goto err;
1235 
1236 		idmef_target_set_node(target, idmef_node_ref(node));
1237         }
1238         else
1239 #endif
1240         if ( idmef_analyzer_get_node(prelude_client_get_analyzer(client)) ) {
1241                 idmef_node_ref(idmef_analyzer_get_node(prelude_client_get_analyzer(client)));
1242                 idmef_target_set_node(target, idmef_analyzer_get_node(prelude_client_get_analyzer(client)));
1243         }
1244 
1245         if ( strstr(message, _("path=")) ) {
1246 #if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
1247                 if ( msgid != MSG_FI_ADD && msgid != MSG_FI_ADD2 )
1248                         get_file_infos(target, message, IDMEF_FILE_CATEGORY_ORIGINAL);
1249 #endif
1250 
1251                 get_file_infos(target, message, IDMEF_FILE_CATEGORY_CURRENT);
1252         }
1253 
1254         ret = idmef_alert_new_assessment(alert, &assessment);
1255         if ( ret < 0 )
1256                 goto err;
1257 
1258         ret = idmef_assessment_new_impact(assessment, &impact);
1259         if ( ret < 0 )
1260                 goto err;
1261 
1262         ret = idmef_classification_new_text(classification, &str);
1263         if ( ret < 0 )
1264                 goto err;
1265 
1266         ret = get_login_info(message, alert);
1267         if ( ret < 0 )
1268                 goto err;
1269 
1270 #ifdef SH_USE_PORTCHECK
1271 	if (msgid == MSG_PORT_MISS || msgid == MSG_PORT_NEW || msgid == MSG_PORT_RESTART || msgid == MSG_PORT_NEWPORT) {
1272 	        ret = get_service_info(message, alert);
1273 		if ( ret < 0 )
1274 		        goto err;
1275         }
1276 #endif
1277 
1278         map_policy_to_class(message, msgid, impact, str);
1279 
1280 #if 0
1281         if ( priority == SH_ERR_SEVERE || priority == SH_ERR_FATAL )
1282                 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_HIGH);
1283 
1284         else if ( priority == SH_ERR_ALL || priority == SH_ERR_INFO || priority == SH_ERR_NOTICE )
1285                 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_LOW);
1286 
1287         else
1288                 idmef_impact_set_severity(impact, IDMEF_IMPACT_SEVERITY_MEDIUM);
1289 #endif
1290 	idmef_impact_set_severity(impact, map_severity(priority));
1291 
1292         idmef_impact_set_completion(impact, IDMEF_IMPACT_COMPLETION_SUCCEEDED);
1293 
1294         ret = idmef_assessment_new_confidence(assessment, &confidence);
1295         if ( ret < 0 )
1296                 goto err;
1297 
1298         idmef_confidence_set_rating(confidence, IDMEF_CONFIDENCE_RATING_HIGH);
1299 
1300         ret = idmef_alert_new_additional_data(alert, &data, IDMEF_LIST_APPEND);
1301         if ( ret < 0 )
1302                 goto err;
1303 
1304         ret = idmef_additional_data_new_meaning(data, &str);
1305         if ( ret < 0 )
1306                 goto err;
1307 
1308         prelude_string_set_dup(str, _("Message generated by Samhain"));
1309         idmef_additional_data_set_type(data, IDMEF_ADDITIONAL_DATA_TYPE_STRING);
1310         idmef_additional_data_set_string_ref(data, message);
1311 
1312         /* debug_print_message(idmef); */
1313 
1314         prelude_client_send_idmef(client, idmef);
1315         idmef_message_destroy(idmef);
1316 
1317         return 0;
1318 
1319  err:
1320         idmef_message_destroy(idmef);
1321         return -1;
1322 }
1323 
1324 
sh_prelude_alert(int priority,int sh_class,char * message,long msgflags,unsigned long msgid,char * inet_peer_ip)1325 int sh_prelude_alert(int priority, int sh_class, char *message, long msgflags, unsigned long msgid, char *inet_peer_ip)
1326 {
1327         int ret;
1328 
1329 	(void) msgflags; /* fix compiler warning */
1330 
1331         if ( initialized < 1 )
1332                 return -1;
1333 
1334         ret = samhain_alert_prelude(priority, sh_class, message, msgid, inet_peer_ip);
1335         if ( ret < 0 ) {
1336                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1337                                 _("Problem with IDMEF for prelude-ids support: alert lost"),
1338                                 _("sh_prelude_alert"));
1339         }
1340 
1341         return ret;
1342 }
1343 
1344 
1345 
sh_prelude_set_profile(const char * arg)1346 int sh_prelude_set_profile(const char *arg)
1347 {
1348         if ( profile ) {
1349                 free(profile);
1350                 profile = NULL;
1351 	}
1352 
1353         if ( arg ) {
1354                 profile = strdup(arg);
1355                 if ( ! profile )
1356                         return -1;
1357         }
1358 
1359         return 0;
1360 }
1361 
1362 /* Allow initialization of prelude; to be called
1363  * after forking the daemon. Delays heartbeat
1364  * start after config read until it is safe.
1365  */
sh_prelude_reset(void)1366 void sh_prelude_reset(void)
1367 {
1368         extern void sh_error_init_prelude();
1369 
1370         ready_for_init = 1;
1371 	sh_error_init_prelude();
1372         return;
1373 }
1374 
1375 
1376 
sh_prelude_stop(void)1377 void sh_prelude_stop(void)
1378 {
1379         if (initialized < 1)
1380                 return;
1381 
1382 	if (sh.flag.isdaemon == S_TRUE)
1383 	        prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_FAILURE);
1384 	else
1385 	        prelude_client_destroy(client, PRELUDE_CLIENT_EXIT_STATUS_SUCCESS);
1386 
1387 	client = NULL;
1388 
1389 	prelude_deinit();
1390 
1391         initialized = 0;
1392         return;
1393 }
1394 
1395 
1396 
sh_prelude_init(void)1397 int sh_prelude_init(void)
1398 {
1399         int ret;
1400         prelude_string_t *str;
1401         idmef_analyzer_t *analyzer;
1402         prelude_client_flags_t flags;
1403 #ifdef SH_NOFAILOVER
1404 	prelude_connection_pool_t *pool;
1405 	prelude_connection_pool_flags_t conn_flags;
1406 #endif
1407 
1408 	if (ready_for_init == 0)
1409 	  return initialized;
1410 
1411 	if (initialized > 0)
1412 	  return initialized;
1413 
1414 	prelude_thread_init(NULL);
1415         prelude_init(&sh_argc_store, sh_argv_store);
1416 
1417         ret = prelude_client_new(&client, profile ? profile : _("samhain"));
1418         if ( ret < 0 ) {
1419                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1420                                 _("Failed to initialize Prelude"), _("sh_prelude_init"));
1421 		initialized = -1;
1422                 return -1;
1423         }
1424 
1425         /*
1426          * Enable automatic heartbeat sending.
1427          */
1428         flags = prelude_client_get_flags(client);
1429         ret = prelude_client_set_flags(client, flags | PRELUDE_CLIENT_FLAGS_ASYNC_TIMER);
1430 
1431         analyzer = prelude_client_get_analyzer(client);
1432 
1433         ret = idmef_analyzer_new_model(analyzer, &str);
1434         prelude_string_set_dup(str, IDMEF_ANALYZER_MODEL);
1435 
1436         ret = idmef_analyzer_new_class(analyzer, &str);
1437         prelude_string_set_dup(str, IDMEF_ANALYZER_CLASS);
1438 
1439 	ret = idmef_analyzer_new_version(analyzer, &str);
1440         prelude_string_set_dup(str, IDMEF_ANALYZER_VERSION);
1441 
1442 #ifdef SH_NOFAILOVER
1443 	pool = prelude_client_get_connection_pool(client);
1444 	conn_flags = prelude_connection_pool_get_flags(pool);
1445 
1446 	conn_flags &= ~PRELUDE_CONNECTION_POOL_FLAGS_FAILOVER;
1447 	prelude_connection_pool_set_flags(pool, conn_flags);
1448 #endif
1449 
1450         ret = prelude_client_start(client);
1451         if ( ret < 0 ) {
1452                 prelude_perror(ret, _("error starting prelude client"));
1453 
1454                 if ( prelude_client_is_setup_needed(ret) )
1455                         prelude_client_print_setup_error(client);
1456 
1457                 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1458                                 _("Failed to start Prelude"), _("sh_prelude_init"));
1459 		initialized = -1;
1460                 return -1;
1461         }
1462 
1463 	initialized = 1;
1464         return 1;
1465 }
1466 
1467 /* HAVE_LIBPRELUDE_9 */
1468 #endif
1469 
1470