source: trunk/src/sh_err_log.c@ 144

Last change on this file since 144 was 138, checked in by rainer, 17 years ago

More fixes for compile and runtime errors.

File size: 26.0 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) 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; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <unistd.h>
26
27#include "samhain.h"
28#include "sh_error.h"
29#include "sh_utils.h"
30#include "sh_tiger.h"
31
32#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
33#include <sys/mman.h>
34#endif
35
36
37#undef FIL__
38#define FIL__ _("sh_err_log.c")
39
40#undef FIX_XML
41#define FIX_XML 1
42
43#define MYSIGLEN (2*KEY_LEN + 32)
44
45typedef struct _sh_log_buf {
46 char signature[KEY_LEN+1];
47 char timestamp[KEY_LEN+1];
48#ifdef SH_USE_XML
49 char sig[MYSIGLEN];
50#endif
51 char * msg;
52} sh_sh_log_buf;
53
54extern struct _errFlags errFlags;
55
56#define CHK_KEY 0
57#define CHK_FIL 1
58#define CHK_NON 2
59
60static int get_key_from_file(char * path, char * keyid, char * key)
61{
62 SL_TICKET fd;
63 char * buf;
64 char * bufc;
65
66 if (path[strlen(path)-1] == '\n')
67 path[strlen(path)-1] = '\0';
68
69 /* open the file, then check it
70 */
71 if ( SL_ISERROR(fd = sl_open_read (path, SL_NOPRIV)))
72 {
73 fprintf(stderr, _("Could not open file <%s>\n"), path);
74 _exit (EXIT_FAILURE);
75 }
76
77 buf = SH_ALLOC( (size_t)(SH_BUFSIZE+1));
78 bufc = SH_ALLOC( (size_t)(SH_MAXBUF+1));
79
80 while (1 == 1)
81 {
82 buf[0] = '\0';
83 bufc[0] = '\0';
84
85 /* find start of next key
86 */
87 while (0 != sl_strncmp(buf, _("-----BEGIN LOGKEY-----"),
88 sizeof("-----BEGIN LOGKEY-----")-1))
89 {
90 (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
91 if (buf[0] == '\0')
92 {
93 /* End of file reached, return.
94 */
95 (void) fflush(stdout);
96 (void) sl_close(fd);
97 return -1;
98 }
99 }
100
101 /* read key
102 */
103 (void) sh_unix_getline (fd, buf, SH_BUFSIZE);
104
105 if (0 == sl_strncmp(keyid, &buf[KEY_LEN], strlen(keyid)))
106 {
107 (void) sl_strlcpy(key, buf, KEY_LEN+1);
108 (void) sl_close(fd);
109 return 0;
110 }
111 }
112
113 /*@notreached@*/
114}
115
116static int just_list = S_FALSE;
117
118int sh_error_logverify_mod (const char * s)
119{
120 just_list = S_TRUE;
121 if (s) /* compiler warning (unused var) fix */
122 return 0;
123 else
124 return 0;
125}
126
127int sh_error_logverify (const char * s)
128{
129 SL_TICKET fd;
130 int len;
131 int status;
132 int count = 0;
133 int start = -1;
134 char * buf;
135 char * bufc;
136#ifdef SH_USE_XML
137 char * ptr;
138 int fixed_xml = S_TRUE;
139 char c_start;
140#endif
141 char signature[64];
142 char key[KEY_LEN+2];
143 char path[KEY_LEN+1];
144 char timestamp[64];
145 char c_cont;
146 int chk_mode = CHK_KEY;
147 char hashbuf[KEYBUF_SIZE];
148
149 sh_error_logoff();
150
151 if (s == NULL || sl_strlen(s) >= PATH_MAX)
152 {
153 fprintf(stderr, _("FAIL: msg=\"Invalid input\", path=\"%s\"\n"), s);
154 _exit (EXIT_FAILURE);
155 }
156
157 /* Open the file, then check it.
158 */
159 if (0 != sl_is_suid())
160 {
161 fprintf(stderr, _("Cannot open file %s in suid mode\n"), s);
162 _exit (EXIT_FAILURE);
163 }
164
165 if ( SL_ISERROR(fd = sl_open_read (s, SL_NOPRIV)) )
166 {
167 fprintf(stderr,
168 _("FAIL: msg=\"File not accessible\", error=\"%ld\", path=\"%s\"\n"), fd, s);
169 _exit (EXIT_FAILURE);
170 }
171
172 /* Find space value.
173 */
174 c_cont = ' ';
175#ifdef SH_STEALTH
176 c_cont ^= XOR_CODE;
177#endif
178
179#ifdef SH_USE_XML
180 c_start = '<';
181#ifdef SH_STEALTH
182 c_start ^= XOR_CODE;
183#endif
184#endif
185
186 buf = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );
187 bufc = (char *) SH_ALLOC( 2*SH_BUFSIZE+1 );
188
189 while (1 == 1)
190 {
191 /* get the log message
192 */
193 if (sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0)
194 break;
195
196 len = (int) sl_strlen(buf);
197
198#ifdef SH_USE_XML
199#ifdef SH_STEALTH
200 if (0 == sl_strncmp (buf, N_("<trail>"), 7))
201#else
202 if (0 == sl_strncmp (buf, _("<trail>"), 7))
203#endif
204#else
205#ifdef SH_STEALTH
206 if (0 == sl_strncmp (buf, N_("[SOF]"), 5))
207#else
208 if (0 == sl_strncmp (buf, _("[SOF]"), 5))
209#endif
210#endif
211 {
212 if (just_list == S_TRUE)
213 {
214#ifdef SH_STEALTH
215 sh_do_decode (buf, sl_strlen(buf));
216#endif
217 fprintf (stdout, _("%s\n"), buf);
218 }
219
220 /* Found start of audit trail, read first line.
221 */
222 start = 1;
223 do {
224 if ( sh_unix_getline (fd, buf, (2*SH_BUFSIZE)) < 0)
225 break;
226 } while (buf[0] == '\0' || buf[0] == '\n');
227 len = (int) sl_strlen(buf);
228
229 if (just_list == S_TRUE)
230 {
231#ifdef SH_STEALTH
232 if (buf[0] != '\n')
233 sh_do_decode (buf, sl_strlen(buf));
234#endif
235 fprintf (stdout, _("%s\n"), buf);
236 start = 0;
237 }
238
239 ++count;
240 }
241 else if (buf[0] == '\n'
242#ifdef SH_USE_XML
243 ||
244#ifdef SH_STEALTH
245 0 == sl_strncmp(buf, N_("</trail>"), 7)
246#else
247 0 == sl_strncmp(buf, _("</trail>"), 7)
248#endif
249#endif
250 )
251 {
252 if (just_list == S_TRUE)
253 {
254#ifdef SH_STEALTH
255 if (buf[0] != '\n')
256 sh_do_decode (buf, sl_strlen(buf));
257#endif
258 fprintf (stdout, _("%s\n"), buf);
259 }
260
261 /* A newline.
262 */
263 ++count;
264 continue;
265 }
266 else if (start == 0)
267 {
268 /* We are inside an audit trail.
269 */
270 ++count;
271 if (just_list == S_TRUE)
272 {
273#ifdef SH_STEALTH
274 sh_do_decode (buf, sl_strlen(buf));
275#endif
276 fprintf (stdout, _("%s\n"), buf);
277 continue;
278 }
279 }
280 else
281 {
282 /* No start-of-file found yet.
283 */
284 continue;
285 }
286
287 if (just_list == S_TRUE)
288 continue;
289
290 /* Check for a continuation line.
291 */
292 while (1 == 1)
293 {
294 do {
295 if ( sh_unix_getline (fd, bufc, (2*SH_BUFSIZE)) < 0)
296 break;
297 } while (bufc[0] == '\0' || bufc[0] == '\n');
298 ++count;
299 if (bufc[0] == c_cont)
300 {
301 /* A continuation line. Add the newline.
302 */
303 (void) sl_strlcat(buf, "\n", 2*SH_BUFSIZE+1);
304 ++len;
305 (void) sl_strlcat(buf, bufc, 2*SH_BUFSIZE+1);
306 len += (int) sl_strlen(bufc);
307 }
308 else
309 {
310 /* No continuation line. Use it as signature.
311 * A48014C05604EF7C9472330E85453E704024943E556163C2
312 */
313#ifdef SH_USE_XML
314#ifdef SH_STEALTH
315 if (bufc[0] == c_start) /* FIX XML */
316#else
317 if (bufc[0] == c_start)
318#endif
319 {
320 (void) sl_strlcpy(signature, &bufc[5], KEY_LEN+1);
321 fixed_xml = S_TRUE;
322 }
323 else
324 {
325 (void) sl_strlcpy(signature, &bufc[4], KEY_LEN+1);
326 fixed_xml = S_FALSE;
327 }
328 if (sl_strlen(bufc) > (KEY_LEN+18))
329 {
330#ifdef SH_STEALTH
331 if (bufc[0] == c_start) /* FIX XML */
332#else
333 if (bufc[0] == c_start)
334#endif
335 (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+5], 64);
336 else
337 (void) sl_strlcpy(timestamp, &bufc[KEY_LEN+4], 64);
338#ifdef SH_STEALTH
339 ptr = strchr(timestamp, c_start);
340#else
341 ptr = strchr(timestamp, c_start);
342#endif
343 if (ptr) *ptr = '\0';
344 }
345 break;
346#else
347 sl_strlcpy(signature, bufc, KEY_LEN+1);
348 if (sl_strlen(bufc) > KEY_LEN)
349 sl_strlcpy(timestamp, &bufc[KEY_LEN], 64);
350 break;
351#endif
352 }
353 }
354
355 /* Get starting key from command line.
356 */
357 if (start == 1)
358 {
359
360 /* Get the timestamp.
361 */
362
363#ifdef SH_STEALTH
364 sh_do_decode (timestamp, sl_strlen(timestamp));
365#endif
366 key[0] = '\0';
367
368 findKey:
369
370 if (chk_mode != CHK_FIL)
371 {
372 /* Ask for the key.
373 */
374 chk_mode = CHK_KEY;
375 fprintf(stdout, _("\nNew audit trail (%s), enter key|keyfile: "),
376 /*@-usedef@*/timestamp/*@+usedef@*/);
377 key[0] = '\0';
378
379 while (sl_strlen(key) < KEY_LEN )
380 {
381 if (key[0] != '\n' && key[0] != '\0')
382 fprintf(stdout, _("New audit trail, enter key: "));
383 else if (key[0] == '\n')
384 {
385 (void) sl_strlcpy(key,
386 sh_tiger_hash(NULL, TIGER_DATA, 0,
387 hashbuf, sizeof(hashbuf)),
388 KEY_LEN+1);
389 chk_mode = CHK_NON;
390 break;
391 }
392 (void) fflush(stdout);
393 key[0] = '\0';
394 (void) fgets(key, sizeof(key), stdin);
395 if (key[0] != '\n')
396 {
397 if (key[strlen(key) - 1] == '\n')
398 key[strlen(key) - 1] = '\0';
399 }
400 if (key[0] == '/')
401 {
402 chk_mode = CHK_FIL;
403 (void) sl_strlcpy(path, key, KEY_LEN+1);
404 break;
405 }
406 }
407 }
408 /* we now have either a key (chk_mode == CHK_NON|CHK_KEY)
409 * or a file (chk_mode == CHK_FIL)
410 */
411 if (chk_mode == CHK_FIL)
412 {
413 fprintf(stdout, _("\nAudit trail (%s), searching file %s\n"),
414 /*@-usedef@*/timestamp, path/*@+usedef@*/);
415 if (-1 == get_key_from_file(path, timestamp, key))
416 {
417 chk_mode = CHK_KEY;
418 fprintf(stdout, _("Key not found in file\n"));
419 goto findKey;
420 }
421 }
422
423
424 sh_util_encode(key, buf, 1, 'B');
425 start = 0;
426 }
427 else
428 {
429 /* Iterate the key.
430 */
431 (void) sl_strlcpy (key,
432 sh_tiger_hash (key, TIGER_DATA, KEY_LEN,
433 hashbuf, sizeof(hashbuf)),
434 KEY_LEN+1);
435 }
436
437 (void) sl_strlcat ( buf, key, 2*SH_BUFSIZE + 1);
438
439#ifdef SH_STEALTH
440 sh_do_decode (signature, sl_strlen(signature));
441#endif
442
443 status = sl_strncmp (signature,
444 sh_tiger_hash (buf, TIGER_DATA,
445 (unsigned long) sl_strlen(buf),
446 hashbuf, sizeof(hashbuf)),
447 KEY_LEN);
448
449 buf[len] = '\0'; /* do not print out the key */
450#ifdef SH_STEALTH
451 sh_do_decode (buf, sl_strlen(buf));
452#endif
453
454 if (status != 0)
455 {
456#ifdef SH_USE_XML
457 if (chk_mode == CHK_NON)
458 {
459 if (fixed_xml == S_FALSE)
460 fprintf (stdout, _("XFAIL: line=%05d %s/log>\n"),
461 count-1, buf);
462 else
463 fprintf (stdout, _("XFAIL: line=%05d %s</log>\n"),
464 count-1, buf);
465 }
466 else
467 {
468 if (fixed_xml == S_FALSE)
469 fprintf (stdout, _("FAIL: line=%05d %s/log>\n"),
470 count-1, buf);
471 else
472 fprintf (stdout, _("FAIL: line=%05d %s</log>\n"),
473 count-1, buf);
474 }
475#else
476 if (chk_mode == CHK_NON)
477 fprintf (stdout, _("XFAIL: line=%5d %s\n"), count-1, buf);
478 else
479 fprintf (stdout, _("FAIL: line=%5d %s\n"), count-1, buf);
480#endif
481 }
482 else
483 {
484#ifdef SH_USE_XML
485 if (fixed_xml == S_FALSE)
486 fprintf (stdout, _("PASS: line=%05d %s/log>\n"), count-1, buf);
487 else
488 fprintf (stdout, _("PASS: line=%05d %s</log>\n"), count-1, buf);
489#else
490 fprintf (stdout, _("PASS: line=%5d %s\n"), count-1, buf);
491#endif
492 }
493 }
494
495 /* Cleanup and exit.
496 */
497 (void) sl_close (fd);
498 SH_FREE (buf);
499 SH_FREE (bufc);
500 (void) fflush (stdout);
501 _exit (EXIT_SUCCESS);
502
503 /* Make compilers happy.
504 */
505 /*@notreached@*/
506 return 0;
507}
508
509/********************************************************************
510 *
511 * Runtime code
512 *
513 ********************************************************************/
514static
515int sh_log_open (char * inet_peer,
516 char * logfile, int * service_failure, SL_TICKET * fildesc)
517{
518 SL_TICKET fd = -1;
519 long int status;
520 char * tmp = NULL;
521 uid_t uid;
522 size_t len;
523 char * lockfile = NULL;
524
525 SL_ENTER(_("sh_log_open"));
526
527 /* open/create the file, then check it
528 */
529
530 if ( 0 != (status = tf_trust_check (logfile, SL_YESPRIV))
531 && (*service_failure) == 0)
532 {
533 tmp = sh_util_safe_name (logfile);
534 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
535 (long) sh.effective.uid, tmp);
536 }
537
538 if (status == 0)
539 {
540 fd = sl_open_write (logfile, SL_YESPRIV);
541 if (SL_ISERROR(fd))
542 {
543 tmp = sh_util_safe_name (logfile);
544 (void) sl_get_euid(&uid);
545 if ((*service_failure) == 0)
546 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
547 (long) uid, tmp);
548 status = -1;
549 }
550 }
551
552
553 if (status == 0 && inet_peer == NULL )
554 {
555 status = sh_unix_write_lock_file(logfile);
556 if (status < 0)
557 {
558 tmp = sh_util_safe_name (logfile);
559 len = sl_strlen(tmp);
560 if (sl_ok_adds (6, len))
561 len += 6;
562 lockfile = SH_ALLOC(len);
563 (void) sl_strlcpy(lockfile, tmp, len);
564 (void) sl_strlcat(lockfile, _(".lock"), len);
565 (void) sl_get_euid(&uid);
566 if ((*service_failure) == 0)
567 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
568 (long) uid, tmp, lockfile);
569 status = -1;
570 SH_FREE(lockfile);
571 (void) sl_close(fd);
572 }
573 }
574
575 if (status == 0)
576 {
577 status = sl_forward(fd);
578 if (SL_ISERROR(status))
579 {
580 tmp = sh_util_safe_name (logfile);
581 (void) sl_get_euid(&uid);
582 if ((*service_failure) == 0)
583 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
584 (long) uid, tmp);
585 status = -1;
586 (void) sl_close(fd);
587 }
588 }
589
590 if (status < 0)
591 {
592 if ((*service_failure) == 0) {
593 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
594 _("logfile"), tmp);
595 (*service_failure) = 1;
596 }
597 SH_FREE(tmp);
598 SL_RETURN(-1, _("sh_log_open"));
599 }
600
601 *fildesc = fd;
602 *service_failure = 0;
603 SL_RETURN(0, _("sh_log_open"));
604}
605
606typedef struct lfstc {
607 char * logfile;
608 int service_failure;
609 int log_start;
610 char sigkey_old[KEY_LEN+1];
611 char sigkey_new[KEY_LEN+1];
612 char crypto[KEY_LEN+1];
613 struct lfstc * next;
614} open_logfile;
615
616static open_logfile * logfile_list = NULL;
617
618static int flag_sep_log = S_FALSE;
619
620#ifdef SH_WITH_SERVER
621int set_flag_sep_log (const char * str)
622{
623 return sh_util_flagval(str, &flag_sep_log);
624}
625#endif
626
627/*
628 * --- Log error message to log file. ---
629 */
630int sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
631{
632 int store1;
633 int store2;
634 int store3;
635 int store4;
636 int store5;
637 int store6;
638 int store7;
639 int store8;
640
641 SL_TICKET fd = -1;
642 size_t status;
643 struct _sh_log_buf log_msg;
644
645 char logfile[SH_PATHBUF+SH_MINIBUF+2];
646 open_logfile * current = logfile_list;
647 open_logfile * next = NULL;
648 char * sigkey_new;
649 char * sigkey_old;
650 char * crypto;
651 char hashbuf[KEYBUF_SIZE];
652
653 SL_ENTER(_("sh_log_file"));
654
655 if (errFlags.HaveLog == BAD) /* paranoia */
656 SL_RETURN((-1), _("sh_log_file"));
657
658#ifdef SH_USE_XML
659 if (NULL == errmsg)
660 {
661 while (current != NULL)
662 {
663 /* don't write second EOF mark
664 */
665 if (current->log_start != S_TRUE)
666 {
667 /* Don't use inet_peer == NULL, userwise a lock file will
668 * be created.
669 */
670 (void) sh_log_open ("\0",
671 current->logfile,
672 &(current->service_failure), &fd);
673
674#ifdef SH_STEALTH
675 (void) sl_write_line (fd, N_("</trail>"), 7);
676 (void) sl_write (fd, "\n", 1);
677 (void) sl_sync(fd);
678#else
679 (void) sl_write_line (fd, _("</trail>\n"), 8);
680 (void) sl_sync(fd);
681#endif
682 (void) sl_close(fd);
683 /* sh_unix_rm_lock_file (current->logfile); */
684 }
685 next = current->next;
686 SH_FREE(current->logfile);
687 SH_FREE(current);
688 current = next;
689 }
690 logfile_list = NULL;
691 SL_RETURN( 0, _("sh_log_file"));
692 }
693#else
694 if (NULL == errmsg)
695 {
696 while (current != NULL)
697 {
698 /* sh_unix_rm_lock_file (current->logfile); */
699 next = current->next;
700 SH_FREE(current->logfile);
701 SH_FREE(current);
702 current = next;
703 }
704 logfile_list = NULL;
705 SL_RETURN( 0, _("sh_log_file"));
706 }
707#endif
708
709 (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
710 if (inet_peer != NULL && flag_sep_log == S_TRUE)
711 {
712 (void) sl_strlcat (logfile, ".", sizeof(logfile));
713 (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
714 }
715
716 if (sh.flag.log_start == S_TRUE)
717 {
718 while (current != NULL)
719 {
720 current->log_start = S_TRUE;
721 current = current->next;
722 }
723 sh.flag.log_start = S_FALSE;
724 current = logfile_list;
725 }
726
727 while (current != NULL)
728 {
729 if (strcmp(logfile, current->logfile) == 0)
730 break;
731 current = current->next;
732 }
733
734 if (current == NULL)
735 {
736 current = SH_ALLOC(sizeof(open_logfile));
737 current->logfile = SH_ALLOC(strlen(logfile) + 1);
738 (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
739 current->service_failure = 0;
740 current->log_start = S_TRUE;
741 memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
742 memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
743 memset(current->crypto, (int)'\0', KEY_LEN+1);
744 current->next = logfile_list;
745 logfile_list = current;
746 }
747
748 if (0 != sh_log_open (inet_peer, current->logfile,
749 &(current->service_failure), &fd))
750 {
751 SL_RETURN ((-1), _("sh_log_file"));
752 }
753
754
755 /* --- Allocate storage and mlock it. ---
756 */
757
758 status = sl_strlen (errmsg);
759 if (!sl_ok_adds(status, (2*KEY_LEN)) || !sl_ok_adds((2*KEY_LEN + status),32))
760 {
761 SL_RETURN ((-1), _("sh_log_file"));
762 }
763
764 log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32));
765
766#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
767 if (skey->mlock_failed == SL_FALSE)
768 {
769 if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg,
770 (size_t)(2*KEY_LEN + status + 32) ) )
771 {
772 skey->mlock_failed = SL_TRUE;
773#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
774 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
775#endif
776 }
777 }
778#else
779 if (skey->mlock_failed == SL_FALSE)
780 {
781 skey->mlock_failed = SL_TRUE;
782#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
783 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
784#endif
785 }
786#endif
787
788 /* --- Write the start marker. ---
789 */
790
791 if (current->log_start == S_TRUE)
792 {
793#ifdef SH_USE_XML
794#ifdef SH_STEALTH
795 (void) sl_write (fd, "\n", 1);
796 (void) sl_write_line (fd, N_("<trail>"), 7);
797 (void) sl_sync(fd);
798#else
799 (void) sl_write_line (fd, _("\n<trail>"), 8);
800 (void) sl_sync(fd);
801#endif
802#else
803#ifdef SH_STEALTH
804 (void) sl_write (fd, "\n", 1);
805 (void) sl_write_line (fd, N_("[SOF]"), 5);
806 (void) sl_sync(fd);
807#else
808 (void) sl_write_line (fd, _("\n[SOF]"), 6);
809 (void) sl_sync(fd);
810#endif
811#endif
812 }
813
814 /* reserve KEY_LEN chars at end for key
815 */
816 (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );
817
818
819#ifdef SH_USE_XML
820 /* cut the trailing "/>"
821 */
822 if (log_msg.msg[status-2] == '/')
823 {
824#ifdef FIX_XML
825 log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
826 log_msg.msg[status-1] = '>'; /* '>' FIX XML */
827#else
828 log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
829 log_msg.msg[status-1] = '<'; /* '>' FIX XML */
830#endif
831 log_msg.msg[status] = '\0';
832 }
833 else if (status >= 6 && log_msg.msg[status-5] == '/' &&
834 log_msg.msg[status-6] == '<')
835 {
836#ifdef FIX_XML
837 log_msg.msg[status-6] = '\0';
838 status -= 6;
839#else
840 log_msg.msg[status-5] = '\0';
841 status -= 5;
842#endif
843 }
844#endif
845
846
847#ifdef SH_STEALTH
848 sh_do_encode (log_msg.msg, status);
849#endif
850
851 if (flag_sep_log == S_TRUE && inet_peer != NULL)
852 {
853 sigkey_old = current->sigkey_old;
854 sigkey_new = current->sigkey_new;
855 crypto = current->crypto;
856 }
857 else
858 {
859 sigkey_old = skey->sigkey_old;
860 sigkey_new = skey->sigkey_new;
861 crypto = skey->crypt; /* flawfinder: ignore */
862 }
863
864 /* write the signature
865 */
866 if (current->log_start == S_TRUE)
867 {
868 if (sh.real.user[0] == '\0')
869 (void) sh_unix_getUser();
870
871 /* Initialize the key.
872 */
873 (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);
874
875 /* Hash the key to make sure it has the correct format.
876 */
877 (void) sl_strlcpy(sigkey_new,
878 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
879 hashbuf, sizeof(hashbuf)),
880 KEY_LEN+1);
881
882 /* Copy it to 'crypt' for encryption.
883 */
884 (void) sl_strlcpy(crypto, sigkey_new, KEY_LEN+1);
885
886 /* Use message and compiled-in key to encrypt.
887 */
888 BREAKEXIT(sh_util_encode);
889 sh_util_encode(crypto, log_msg.msg, 0, 'B');
890
891 /* Send out the key.
892 */
893 (void) sh_unix_time(0, log_msg.timestamp, KEY_LEN+1);
894
895 store1 = errFlags.loglevel;
896 store2 = errFlags.sysloglevel;
897 store3 = errFlags.printlevel;
898 store4 = errFlags.exportlevel;
899 store5 = errFlags.maillevel;
900 store6 = errFlags.externallevel;
901 store7 = errFlags.databaselevel;
902 store8 = errFlags.preludelevel;
903
904 /* mail the key
905 */
906 errFlags.loglevel = SH_ERR_NOT;
907 errFlags.sysloglevel = SH_ERR_NOT;
908 errFlags.printlevel = SH_ERR_NOT;
909 errFlags.exportlevel = SH_ERR_NOT;
910 errFlags.externallevel = SH_ERR_NOT;
911 errFlags.databaselevel = SH_ERR_NOT;
912 errFlags.preludelevel = SH_ERR_NOT;
913
914 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
915 sh.prg_name, crypto,
916 crypto, log_msg.timestamp);
917
918 /* send to other allowed channels
919 */
920 errFlags.maillevel = SH_ERR_NOT;
921 /* errFlags.printlevel = store3; */
922 errFlags.exportlevel = store4;
923 errFlags.externallevel = store6;
924 errFlags.databaselevel = store7;
925 errFlags.preludelevel = store8;
926
927 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
928 sh.prg_name, crypto);
929
930 /* Cleanup.
931 */
932 errFlags.loglevel = store1;
933 errFlags.sysloglevel = store2;
934 errFlags.printlevel = store3;
935 errFlags.exportlevel = store4;
936 errFlags.maillevel = store5;
937 errFlags.externallevel = store6;
938 errFlags.databaselevel = store7;
939
940
941 memset (crypto, (int) '\0', KEY_LEN);
942 sh.flag.log_start = S_FALSE;
943 current->log_start = S_FALSE;
944 }
945 else
946 {
947 log_msg.timestamp[0] = '\0';
948 (void) sl_strlcpy (sigkey_new,
949 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
950 hashbuf, sizeof(hashbuf)),
951 KEY_LEN+1);
952 }
953
954 /* --- Sign the message with the signature key. ---
955 */
956 sh_tiger_hash (log_msg.msg, TIGER_DATA,
957 (unsigned long)(status + KEY_LEN),
958 (char *) hashbuf, (size_t) sizeof(hashbuf));
959
960 (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
961 (void) sl_strlcpy (log_msg.signature,
962 sh_tiger_hash (log_msg.msg, (TigerType) TIGER_DATA,
963 (unsigned long)(status + KEY_LEN),
964 hashbuf, sizeof(hashbuf)),
965 KEY_LEN+1);
966 (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1);
967
968 /*@-usedef@*/
969#ifdef SH_USE_XML
970 if (log_msg.timestamp[0] != '\0')
971 sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
972#ifdef FIX_XML
973 _("\n<sig>%s%s</sig></log>\n"), /* <sig> FIX XML */
974#else
975 _("\nsig>%s%s</sig></log>\n"), /* <sig> FIX XML */
976#endif
977 log_msg.signature, log_msg.timestamp);
978 else
979 sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
980#ifdef FIX_XML
981 _("\n<sig>%s</sig></log>\n"), /* <sig> FIX XML */
982#else
983 _("\nsig>%s</sig></log>\n"), /* <sig> FIX XML */
984#endif
985 log_msg.signature);
986 /*@+usedef@*/
987
988#ifdef SH_STEALTH
989 /* don't encode the line breaks (0 + last char)
990 */
991 sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
992#endif
993#else
994#ifdef SH_STEALTH
995 sh_do_encode (log_msg.signature, KEY_LEN);
996 sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
997#endif
998#endif
999
1000#ifdef SH_USE_XML
1001 log_msg.msg[status] = '\0';
1002 (void) sl_strlcat (log_msg.msg, log_msg.sig,
1003 (size_t)(status + 2*KEY_LEN + 32));
1004#ifdef SH_STEALTH
1005 if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
1006 NULL == sl_strstr(log_msg.msg, N_("remote_host")))
1007 {
1008 (void) sl_strlcat (log_msg.msg, N_("</trail>"),
1009 (size_t)(status + 2*KEY_LEN + 32));
1010#else
1011 if (NULL != sl_strstr(log_msg.msg, _("msg=\"EXIT\"")) &&
1012 NULL == sl_strstr(log_msg.msg, _("remote_host")))
1013 {
1014 (void) sl_strlcat (log_msg.msg, _("</trail>"),
1015 (size_t)(status + 2*KEY_LEN + 32));
1016#endif
1017
1018 (void) sl_strlcat (log_msg.msg, _("\n"),
1019 (size_t)(status + 2*KEY_LEN + 32));
1020 current->log_start = S_TRUE;
1021 }
1022#else
1023 log_msg.msg[status] = '\0';
1024 (void) sl_strlcat (log_msg.msg, "\n",
1025 (size_t)(status + KEY_LEN + 2));
1026 (void) sl_strlcat (log_msg.msg, log_msg.signature,
1027 (size_t)(status + KEY_LEN + 2));
1028 if (log_msg.timestamp[0] != '\0')
1029 (void) sl_strlcat (log_msg.msg, log_msg.timestamp,
1030 (size_t)(status + 2*KEY_LEN + 2));
1031 (void) sl_strlcat (log_msg.msg, "\n",
1032 (size_t)(status + 2*KEY_LEN + 3));
1033#endif
1034
1035 /* --- Write out the record. ---
1036 */
1037 (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
1038 (void) sl_sync (fd);
1039 (void) sl_close (fd);
1040
1041 /* --- Clean up and free record. ---
1042 */
1043 memset (log_msg.msg, (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
1044 memset (log_msg.signature, (int)'\0', KEY_LEN);
1045 (void) sh_unix_munlock (log_msg.msg,
1046 (size_t)(status + 2*KEY_LEN + 32));
1047 SH_FREE(log_msg.msg);
1048
1049 SL_RETURN (0, _("sh_log_file"));
1050}
1051
Note: See TracBrowser for help on using the repository browser.