source: trunk/src/sh_err_log.c@ 237

Last change on this file since 237 was 212, checked in by katerina, 16 years ago

Lock baseline database (ticket #139) and allow list as input for PortCheckInterface (ticket #140).

File size: 26.0 KB
RevLine 
[1]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
[20]118int sh_error_logverify_mod (const char * s)
[1]119{
120 just_list = S_TRUE;
121 if (s) /* compiler warning (unused var) fix */
122 return 0;
123 else
124 return 0;
125}
126
[20]127int sh_error_logverify (const char * s)
[1]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;
[133]147 char hashbuf[KEYBUF_SIZE];
[1]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
[170]186 buf = (char *) SH_ALLOC( 2*SH_MSG_BUF+1 );
187 bufc = (char *) SH_ALLOC( 2*SH_MSG_BUF+1 );
[1]188
189 while (1 == 1)
190 {
191 /* get the log message
192 */
[170]193 if (sh_unix_getline (fd, buf, (2*SH_MSG_BUF)) < 0)
[1]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 {
[170]224 if ( sh_unix_getline (fd, buf, (2*SH_MSG_BUF)) < 0)
[1]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 {
[170]295 if ( sh_unix_getline (fd, bufc, (2*SH_MSG_BUF)) < 0)
[1]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 */
[170]303 (void) sl_strlcat(buf, "\n", 2*SH_MSG_BUF+1);
[1]304 ++len;
[170]305 (void) sl_strlcat(buf, bufc, 2*SH_MSG_BUF+1);
[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')
[210]382 fprintf(stdout, "%s",_("New audit trail, enter key: "));
[1]383 else if (key[0] == '\n')
384 {
385 (void) sl_strlcpy(key,
[133]386 sh_tiger_hash(NULL, TIGER_DATA, 0,
387 hashbuf, sizeof(hashbuf)),
[1]388 KEY_LEN+1);
389 chk_mode = CHK_NON;
390 break;
391 }
392 (void) fflush(stdout);
393 key[0] = '\0';
[153]394 if (NULL != fgets(key, sizeof(key), stdin))
[1]395 {
[153]396 if (key[0] != '\n')
397 {
398 if (key[strlen(key) - 1] == '\n')
399 key[strlen(key) - 1] = '\0';
400 }
401 if (key[0] == '/')
402 {
403 chk_mode = CHK_FIL;
404 (void) sl_strlcpy(path, key, KEY_LEN+1);
405 break;
406 }
[1]407 }
408 }
409 }
410 /* we now have either a key (chk_mode == CHK_NON|CHK_KEY)
411 * or a file (chk_mode == CHK_FIL)
412 */
413 if (chk_mode == CHK_FIL)
414 {
415 fprintf(stdout, _("\nAudit trail (%s), searching file %s\n"),
416 /*@-usedef@*/timestamp, path/*@+usedef@*/);
417 if (-1 == get_key_from_file(path, timestamp, key))
418 {
419 chk_mode = CHK_KEY;
[210]420 fprintf(stdout, "%s",_("Key not found in file\n"));
[1]421 goto findKey;
422 }
423 }
424
425
426 sh_util_encode(key, buf, 1, 'B');
427 start = 0;
428 }
429 else
430 {
431 /* Iterate the key.
432 */
433 (void) sl_strlcpy (key,
[133]434 sh_tiger_hash (key, TIGER_DATA, KEY_LEN,
435 hashbuf, sizeof(hashbuf)),
[1]436 KEY_LEN+1);
437 }
438
[170]439 (void) sl_strlcat ( buf, key, 2*SH_MSG_BUF + 1);
[1]440
441#ifdef SH_STEALTH
442 sh_do_decode (signature, sl_strlen(signature));
443#endif
444
445 status = sl_strncmp (signature,
446 sh_tiger_hash (buf, TIGER_DATA,
[133]447 (unsigned long) sl_strlen(buf),
448 hashbuf, sizeof(hashbuf)),
[1]449 KEY_LEN);
450
451 buf[len] = '\0'; /* do not print out the key */
452#ifdef SH_STEALTH
453 sh_do_decode (buf, sl_strlen(buf));
454#endif
455
456 if (status != 0)
457 {
458#ifdef SH_USE_XML
459 if (chk_mode == CHK_NON)
460 {
461 if (fixed_xml == S_FALSE)
462 fprintf (stdout, _("XFAIL: line=%05d %s/log>\n"),
463 count-1, buf);
464 else
465 fprintf (stdout, _("XFAIL: line=%05d %s</log>\n"),
466 count-1, buf);
467 }
468 else
469 {
470 if (fixed_xml == S_FALSE)
471 fprintf (stdout, _("FAIL: line=%05d %s/log>\n"),
472 count-1, buf);
473 else
474 fprintf (stdout, _("FAIL: line=%05d %s</log>\n"),
475 count-1, buf);
476 }
477#else
478 if (chk_mode == CHK_NON)
479 fprintf (stdout, _("XFAIL: line=%5d %s\n"), count-1, buf);
480 else
481 fprintf (stdout, _("FAIL: line=%5d %s\n"), count-1, buf);
482#endif
483 }
484 else
485 {
486#ifdef SH_USE_XML
487 if (fixed_xml == S_FALSE)
488 fprintf (stdout, _("PASS: line=%05d %s/log>\n"), count-1, buf);
489 else
490 fprintf (stdout, _("PASS: line=%05d %s</log>\n"), count-1, buf);
491#else
492 fprintf (stdout, _("PASS: line=%5d %s\n"), count-1, buf);
493#endif
494 }
495 }
496
497 /* Cleanup and exit.
498 */
499 (void) sl_close (fd);
500 SH_FREE (buf);
501 SH_FREE (bufc);
502 (void) fflush (stdout);
503 _exit (EXIT_SUCCESS);
504
505 /* Make compilers happy.
506 */
507 /*@notreached@*/
508 return 0;
509}
510
511/********************************************************************
512 *
513 * Runtime code
514 *
515 ********************************************************************/
516static
517int sh_log_open (char * inet_peer,
518 char * logfile, int * service_failure, SL_TICKET * fildesc)
519{
520 SL_TICKET fd = -1;
521 long int status;
522 char * tmp = NULL;
523 uid_t uid;
524 size_t len;
525 char * lockfile = NULL;
526
527 SL_ENTER(_("sh_log_open"));
528
529 /* open/create the file, then check it
530 */
531
532 if ( 0 != (status = tf_trust_check (logfile, SL_YESPRIV))
533 && (*service_failure) == 0)
534 {
535 tmp = sh_util_safe_name (logfile);
536 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_TRUST,
537 (long) sh.effective.uid, tmp);
538 }
539
540 if (status == 0)
541 {
542 fd = sl_open_write (logfile, SL_YESPRIV);
543 if (SL_ISERROR(fd))
544 {
545 tmp = sh_util_safe_name (logfile);
546 (void) sl_get_euid(&uid);
547 if ((*service_failure) == 0)
548 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_E_ACCESS,
549 (long) uid, tmp);
550 status = -1;
551 }
552 }
553
554
555 if (status == 0 && inet_peer == NULL )
556 {
557 status = sh_unix_write_lock_file(logfile);
558 if (status < 0)
559 {
560 tmp = sh_util_safe_name (logfile);
[34]561 len = sl_strlen(tmp);
562 if (sl_ok_adds (6, len))
563 len += 6;
[1]564 lockfile = SH_ALLOC(len);
565 (void) sl_strlcpy(lockfile, tmp, len);
566 (void) sl_strlcat(lockfile, _(".lock"), len);
567 (void) sl_get_euid(&uid);
568 if ((*service_failure) == 0)
569 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_LOCKED,
570 (long) uid, tmp, lockfile);
571 status = -1;
572 SH_FREE(lockfile);
573 (void) sl_close(fd);
574 }
575 }
576
577 if (status == 0)
578 {
579 status = sl_forward(fd);
580 if (SL_ISERROR(status))
581 {
582 tmp = sh_util_safe_name (logfile);
583 (void) sl_get_euid(&uid);
584 if ((*service_failure) == 0)
585 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_ACCESS,
586 (long) uid, tmp);
587 status = -1;
588 (void) sl_close(fd);
589 }
590 }
591
592 if (status < 0)
593 {
594 if ((*service_failure) == 0) {
595 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_SRV_FAIL,
596 _("logfile"), tmp);
597 (*service_failure) = 1;
598 }
599 SH_FREE(tmp);
600 SL_RETURN(-1, _("sh_log_open"));
601 }
602
603 *fildesc = fd;
604 *service_failure = 0;
605 SL_RETURN(0, _("sh_log_open"));
606}
607
608typedef struct lfstc {
609 char * logfile;
610 int service_failure;
611 int log_start;
612 char sigkey_old[KEY_LEN+1];
613 char sigkey_new[KEY_LEN+1];
[22]614 char crypto[KEY_LEN+1];
[1]615 struct lfstc * next;
616} open_logfile;
617
618static open_logfile * logfile_list = NULL;
619
620static int flag_sep_log = S_FALSE;
621
622#ifdef SH_WITH_SERVER
[22]623int set_flag_sep_log (const char * str)
[1]624{
625 return sh_util_flagval(str, &flag_sep_log);
626}
627#endif
628
629/*
630 * --- Log error message to log file. ---
631 */
632int sh_log_file (/*@null@*/char *errmsg, /*@null@*/char * inet_peer)
633{
634 int store1;
635 int store2;
636 int store3;
637 int store4;
638 int store5;
639 int store6;
640 int store7;
641 int store8;
642
643 SL_TICKET fd = -1;
[34]644 size_t status;
[1]645 struct _sh_log_buf log_msg;
646
647 char logfile[SH_PATHBUF+SH_MINIBUF+2];
648 open_logfile * current = logfile_list;
649 open_logfile * next = NULL;
650 char * sigkey_new;
651 char * sigkey_old;
[22]652 char * crypto;
[137]653 char hashbuf[KEYBUF_SIZE];
[1]654
655 SL_ENTER(_("sh_log_file"));
656
657 if (errFlags.HaveLog == BAD) /* paranoia */
658 SL_RETURN((-1), _("sh_log_file"));
659
660#ifdef SH_USE_XML
661 if (NULL == errmsg)
662 {
663 while (current != NULL)
664 {
665 /* don't write second EOF mark
666 */
[212]667 if (current->log_start != S_TRUE && sh.flag.islocked == GOOD)
[1]668 {
669 /* Don't use inet_peer == NULL, userwise a lock file will
670 * be created.
671 */
672 (void) sh_log_open ("\0",
673 current->logfile,
674 &(current->service_failure), &fd);
675
676#ifdef SH_STEALTH
677 (void) sl_write_line (fd, N_("</trail>"), 7);
678 (void) sl_write (fd, "\n", 1);
679 (void) sl_sync(fd);
680#else
681 (void) sl_write_line (fd, _("</trail>\n"), 8);
682 (void) sl_sync(fd);
683#endif
684 (void) sl_close(fd);
685 /* sh_unix_rm_lock_file (current->logfile); */
686 }
687 next = current->next;
688 SH_FREE(current->logfile);
689 SH_FREE(current);
690 current = next;
691 }
692 logfile_list = NULL;
693 SL_RETURN( 0, _("sh_log_file"));
694 }
695#else
696 if (NULL == errmsg)
697 {
698 while (current != NULL)
699 {
700 /* sh_unix_rm_lock_file (current->logfile); */
701 next = current->next;
702 SH_FREE(current->logfile);
703 SH_FREE(current);
704 current = next;
705 }
706 logfile_list = NULL;
707 SL_RETURN( 0, _("sh_log_file"));
708 }
709#endif
710
711 (void) sl_strlcpy (logfile, sh.srvlog.name, sizeof(logfile));
712 if (inet_peer != NULL && flag_sep_log == S_TRUE)
713 {
714 (void) sl_strlcat (logfile, ".", sizeof(logfile));
715 (void) sl_strlcat (logfile, inet_peer, sizeof(logfile));
716 }
717
718 if (sh.flag.log_start == S_TRUE)
719 {
720 while (current != NULL)
721 {
722 current->log_start = S_TRUE;
723 current = current->next;
724 }
725 sh.flag.log_start = S_FALSE;
726 current = logfile_list;
727 }
728
729 while (current != NULL)
730 {
731 if (strcmp(logfile, current->logfile) == 0)
732 break;
733 current = current->next;
734 }
735
736 if (current == NULL)
737 {
738 current = SH_ALLOC(sizeof(open_logfile));
739 current->logfile = SH_ALLOC(strlen(logfile) + 1);
740 (void) sl_strlcpy(current->logfile, logfile, strlen(logfile) + 1);
741 current->service_failure = 0;
742 current->log_start = S_TRUE;
743 memset(current->sigkey_old, (int)'\0', KEY_LEN+1);
744 memset(current->sigkey_new, (int)'\0', KEY_LEN+1);
[22]745 memset(current->crypto, (int)'\0', KEY_LEN+1);
[1]746 current->next = logfile_list;
747 logfile_list = current;
748 }
749
750 if (0 != sh_log_open (inet_peer, current->logfile,
751 &(current->service_failure), &fd))
752 {
753 SL_RETURN ((-1), _("sh_log_file"));
754 }
755
756
757 /* --- Allocate storage and mlock it. ---
758 */
759
[34]760 status = sl_strlen (errmsg);
761 if (!sl_ok_adds(status, (2*KEY_LEN)) || !sl_ok_adds((2*KEY_LEN + status),32))
762 {
763 SL_RETURN ((-1), _("sh_log_file"));
764 }
765
[1]766 log_msg.msg = (char *) SH_ALLOC ((size_t) (2*KEY_LEN + status + 32));
767
768#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
769 if (skey->mlock_failed == SL_FALSE)
770 {
[19]771 if ( (-1) == sh_unix_mlock( FIL__, __LINE__, log_msg.msg,
[1]772 (size_t)(2*KEY_LEN + status + 32) ) )
773 {
774 skey->mlock_failed = SL_TRUE;
775#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
776 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
777#endif
778 }
779 }
780#else
781 if (skey->mlock_failed == SL_FALSE)
782 {
783 skey->mlock_failed = SL_TRUE;
784#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
785 sh_error_handle ((-1), FIL__, __LINE__, EPERM, MSG_MLOCK);
786#endif
787 }
788#endif
789
790 /* --- Write the start marker. ---
791 */
792
793 if (current->log_start == S_TRUE)
794 {
795#ifdef SH_USE_XML
796#ifdef SH_STEALTH
797 (void) sl_write (fd, "\n", 1);
798 (void) sl_write_line (fd, N_("<trail>"), 7);
799 (void) sl_sync(fd);
800#else
801 (void) sl_write_line (fd, _("\n<trail>"), 8);
802 (void) sl_sync(fd);
803#endif
804#else
805#ifdef SH_STEALTH
806 (void) sl_write (fd, "\n", 1);
807 (void) sl_write_line (fd, N_("[SOF]"), 5);
808 (void) sl_sync(fd);
809#else
810 (void) sl_write_line (fd, _("\n[SOF]"), 6);
811 (void) sl_sync(fd);
812#endif
813#endif
814 }
815
816 /* reserve KEY_LEN chars at end for key
817 */
818 (void) sl_strlcpy (log_msg.msg, errmsg, (size_t) status+1 );
819
820
821#ifdef SH_USE_XML
822 /* cut the trailing "/>"
823 */
824 if (log_msg.msg[status-2] == '/')
825 {
826#ifdef FIX_XML
827 log_msg.msg[status-2] = ' '; /* ' ' FIX XML */
828 log_msg.msg[status-1] = '>'; /* '>' FIX XML */
829#else
830 log_msg.msg[status-2] = '>'; /* ' ' FIX XML */
831 log_msg.msg[status-1] = '<'; /* '>' FIX XML */
832#endif
833 log_msg.msg[status] = '\0';
834 }
835 else if (status >= 6 && log_msg.msg[status-5] == '/' &&
836 log_msg.msg[status-6] == '<')
837 {
838#ifdef FIX_XML
839 log_msg.msg[status-6] = '\0';
840 status -= 6;
841#else
842 log_msg.msg[status-5] = '\0';
843 status -= 5;
844#endif
845 }
846#endif
847
848
849#ifdef SH_STEALTH
850 sh_do_encode (log_msg.msg, status);
851#endif
852
853 if (flag_sep_log == S_TRUE && inet_peer != NULL)
854 {
855 sigkey_old = current->sigkey_old;
856 sigkey_new = current->sigkey_new;
[22]857 crypto = current->crypto;
[1]858 }
859 else
860 {
861 sigkey_old = skey->sigkey_old;
862 sigkey_new = skey->sigkey_new;
[22]863 crypto = skey->crypt; /* flawfinder: ignore */
[1]864 }
865
866 /* write the signature
867 */
868 if (current->log_start == S_TRUE)
869 {
870 if (sh.real.user[0] == '\0')
871 (void) sh_unix_getUser();
872
873 /* Initialize the key.
874 */
875 (void) sh_util_keyinit(sigkey_old, KEY_LEN+1);
876
877 /* Hash the key to make sure it has the correct format.
878 */
879 (void) sl_strlcpy(sigkey_new,
[133]880 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
881 hashbuf, sizeof(hashbuf)),
[1]882 KEY_LEN+1);
883
884 /* Copy it to 'crypt' for encryption.
885 */
[22]886 (void) sl_strlcpy(crypto, sigkey_new, KEY_LEN+1);
[1]887
888 /* Use message and compiled-in key to encrypt.
889 */
890 BREAKEXIT(sh_util_encode);
[22]891 sh_util_encode(crypto, log_msg.msg, 0, 'B');
[1]892
893 /* Send out the key.
894 */
[132]895 (void) sh_unix_time(0, log_msg.timestamp, KEY_LEN+1);
[1]896
897 store1 = errFlags.loglevel;
898 store2 = errFlags.sysloglevel;
899 store3 = errFlags.printlevel;
900 store4 = errFlags.exportlevel;
901 store5 = errFlags.maillevel;
902 store6 = errFlags.externallevel;
903 store7 = errFlags.databaselevel;
904 store8 = errFlags.preludelevel;
905
906 /* mail the key
907 */
908 errFlags.loglevel = SH_ERR_NOT;
909 errFlags.sysloglevel = SH_ERR_NOT;
910 errFlags.printlevel = SH_ERR_NOT;
911 errFlags.exportlevel = SH_ERR_NOT;
912 errFlags.externallevel = SH_ERR_NOT;
913 errFlags.databaselevel = SH_ERR_NOT;
914 errFlags.preludelevel = SH_ERR_NOT;
915
916 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY_MAIL,
[22]917 sh.prg_name, crypto,
918 crypto, log_msg.timestamp);
[1]919
920 /* send to other allowed channels
921 */
922 errFlags.maillevel = SH_ERR_NOT;
923 /* errFlags.printlevel = store3; */
924 errFlags.exportlevel = store4;
925 errFlags.externallevel = store6;
926 errFlags.databaselevel = store7;
927 errFlags.preludelevel = store8;
928
929 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_START_KEY,
[22]930 sh.prg_name, crypto);
[1]931
932 /* Cleanup.
933 */
934 errFlags.loglevel = store1;
935 errFlags.sysloglevel = store2;
936 errFlags.printlevel = store3;
937 errFlags.exportlevel = store4;
938 errFlags.maillevel = store5;
939 errFlags.externallevel = store6;
940 errFlags.databaselevel = store7;
941
942
[22]943 memset (crypto, (int) '\0', KEY_LEN);
[1]944 sh.flag.log_start = S_FALSE;
945 current->log_start = S_FALSE;
946 }
947 else
948 {
949 log_msg.timestamp[0] = '\0';
950 (void) sl_strlcpy (sigkey_new,
[138]951 sh_tiger_hash (sigkey_old, TIGER_DATA, KEY_LEN,
952 hashbuf, sizeof(hashbuf)),
[1]953 KEY_LEN+1);
954 }
955
956 /* --- Sign the message with the signature key. ---
957 */
[137]958 sh_tiger_hash (log_msg.msg, TIGER_DATA,
[138]959 (unsigned long)(status + KEY_LEN),
960 (char *) hashbuf, (size_t) sizeof(hashbuf));
[1]961
962 (void) sl_strlcat (log_msg.msg, sigkey_new, (size_t)(status + KEY_LEN + 2));
963 (void) sl_strlcpy (log_msg.signature,
[137]964 sh_tiger_hash (log_msg.msg, (TigerType) TIGER_DATA,
[138]965 (unsigned long)(status + KEY_LEN),
966 hashbuf, sizeof(hashbuf)),
[1]967 KEY_LEN+1);
968 (void) sl_strlcpy (sigkey_old, sigkey_new, KEY_LEN+1);
969
[22]970 /*@-usedef@*/
[1]971#ifdef SH_USE_XML
972 if (log_msg.timestamp[0] != '\0')
[22]973 sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
[1]974#ifdef FIX_XML
[22]975 _("\n<sig>%s%s</sig></log>\n"), /* <sig> FIX XML */
[1]976#else
[22]977 _("\nsig>%s%s</sig></log>\n"), /* <sig> FIX XML */
[1]978#endif
[22]979 log_msg.signature, log_msg.timestamp);
[1]980 else
[22]981 sl_snprintf(log_msg.sig, sizeof(log_msg.sig),
[1]982#ifdef FIX_XML
[22]983 _("\n<sig>%s</sig></log>\n"), /* <sig> FIX XML */
[1]984#else
[22]985 _("\nsig>%s</sig></log>\n"), /* <sig> FIX XML */
[1]986#endif
[22]987 log_msg.signature);
988 /*@+usedef@*/
[1]989
990#ifdef SH_STEALTH
991 /* don't encode the line breaks (0 + last char)
992 */
993 sh_do_encode (&log_msg.sig[1], (sl_strlen(log_msg.sig)-2) );
994#endif
995#else
996#ifdef SH_STEALTH
997 sh_do_encode (log_msg.signature, KEY_LEN);
998 sh_do_encode (log_msg.timestamp, sl_strlen(log_msg.timestamp));
999#endif
1000#endif
1001
1002#ifdef SH_USE_XML
1003 log_msg.msg[status] = '\0';
1004 (void) sl_strlcat (log_msg.msg, log_msg.sig,
1005 (size_t)(status + 2*KEY_LEN + 32));
1006#ifdef SH_STEALTH
1007 if (NULL != sl_strstr(log_msg.msg, N_("EXIT")) &&
1008 NULL == sl_strstr(log_msg.msg, N_("remote_host")))
1009 {
1010 (void) sl_strlcat (log_msg.msg, N_("</trail>"),
1011 (size_t)(status + 2*KEY_LEN + 32));
1012#else
1013 if (NULL != sl_strstr(log_msg.msg, _("msg=\"EXIT\"")) &&
1014 NULL == sl_strstr(log_msg.msg, _("remote_host")))
1015 {
1016 (void) sl_strlcat (log_msg.msg, _("</trail>"),
1017 (size_t)(status + 2*KEY_LEN + 32));
1018#endif
1019
1020 (void) sl_strlcat (log_msg.msg, _("\n"),
1021 (size_t)(status + 2*KEY_LEN + 32));
1022 current->log_start = S_TRUE;
1023 }
1024#else
1025 log_msg.msg[status] = '\0';
1026 (void) sl_strlcat (log_msg.msg, "\n",
1027 (size_t)(status + KEY_LEN + 2));
1028 (void) sl_strlcat (log_msg.msg, log_msg.signature,
1029 (size_t)(status + KEY_LEN + 2));
1030 if (log_msg.timestamp[0] != '\0')
1031 (void) sl_strlcat (log_msg.msg, log_msg.timestamp,
1032 (size_t)(status + 2*KEY_LEN + 2));
1033 (void) sl_strlcat (log_msg.msg, "\n",
1034 (size_t)(status + 2*KEY_LEN + 3));
1035#endif
1036
1037 /* --- Write out the record. ---
1038 */
1039 (void) sl_write (fd, log_msg.msg, (long) strlen(log_msg.msg));
1040 (void) sl_sync (fd);
1041 (void) sl_close (fd);
1042
1043 /* --- Clean up and free record. ---
1044 */
1045 memset (log_msg.msg, (int)'\0', (size_t)(status + 2*KEY_LEN + 32));
1046 memset (log_msg.signature, (int)'\0', KEY_LEN);
1047 (void) sh_unix_munlock (log_msg.msg,
1048 (size_t)(status + 2*KEY_LEN + 32));
1049 SH_FREE(log_msg.msg);
1050
1051 SL_RETURN (0, _("sh_log_file"));
1052}
1053
Note: See TracBrowser for help on using the repository browser.