source: trunk/src/sh_prelude_old.c@ 162

Last change on this file since 162 was 134, checked in by rainer, 17 years ago

More thread-safety changes.

File size: 20.9 KB
Line 
1/*
2 *
3 * Copyright (C) 2004, 2005 Rainer Wichmann, Patrice Bourgin,
4 * Yoann Vandoorselaere
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 *
24 * 03/12/2004 : R.W.:
25 * fix more memory leaks in get_file_infos()
26 * workaround (re-init) for file descriptor closing problem with GPG
27 *
28 * R.W.: fix missing treatment of alternative XML-style messages
29 * fix get_value (if terminating '>' or '"' is not found, may
30 * overwrite the NULL terminator of the string ...)
31 * fix memory leaks in get_file_infos(), retrieve_time()
32 *
33 * 13/03/2004 : This file is modified by Patrice Bourgin
34 * <pbourgin@xpconseil.com>
35 *
36 * R.W.: Some problems with the patch by Patrice Bourgin fixed
37 * (e.g. memory leak)
38 *
39 * Modifications (13/03/2004) by Patrice bourgin (pbourgin@xpconseil.com) :
40 * Comment : thanks for memory leak fix :p
41 * 1 : remove translation of HTML tag
42 * 2 : send detailled information about files to prelude (with two
43 * functions : get_value and get_file_infos)
44 * these two functions were written by Yoann, but for future
45 * version of prelude, I adapt them to work
46 * with version 0.8.10 of libprelude
47 * 3 : send a heartbeat just after initialization, to alert prelude that
48 * samhain is started
49 * 4 : these modifications was tested successfully, and all informations are
50 * correctly transmitted to prelude and displayed with piwi
51 *
52 * Modifications (7/03/2004) by Patrice bourgin (pbourgin@xpconseil.com) :
53 * 1 : translation of HTML tag <> to tag () in alert to permit
54 * displaying alerts on piwi
55 * 2 : add the address in the source and in the target for displaying on piwi
56 * 3 : add information about the classification, because there was only
57 * one classification and it was not enough
58 * 4 : add impact field to classify alert in prelude, becuse impact is
59 * needed to treat information
60 * 5 : correct some errors with transmission to prelude with libprelude
61 */
62
63#include "config_xor.h"
64
65#include <stdio.h>
66#include <string.h>
67#include <sys/types.h>
68
69#if TIME_WITH_SYS_TIME
70#include <sys/time.h>
71#include <time.h>
72#else
73#if HAVE_SYS_TIME_H
74#include <sys/time.h>
75#else
76#include <time.h>
77#endif
78#endif
79#include <unistd.h>
80#include <syslog.h>
81
82#if defined(HAVE_LIBPRELUDE) && !defined(HAVE_LIBPRELUDE_9)
83
84/*
85 * _() macros are samhain specific; they are used to replace string
86 * constants at runtime. This is part of the samhain stealth mode
87 * (fill string constants with encoded strings, decode at runtime).
88 */
89#define FIL__ _("sh_prelude.c")
90
91#if defined(__GNUC__)
92extern char *strptime (const char * s,
93 const char * fmt, struct tm * tp);
94#endif
95
96#include <netdb.h>
97#include <netinet/in.h>
98#include <arpa/inet.h>
99#include <sys/utsname.h>
100#ifdef HAVE_LIBGEN_H
101#include <libgen.h>
102#endif
103
104#include <libprelude/list.h>
105#include <libprelude/idmef-tree.h>
106#include <libprelude/idmef-tree-func.h>
107#include <libprelude/prelude-io.h>
108#include <libprelude/prelude-message.h>
109#include <libprelude/prelude-message-buffered.h>
110#include <libprelude/idmef-msg-send.h>
111#include <libprelude/idmef-message-id.h>
112#include <libprelude/prelude-message-id.h>
113#include <libprelude/sensor.h>
114
115#ifndef HAVE_BASENAME
116#define basename(a) ((NULL == strrchr(a, '/')) ? (a) : (strrchr(a, '/')))
117#endif
118
119/*
120 * includes for samhain-specific functions (sl_strstr, sh_error_handle)
121 */
122#include "slib.h"
123#include "sh_mem.h"
124#include "sh_cat.h"
125#include "sh_error_min.h"
126#include "sh_prelude.h"
127#define SH_NEED_GETHOSTBYXXX
128#include "sh_static.h"
129#include "sh_pthread.h"
130
131static char programname[64];
132static idmef_heartbeat_t heartbeat;
133static prelude_msgbuf_t * hb_msgbuf = NULL;
134static struct utsname * uname_data = NULL;
135
136static char hostname[256];
137
138static char model[64];
139static char class[64];
140static char version[8];
141static char manufacturer[64];
142
143static char name[16];
144static char url[32];
145
146static char meaning[64];
147static char description[128];
148
149static char * path_basename = NULL;
150static char * path_fullname = NULL;
151
152/* safe string duplication function
153 */
154static char * xstrdup (const char * str)
155{
156 size_t len;
157 char * ret;
158
159 if (!str)
160 return NULL;
161 len = sl_strlen(str);
162 ret = SH_ALLOC(len+1);
163 sl_strlcpy (ret, str, len+1);
164 return (ret);
165}
166
167/* Get the value for a key. The key is built from toktmp + toksuffix.
168 * msg is modified temporarily, so it should not be declared 'const'.
169 */
170static char *get_value (char *msg, const char *toktmp,
171 const char *toksuffix)
172{
173 char * ret = NULL, *ptr, tok[128];
174
175 snprintf(tok, sizeof(tok), "%s%s", toktmp, (toksuffix) ? toksuffix : "");
176
177 ptr = strstr(msg, tok);
178 if ( ! ptr )
179 return NULL;
180
181#ifdef SH_USE_XML
182 while (*ptr && *ptr != '"') ptr++;
183 if (*ptr) {
184 ret = ptr + 1; ptr = ret;
185 }
186 while (*ptr && *ptr != '"') ptr++;
187 if (*ptr)
188 {
189 *ptr = '\0';
190 if (ret) ret = xstrdup(ret);
191 *ptr = '"';
192 }
193 else
194 {
195 if (ret) ret = xstrdup(ret);
196 }
197#else
198 while (*ptr && *ptr != '<') ptr++;
199 if (*ptr) ret = ptr + 1;
200 while (*ptr && *ptr != '>') ptr++;
201 if (*ptr)
202 {
203 *ptr = '\0';
204 if (ret) ret = xstrdup(ret);
205 *ptr = '>';
206 }
207 else
208 {
209 if (ret) ret = xstrdup(ret);
210 }
211#endif
212
213 return ret;
214}
215
216int sh_prelude_init ()
217{
218 int ret = -1;
219
220 if (uname_data != NULL) {
221 SH_FREE(uname_data);
222 uname_data = NULL;
223 }
224 uname_data = SH_ALLOC(sizeof(struct utsname)); /* only once */
225 if (!uname_data) {
226 return -1;
227 }
228 ret = uname(uname_data);
229 if (ret < 0) {
230 uname_data = NULL;
231 return -1;
232 }
233
234 /* ------- LibPrelude Init -------
235 */
236 strncpy(programname, _("Samhain"), 64);
237 programname[63] = '\0';
238
239 if ( prelude_sensor_init(programname, NULL, 0, NULL) < 0)
240 {
241 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
242 _("Failed to initialize Prelude"),
243 _("sh_prelude_init"));
244 return -1;
245 }
246
247 strncpy(model, _("Samhain"), 64);
248 model[63] = '\0';
249 strncpy(class, _("Samhain Host Intrusion Detection System"), 64);
250 class[63] = '\0';
251 strncpy(version, VERSION, 8);
252 version[7] = '\0';
253 strncpy(manufacturer, _("Samhain by Rainer Wichmann"), 64);
254 manufacturer[63] = '\0';
255
256 /*
257 if (sh.host.name[0] != '\0') {
258 strncpy(hostname, sh.host.name, 256); hostname[255] = '\0';
259 } else {
260 gethostname (hostname, 256); hostname[255] = '\0';
261 }
262 */
263
264 /* According to the manpage, if gethostname returns a truncated hostname,
265 * it may or may not be NULL terminated. So we terminate explicitely.
266 */
267 gethostname (hostname, 256); hostname[255] = '\0';
268
269 strncpy (name, _("Samhain HIDS"), 16);
270 name[15] = '\0';
271 strncpy (url, _("http://www.la-samhna.de/samhain/"), 32);
272 url[31] = '\0';
273
274 strncpy (meaning, _("Message generated by Samhain"), 64);
275 meaning[63] = '\0';
276
277 /* analyzer information */
278 idmef_string_set (&heartbeat.analyzer.model, model);
279 idmef_string_set (&heartbeat.analyzer.class, class);
280 idmef_string_set (&heartbeat.analyzer.version, version);
281
282 /* analyzer address */
283 idmef_analyzer_node_new(&heartbeat.analyzer);
284 idmef_string_set (&heartbeat.analyzer.node->name, hostname);
285
286 /* analyzer type */
287 idmef_string_set(&heartbeat.analyzer.ostype, uname_data->sysname);
288 idmef_string_set(&heartbeat.analyzer.osversion, uname_data->release);
289
290
291 INIT_LIST_HEAD(&heartbeat.additional_data_list);
292
293 if (hb_msgbuf != NULL)
294 {
295 prelude_msgbuf_close (hb_msgbuf);
296 hb_msgbuf = NULL;
297 }
298 hb_msgbuf = prelude_msgbuf_new(0);
299 if (!hb_msgbuf) {
300 return -1;
301 }
302
303 /* prelude_heartbeat_register_cb(&SendHeartbeat, NULL); */
304 return 1;
305}
306
307/* Retrieve the content of "msg=" for adding informations on
308 * impact tag with prelude
309 */
310char *RetrieveImpact(const char *msg)
311{
312 char *tmp1;
313 char *tmp2;
314 char *tmp0;
315 char *ret = NULL;
316
317 tmp2 = xstrdup(msg);
318 /*
319 * don't use strtok - strtok (str, delim) is 'one of the chars
320 * in delim', not the full 'delim' string
321 */
322 if (tmp2)
323 tmp1 = sl_strstr (tmp2, _("msg="));
324 else
325 return NULL;
326
327 if (tmp1)
328 {
329 tmp1 += 5;
330#ifdef SH_USE_XML
331 tmp0 = strchr(tmp1, '"');
332#else
333 tmp0 = strchr(tmp1, '>');
334#endif
335 if (tmp0)
336 *tmp0 = '\0';
337 ret = xstrdup(tmp1);
338 }
339 SH_FREE(tmp2); /* fix memory leak */
340
341 return ret;
342}
343
344/* Transform the string time from the event into time
345 */
346time_t retrieve_time(char *stime)
347{
348#ifdef HAVE_STRPTIME
349 struct tm tmptime;
350 time_t rettime = -1;
351 char *tmp0, *tmp1, *tmp2;
352
353 /* fix more memory leaks
354 */
355 if ( stime )
356 {
357 tmp0 = xstrdup(stime);
358 tmp1 = tmp0;
359 tmp2 = tmp1 + 1;
360
361 while (*tmp1 && *tmp1 != ']') tmp1++;
362 if (*tmp1)
363 {
364 *tmp1 = '\0';
365 tmp2 = xstrdup(tmp2);
366 SH_FREE (tmp0);
367 }
368 else
369 {
370 tmp2 = xstrdup(tmp2);
371 SH_FREE (tmp0);
372 }
373
374 memset (&tmptime, '\0', sizeof(struct tm));
375 strptime(tmp2,"%Y-%m-%dT%H:%M:%S", &tmptime);
376 rettime = mktime(&tmptime);
377
378 SH_FREE(tmp2);
379
380 if ( rettime != -1 )
381 return rettime;
382 else
383 return 0;
384 }
385#endif
386 return 0;
387}
388
389/* msg is modified temporarily in get_value(),
390 * so it should not be declared 'const'.
391 */
392void get_file_infos(idmef_target_t *target, char *msg,
393 idmef_file_category_t category)
394{
395 char *ptr;
396 idmef_file_t *file;
397 idmef_time_t *temps;
398 idmef_inode_t *inode;
399 const char *suffix = (category == current) ? "_new" : "_old";
400
401 file = idmef_target_file_new(target);
402 if ( ! file )
403 return;
404
405 file->category = category;
406 /*
407 * Fix memory leak - the pointer to get_value(msg, "path", NULL) is lost
408 * libprelude does not strdup, only sets a pointer, so need a global pointer
409 * to keep track of this :(
410 */
411 if (category == original)
412 path_fullname = get_value(msg, "path", NULL);
413 idmef_string_set (&file->path, path_fullname);
414
415 if (category == original)
416 path_basename = get_value(msg, "path", NULL);
417 if (path_basename) {
418 idmef_string_set (&file->name, basename(path_basename));
419 }
420
421 ptr = get_value(msg, "size", suffix);
422 if ( ptr ) {
423 file->data_size = strtoul(ptr, NULL, 10);
424 SH_FREE(ptr);
425 }
426
427 ptr = get_value(msg, "mtime", suffix);
428 if ( ptr ) {
429 temps = idmef_file_modify_time_new(file);
430 temps->sec = retrieve_time(ptr);
431 SH_FREE(ptr);
432 }
433
434 ptr = get_value(msg, "ctime", suffix);
435 if ( ptr ) {
436 temps = idmef_file_create_time_new(file);
437 temps->sec = retrieve_time(ptr);
438 SH_FREE(ptr);
439 }
440
441 ptr = get_value(msg, "atime", suffix);
442 if ( ptr ) {
443 temps = idmef_file_access_time_new(file);
444 temps->sec = retrieve_time(ptr);
445 SH_FREE(ptr);
446 }
447
448 ptr = get_value(msg, "inode", suffix);
449 if ( ptr ) {
450 inode = idmef_file_inode_new(file);
451 inode->number = strtoul(ptr, NULL, 10);
452 SH_FREE(ptr);
453 }
454}
455
456void sh_prelude_reset()
457{
458 (void) sh_prelude_alert (0, 0, NULL, 0, 0);
459 return;
460}
461
462int sh_prelude_alert (int priority, int sh_class, char * message,
463 long msgflags, unsigned long msgid)
464{
465 static int initialized = 0;
466 struct timeval tv;
467
468 idmef_alert_t * alert;
469 idmef_message_t * idmef;
470 prelude_msgbuf_t * msgbuf;
471 idmef_classification_t * classification;
472 idmef_target_t * target;
473 idmef_address_t * taddr;
474 idmef_source_t * source;
475 idmef_assessment_t * assessment;
476 idmef_additional_data_t * data;
477 /* To store impact */
478 char * impactmsg = NULL;
479 struct hostent * myhost;
480 char * src_ip = NULL;
481
482 static int some_error = 0;
483
484 (void) msgflags;
485 (void) msgid;
486
487 /* Workaround for the file closing bug
488 */
489 if (message == NULL && priority == 0 && sh_class == 0)
490 {
491 initialized = 0;
492 return 0;
493 }
494
495 if (initialized == 0)
496 {
497 /* initialize
498 */
499 initialized = sh_prelude_init();
500
501 /* send a heartbeat after initialization to say to prelude "I'm alive" */
502
503 gettimeofday(&tv, NULL);
504 heartbeat.create_time.sec = tv.tv_sec;
505 heartbeat.create_time.usec = tv.tv_usec;
506
507 /*
508 * we could use additional data to send stats.
509 */
510 prelude_msgbuf_set_header(hb_msgbuf, PRELUDE_MSG_IDMEF, 0);
511 idmef_send_heartbeat(hb_msgbuf, &heartbeat);
512 prelude_msgbuf_mark_end(hb_msgbuf);
513 }
514 if (initialized == -1)
515 {
516 /* init failed
517 */
518 if (some_error == 0)
519 {
520 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
521 _("Problem with prelude-ids support: init failed"),
522 _("sh_prelude_alert"));
523 }
524 some_error = 1;
525 return -1;
526 }
527
528 if (sh_class == STAMP)
529 {
530 gettimeofday(&tv, NULL);
531 heartbeat.create_time.sec = tv.tv_sec;
532 heartbeat.create_time.usec = tv.tv_usec;
533
534 /*
535 * we could use additional data to send stats.
536 */
537 prelude_msgbuf_set_header(hb_msgbuf, PRELUDE_MSG_IDMEF, 0);
538 idmef_send_heartbeat(hb_msgbuf, &heartbeat);
539 prelude_msgbuf_mark_end(hb_msgbuf);
540 return 0;
541 }
542
543 /* This function serves to initialize a message structure.
544 * The returned idmef_message_t structure is a static variable
545 * declared in idmef_message_new().
546 */
547 idmef = idmef_message_new();
548 if ( ! idmef )
549 goto err;
550
551 /* 'alert' is a static variable that gets initialized and
552 * associated with the idmef_message_t idmef_alert_t member.
553 * -> no new memory allocated; not signal-safe or thread-safe.
554 */
555 idmef_alert_new(idmef);
556 alert = idmef->message.alert;
557
558 /* Set the 'detect time'. idmef_alert_new() will already set the
559 * 'create time', whatever the difference is supposed to be.
560 */
561 gettimeofday(&tv, NULL);
562 idmef_alert_detect_time_new(alert);
563 alert->detect_time->sec = tv.tv_sec;
564 alert->detect_time->usec = tv.tv_usec;
565
566 /* ------- Analyzer. -------
567 *
568 * This apparently is supposed to provide some information
569 * about the sensor to the server (what sensor process ? where ?).
570 *
571 * idmef_string_set (x, y) is a macro that will make x
572 * a pointer to y. Therefore the caller must guarantee that y will
573 * never be overwritten until the alert is sent.
574 * With the samhain _() macros, this means we must copy to another
575 * storage region.
576 *
577 * N.B.: with constant strings, you can use idmef_string_set_constant()
578 * instead.
579 */
580 idmef_string_set (&alert->analyzer.model, model);
581 idmef_string_set (&alert->analyzer.class, class);
582 idmef_string_set (&alert->analyzer.version, version);
583 idmef_string_set (&alert->analyzer.manufacturer, manufacturer);
584
585 /* Here we add some information on the host OS.
586 */
587 idmef_string_set (&alert->analyzer.ostype, uname_data->sysname);
588 idmef_string_set (&alert->analyzer.osversion, uname_data->release);
589
590 /* ------- Analyzer / Process -------
591 *
592 * Fill in minimal info about the process. Apparently one could also
593 * supply things like path, argv, env (?).
594 */
595 idmef_analyzer_process_new (&alert->analyzer);
596 alert->analyzer.process->pid = getpid();
597
598 /* ------- Analyzer / Node -------
599 *
600 * Provide the name of this node, i.e. host.
601 */
602 idmef_analyzer_node_new (&alert->analyzer);
603 idmef_string_set (&alert->analyzer.node->name, hostname);
604
605
606
607 /* ------- Classification -------
608 *
609 * Apparently 'classification' provides details about the sensor
610 * program.
611 *
612 * For reasons unbeknown to me (did not care to investigate),
613 * this function does allocate memory, instead of using a static variable.
614 *
615 */
616 classification = idmef_alert_classification_new(alert);
617 if ( ! classification )
618 goto err;
619
620
621 impactmsg = RetrieveImpact(message);
622 if (impactmsg)
623 idmef_string_set (&classification->name, impactmsg);
624 idmef_string_set (&classification->url, url);
625
626 classification->origin = vendor_specific;
627
628 /* Get information about ip address */
629
630 SH_MUTEX_LOCK(mutex_resolv);
631 myhost = sh_gethostbyname(hostname);
632 src_ip = xstrdup(inet_ntoa(*((struct in_addr *)myhost->h_addr_list[0])));
633 SH_MUTEX_UNLOCK(mutex_resolv);
634
635
636 /* ------- Target -------
637 *
638 * Purpose ? To provide informations about destination of alert
639 *
640 * Allocates memory.
641 *
642 */
643 target = idmef_alert_target_new(alert);
644 if ( ! target )
645 goto err;
646 idmef_target_node_new(target);
647 idmef_string_set(&target->node->name, hostname);
648
649 if ( strstr(message, "path=") ) {
650 get_file_infos(target, message, original);
651 get_file_infos(target, message, current);
652 }
653
654 if (src_ip)
655 {
656 taddr = idmef_node_address_new(target->node);
657 if (!taddr)
658 goto err;
659
660 taddr->category = ipv4_addr;
661 idmef_string_set(&taddr->address, src_ip);
662 }
663
664 /* ------- Source -------
665 *
666 * Purpose ? To provide informations about source of alert
667 *
668 * Allocates memory.
669 *
670 */
671 source = idmef_alert_source_new(alert);
672 if ( ! source )
673 goto err;
674
675 /* ------- Impact -------
676 */
677 idmef_alert_assessment_new(alert);
678 assessment = alert->assessment;
679 idmef_assessment_impact_new(assessment);
680
681 if ((priority == SH_ERR_SEVERE) || (priority == SH_ERR_FATAL))
682 {
683 assessment->impact->severity = impact_high;
684 }
685 else if ((priority == SH_ERR_ALL) || (priority == SH_ERR_INFO) ||
686 (priority == SH_ERR_NOTICE))
687 {
688 assessment->impact->severity = impact_low;
689 }
690 else
691 {
692 assessment->impact->severity = impact_medium;
693 }
694
695 if (NULL != sl_strstr(message, _("POLICY")))
696 {
697 if (NULL != sl_strstr(message, _("POLICY KERNEL")))
698 {
699 assessment->impact->severity = impact_high;
700 assessment->impact->completion = succeeded;
701 assessment->impact->type = other;
702 strncpy(description,
703 _("Kernel modification detected by Samhain."),
704 128);
705 description[127] = '\0';
706 }
707 else
708 {
709 assessment->impact->severity = impact_high;
710 assessment->impact->completion = succeeded;
711 assessment->impact->type = file;
712 strncpy(description,
713 _("File system modification detected by Samhain."),
714 128);
715 description[127] = '\0';
716 }
717 }
718 else
719 {
720 if ( ((NULL != sl_strstr(message, _("Login"))) ||
721 (NULL != sl_strstr(message, _("Multiple login"))) ||
722 (NULL != sl_strstr(message, _("Logout")))) &&
723 (NULL == sl_strstr(message, _("Checking"))))
724 {
725 assessment->impact->completion = succeeded;
726 assessment->impact->type = user;
727 strncpy(description,
728 _("Login/logout detected by Samhain."),
729 128);
730 description[127] = '\0';
731 }
732 else
733 {
734 /* assessment->impact->severity = impact_low; */
735 assessment->impact->completion = succeeded;
736 assessment->impact->type = other;
737 strncpy(description,
738 _("Message by Samhain."),
739 128);
740 description[127] = '\0';
741 }
742 }
743 idmef_string_set (&assessment->impact->description, description);
744 idmef_assessment_confidence_new(assessment);
745 assessment->confidence->rating = high;
746
747 /* ------- Additional Data -------
748 *
749 * Here we supply the log message.
750 *
751 */
752 data = idmef_alert_additional_data_new(alert);
753 if ( ! data )
754 goto err;
755
756 data->type = string;
757 idmef_string_set (&data->meaning, meaning);
758 if (message)
759 idmef_additional_data_set_data (data, string, message,
760 strlen(message) + 1);
761
762 /* ------- Send -------
763 *
764 * Finally, the preparated message is sent.
765 */
766 msgbuf = prelude_msgbuf_new(0);
767 if ( ! msgbuf )
768 goto err;
769
770 /* Always return 0 (in libprelude 0.8.10); i.e. no useful
771 * exit status
772 */
773 idmef_msg_send(msgbuf, idmef, PRELUDE_MSG_PRIORITY_HIGH);
774
775 /* Cleanup
776 */
777 idmef_message_free(idmef);
778 prelude_msgbuf_close(msgbuf);
779 if (path_basename)
780 {
781 SH_FREE(path_basename);
782 path_basename = NULL;
783 }
784 if (path_fullname)
785 {
786 SH_FREE(path_fullname);
787 path_fullname = NULL;
788 }
789 if (impactmsg)
790 SH_FREE(impactmsg);
791 if (src_ip)
792 SH_FREE(src_ip);
793
794 some_error = 0;
795
796 return 0;
797
798 err:
799 /* Cleanup
800 */
801 idmef_message_free(idmef);
802 if (0 == some_error)
803 {
804 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
805 _("Problem with IDMEF for prelude-ids support: alert lost"),
806 _("sh_prelude_alert"));
807 }
808 if (path_basename)
809 {
810 SH_FREE(path_basename);
811 path_basename = NULL;
812 }
813 if (path_fullname)
814 {
815 SH_FREE(path_fullname);
816 path_fullname = NULL;
817 }
818 if (impactmsg)
819 SH_FREE(impactmsg);
820 if (src_ip)
821 SH_FREE(src_ip);
822 some_error = 1;
823 return -1;
824
825}
826
827/* HAVE_LIBPRELUDE */
828#endif
Note: See TracBrowser for help on using the repository browser.