source: trunk/src/sh_forward.c@ 19

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

Rewrite of test suite, checksum for growing logs, fix for minor bug with dead client detection.

File size: 140.4 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 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 <string.h>
23#include <stdio.h>
24#include <stdlib.h>
25
26
27/* Must be early on FreeBSD
28 */
29#include <sys/types.h>
30
31/* must be .le. than (1020 * 64)
32 * (see sh_tools.c -- put_header)
33 *
34 * also: must be (N * 16), otherwise
35 * binary files cannot be transferred encrypted
36 *
37 * 65280 = (1020*64)
38 * #define TRANS_BYTES 8000 V0.8
39 */
40#ifdef SH_ENCRYPT_2
41#define TRANS_BYTES 65120
42#else
43#define TRANS_BYTES 65280
44#endif
45
46/* timeout for session key
47 */
48#define TIMEOUT_KEY 7200
49
50/* max time between connection attempts
51 */
52#define TIMEOUT_CON 2048
53
54/* #undef SRP_DEBUG */
55/* #define SRP_DEBUG */
56
57#ifdef HAVE_MEMORY_H
58#include <memory.h>
59#endif
60
61#if TIME_WITH_SYS_TIME
62#include <sys/time.h>
63#include <time.h>
64#else
65#if HAVE_SYS_TIME_H
66#include <sys/time.h>
67#else
68#include <time.h>
69#endif
70#endif
71
72/*
73#ifdef TM_IN_SYS_TIME
74#include <sys/time.h>
75#else
76#include <time.h>
77#endif
78*/
79
80#ifdef HAVE_SYS_SELECT_H
81#include <sys/select.h>
82#endif
83
84#ifdef HAVE_UNISTD_H
85#include <errno.h>
86#include <signal.h>
87#include <setjmp.h>
88#include <pwd.h>
89#include <grp.h>
90#include <sys/stat.h>
91#include <sys/resource.h>
92#include <fcntl.h>
93#include <sys/wait.h>
94#include <unistd.h>
95#endif
96
97#ifndef FD_SET
98#define NFDBITS 32
99#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
100#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
101#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
102#endif /* !FD_SET */
103#ifndef FD_SETSIZE
104#define FD_SETSIZE 32
105#endif
106#ifndef FD_ZERO
107#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p)))
108#endif
109
110#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
111#include <sys/mman.h>
112#endif
113
114
115#include <netdb.h>
116#include <sys/types.h>
117#include <netinet/in.h>
118#include <sys/socket.h>
119#ifndef S_SPLINT_S
120#include <arpa/inet.h>
121#endif
122
123#include "samhain.h"
124#include "sh_tiger.h"
125#include "sh_utils.h"
126#include "sh_unix.h"
127#include "sh_forward.h"
128#include "sh_srp.h"
129#include "sh_fifo.h"
130#include "sh_tools.h"
131#include "sh_entropy.h"
132#include "sh_html.h"
133#include "sh_mail.h"
134#include "sh_socket.h"
135#define SH_NEED_GETHOSTBYXXX
136#include "sh_static.h"
137
138#ifdef SH_ENCRYPT
139#include "rijndael-api-fst.h"
140char * sh_tools_makePack (unsigned char * header,
141 char * payload, int payload_size,
142 keyInstance * keyInstE);
143char * sh_tools_revertPack (unsigned char * header, char * message,
144 keyInstance * keyInstE,
145 unsigned long message_size);
146#endif
147
148/* define this if you want to debug the client/server communication */
149/* #define SH_DBG_PROT 1 */
150
151#ifdef SH_DBG_PROT
152#define SH_SHOWPROT(c,d) sh_tools_show_header((c), (d))
153#else
154#define SH_SHOWPROT(c,d)
155#endif
156
157/* the port client will be connecting to
158 */
159#ifndef SH_DEFAULT_PORT
160#define SH_DEFAULT_PORT 49777
161#endif
162
163#ifndef SH_SELECT_REPEAT
164#define SH_SELECT_REPEAT 60
165#endif
166
167#ifndef SH_HEADER_SIZE
168#define SH_HEADER_SIZE 7
169#endif
170
171#ifndef SH_CHALLENGE_SIZE
172#define SH_CHALLENGE_SIZE 9
173#endif
174
175#undef FIL__
176#define FIL__ _("sh_forward.c")
177
178int clt_class = (-1);
179
180extern int flag_err_debug;
181extern int flag_err_info;
182
183#ifndef SH_STANDALONE
184
185#if defined(WITH_TRACE) || defined(WITH_TPT)
186char * hu_trans(const char * ihu)
187{
188 static char ohu[17];
189 sprintf(ohu, _("%c%03o"), '\\', /* known to fit */
190 (unsigned char) ihu[0]);
191 sprintf(&(ohu[4]), _("%c%03o"), '\\', /* known to fit */
192 (unsigned char) ihu[1]);
193 sprintf(&(ohu[8]), _("%c%03o"), '\\', /* known to fit */
194 (unsigned char) ihu[2]);
195 sprintf(&(ohu[12]), _("%c%03o"), '\\', /* known to fit */
196 (unsigned char) ihu[3]);
197 ohu[16] = '\0';
198 return ohu;
199}
200#endif
201
202static int StripDomain = S_TRUE;
203
204int sh_forward_set_strip (char * str)
205{
206 static int fromcl = 0;
207 char dummy[2] = "F";
208
209 if (fromcl == 1)
210 return 0;
211
212 if (str == NULL)
213 {
214 fromcl = 1;
215 return (sh_util_flagval(dummy, &StripDomain));
216 }
217 else
218 return (sh_util_flagval(str, &StripDomain));
219}
220
221#include <ctype.h>
222
223const char * sh_strip_domain (char *name)
224{
225 char * first;
226 static char name_2[SH_MINIBUF+1];
227 register int i = 0;
228
229 SL_ENTER(_("sh_strip_domain"));
230
231 if (StripDomain == S_FALSE || (first = strchr(name, '.')) == NULL)
232 {
233 SL_RETURN( name, _("sh_strip_domain"));
234 }
235 else
236 {
237
238 /* check whether it is in dotted number format
239 * --> last part must be kept
240 */
241 if (0 != is_numeric(name))
242 {
243 SL_RETURN( name, _("sh_strip_domain"));
244 /*
245 i = sl_strlen(name) - 1;
246 while (name[i] != '.' && i >= 0)
247 --i;
248 if (name[i] == '.') ++i;
249 sl_strlcpy( name_2, &name[i], SH_MINIBUF +1 );
250 */
251 }
252 else
253 {
254 first = name;
255 while (i < SH_MINIBUF && *first != '.' && *first != '\0')
256 {
257 name_2[i] = *first;
258 ++first; ++i;
259 }
260 name_2[i] = '\0';
261 }
262 }
263
264 SL_RETURN( name_2, _("sh_strip_domain"));
265}
266
267/* #ifndef SH_STANDALONE */
268#endif
269
270#ifndef USE_SRP_PROTOCOL
271static
272void sh_passwd (char * salt, char * password, char * nounce, char *hash)
273{
274
275 char *combi;
276 size_t len;
277 register int i;
278 unsigned char * dez = NULL;
279
280 if (password == NULL)
281 dez = (unsigned char *) &(skey->pw[0]);
282 else if (sl_strlen(password) < PW_LEN)
283 {
284 fprintf(stderr, _("Password has less than %d chars !\n"),
285 PW_LEN);
286 _exit(EXIT_FAILURE);
287 }
288
289 if (password == NULL)
290 {
291 /* --- copy password ---
292 */
293 for (i = 0; i < PW_LEN; ++i)
294 {
295 skey->vernam[i] = (char)(*dez);
296 ++dez;
297 }
298 (void) sl_strlcpy (skey->vernam,
299 sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN),
300 KEY_LEN+1);
301 }
302 else
303 {
304 (void) sl_strlcpy (skey->vernam, password, KEY_LEN+1);
305 }
306
307 len = sl_strlen(salt) + sl_strlen(skey->vernam) + 1;
308 if (nounce != NULL)
309 len += sl_strlen(nounce);
310
311 /* H(s,P)
312 */
313 combi = SH_ALLOC(len);
314 (void) sl_strlcpy (combi, salt, len);
315 (void) sl_strlcat (combi, skey->vernam, len);
316 if (nounce != NULL)
317 (void) sl_strlcat (combi, nounce, len);
318 (void) sl_strlcpy (hash,
319 sh_tiger_hash(combi, TIGER_DATA,
320 (unsigned long) sl_strlen(combi)),
321 KEY_LEN+1);
322
323 /*
324 fprintf(stderr, "DD: A: <%s>\n", salt);
325 fprintf(stderr, "DD: P: <%s>\n", skey->pw);
326 fprintf(stderr, "DD: V: <%s>\n", skey->vernam);
327 fprintf(stderr, "DD: C: <%s>\n", combi);
328 fprintf(stderr, "DD: H: <%s>\n", hash);
329 */
330
331 SH_FREE (combi);
332 hash[KEY_LEN] = '\0';
333 return;
334}
335#endif
336
337#ifdef SH_WITH_CLIENT
338
339static int count_dev_server = 0;
340
341void reset_count_dev_server(void)
342{
343 count_dev_server = 0;
344 return;
345}
346
347int sh_forward_setlogserver (char * address)
348{
349 SL_ENTER(_("sh_forward_setlogserver"));
350
351 if (address != NULL && count_dev_server < 2
352 && sl_strlen(address) < SH_PATHBUF && sl_strlen(address) > 0)
353 {
354 if (count_dev_server == 0)
355 (void) sl_strlcpy (sh.srvexport.name, address, SH_PATHBUF);
356 else
357 (void) sl_strlcpy (sh.srvexport.alt, address, SH_PATHBUF);
358
359 ++count_dev_server;
360 SL_RETURN (0, _("sh_forward_setlogserver"));
361 }
362 SL_RETURN (-1, _("sh_forward_setlogserver"));
363}
364
365static
366int sh_forward_send_intern (int mysocket, char protocol, char * micro,
367 char * msgbuf, unsigned long length, int docrypt)
368{
369 unsigned long numbytes, countbytes;
370 int flag_err = 0;
371 unsigned char head[SH_HEADER_SIZE];
372 char * outbuf;
373
374#ifdef SH_ENCRYPT
375
376 unsigned long blkfac;
377 int rem;
378 unsigned long length2;
379 char * msg2buf = NULL;
380 char * p, * q;
381 RIJ_BYTE inBlock[B_SIZ];
382 RIJ_BYTE outBlock[B_SIZ];
383 unsigned long j;
384 cipherInstance cipherInst;
385 int err_num;
386#else
387 docrypt = SL_FALSE; /* dummy to fix compiler warning */
388#endif
389
390 SL_ENTER(_("sh_forward_send_intern"));
391
392#ifdef SH_ENCRYPT
393 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != (char)0))
394 {
395 put_header (head, (int)protocol, &length, micro);
396 msg2buf = sh_tools_makePack (head, msgbuf, (int) length,
397 &(skey->keyInstE));
398 /*@-usedef@*/
399 length = (unsigned long) (256 * (unsigned int)head[1] +
400 (unsigned int)head[2]);
401 /*@+usedef@*/
402 outbuf = msg2buf;
403 }
404 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != (char)0))
405 {
406 blkfac = length/B_SIZ;
407 rem = (int) (length - (B_SIZ * blkfac));
408 length2 = (B_SIZ * blkfac) + ((rem == 0) ? 0 : B_SIZ);
409
410 msg2buf = SH_ALLOC((size_t)length2);
411 p = msgbuf;
412 q = msg2buf;
413
414 err_num = cipherInit (&cipherInst, (RIJ_BYTE)MODE_CBC, NULL);
415
416 if (err_num < 0)
417 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
418 errorExplain(err_num),
419 _("sh_forward_send_intern: cipherInit"));
420
421
422 for (j = 0; j < blkfac; ++j)
423 {
424 memcpy(inBlock, p, B_SIZ);
425 err_num = blockEncrypt(&cipherInst, &(skey->keyInstE),
426 inBlock, 128 * BNUM, outBlock);
427 if (err_num < 0)
428 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
429 errorExplain(err_num),
430 _("sh_forward_send_intern: blockEncrypt"));
431 memcpy(q, outBlock, B_SIZ);
432 p += B_SIZ;
433 q += B_SIZ;
434 }
435 if (rem > 0)
436 {
437 memset(inBlock, 0, B_SIZ);
438 memcpy(inBlock, p, (size_t)rem);
439 err_num = blockEncrypt(&cipherInst, &(skey->keyInstE),
440 inBlock, 128 * BNUM, outBlock);
441 if (err_num < 0)
442 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
443 errorExplain(err_num),
444 _("sh_forward_send_intern: blockEncrypt"));
445 memcpy(q, outBlock, B_SIZ);
446 q += B_SIZ;
447 }
448
449 outbuf = msg2buf;
450 length = length2;
451 put_header (head, (int)protocol, &length, micro);
452 }
453 else
454 {
455 outbuf = msgbuf;
456 put_header (head, (int)protocol, &length, micro);
457 }
458#else
459 outbuf = msgbuf;
460 put_header (head, (int)protocol, &length, micro);
461#endif
462
463 SH_SHOWPROT(head,'>');
464
465 numbytes = SH_HEADER_SIZE;
466 countbytes = write_port (mysocket,
467 (char *) head, numbytes,
468 &flag_err, 300);
469
470 if (countbytes == numbytes && outbuf != NULL)
471 {
472 numbytes = (length);
473 countbytes = write_port (mysocket,
474 outbuf, numbytes,
475 &flag_err, 300);
476 }
477
478#ifdef SH_ENCRYPT
479 /*@-usedef@*/
480 if (msg2buf != NULL)
481 SH_FREE(msg2buf);
482 /*@+usedef@*/
483#endif
484
485 if (countbytes == numbytes)
486 {
487 SL_RETURN( 0, _("sh_forward_send_intern"));
488 }
489 else
490 {
491 SL_RETURN( flag_err, _("sh_forward_send_intern"));
492 }
493}
494static
495int sh_forward_send (int mysocket, char protocol, char * micro,
496 char * msgbuf, unsigned long length)
497{
498 int i;
499 SL_ENTER(_("sh_forward_send"));
500 TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
501 i = sh_forward_send_intern (mysocket, protocol, micro,
502 msgbuf, length, S_FALSE);
503 SL_RETURN(i, _("sh_forward_send"));
504}
505static
506int sh_forward_send_crypt (int mysocket, char protocol, char * micro,
507 char * msgbuf, unsigned long length)
508{
509 int i;
510 SL_ENTER(_("sh_forward_send_crypt"));
511#ifdef SH_ENCRYPT
512 TPT(( 0, FIL__, __LINE__, _("msg=<Send encrypted.>\n")));
513#else
514 TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
515#endif
516 i = sh_forward_send_intern (mysocket, protocol, micro,
517 msgbuf, length, S_TRUE);
518 SL_RETURN(i, _("sh_forward_send_crypt"));
519}
520
521
522/* receive answer, add a trailing NULL to terminate string
523 * rev 0.8
524 */
525static
526long sh_forward_receive_intern (int mysocket, char protocol, char * micro,
527 char * msgbuf, unsigned long length,
528 int docrypt)
529{
530 unsigned long numbytes, countbytes;
531 int flag_err = -1;
532 unsigned char head[SH_HEADER_SIZE];
533
534#ifdef SH_ENCRYPT
535
536 unsigned long head_length;
537 unsigned long blkfac;
538 /* unsigned long length2; */
539 char * p, * q, * tmp;
540 RIJ_BYTE inBlock[B_SIZ];
541 RIJ_BYTE outBlock[B_SIZ];
542 unsigned long j;
543 cipherInstance cipherInst;
544 int err_num;
545#else
546 docrypt = SL_FALSE; /* dummy to fix compiler warning */
547#endif
548
549 SL_ENTER(_("sh_forward_receive_intern"));
550
551 if (micro != NULL)
552 micro[4] = '\0';
553
554 if (msgbuf != NULL)
555 msgbuf[0] = '\0';
556
557 numbytes = SH_HEADER_SIZE;
558 countbytes = read_port (mysocket,
559 (char *) head, numbytes,
560 &flag_err, 300);
561
562 if (countbytes != numbytes)
563 {
564 TPT(( 0, FIL__, __LINE__, _("msg=<countbytes != numbytes>\n")));
565 SL_RETURN(flag_err, _("sh_forward_receive_intern"));
566 }
567 /*@-usedef +ignoresigns@*/
568 else if (head[0] != protocol &&
569 (head[0] & SH_PROTO_SRP) == (char)0 /* not set */)
570 {
571 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISMATCH);
572 SL_RETURN((-1), _("sh_forward_receive_intern"));
573 }
574 /*@+usedef -ignoresigns@*/
575 else
576 {
577 get_header (head, &numbytes, micro);
578 SH_SHOWPROT(head, '<');
579
580 if (numbytes > 0)
581 {
582 numbytes = (numbytes > length ? length : numbytes);
583
584 countbytes = read_port (mysocket,
585 msgbuf, numbytes,
586 &flag_err, 300);
587
588 if (countbytes < length)
589 msgbuf[countbytes] = '\0';
590 else
591 msgbuf[length-1] = '\0';
592
593 if (flag_err != 0)
594 {
595 TPT(( 0, FIL__, __LINE__, _("msg=<read error>\n")));
596 SL_RETURN((-1), _("sh_forward_receive_intern"));
597 }
598 }
599 }
600
601#ifdef SH_ENCRYPT
602 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != (char)0))
603 {
604 tmp = SH_ALLOC((size_t)length);
605 memcpy(tmp, msgbuf, (size_t)length);
606 tmp = sh_tools_revertPack (head, tmp, &(skey->keyInstD), countbytes);
607
608 head_length = (unsigned long) (256 * (unsigned int)head[1] +
609 (unsigned int)head[2]);
610 head_length = (head_length > length ? length : head_length);
611 length = head_length;
612
613 memcpy(msgbuf, tmp, (size_t)length);
614 msgbuf[length] = '\0';
615 SH_FREE(tmp);
616 if (countbytes == numbytes)
617 {
618 countbytes = length; /* to avoid error on return, see below */
619 }
620 numbytes = length;
621 }
622 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != (char)0))
623 {
624 /* Decrypt only complete blocks. If there is an incomplete block,
625 * something is wrong anyway.
626 * Decrypt in place.
627 */
628 blkfac = countbytes/B_SIZ;
629 /* length2 = (B_SIZ * blkfac); */
630 p = msgbuf;
631 q = msgbuf;
632
633 err_num = cipherInit (&cipherInst, (RIJ_BYTE)MODE_CBC, NULL);
634
635 if (err_num < 0)
636 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
637 errorExplain(err_num),
638 _("sh_forward_receive_intern: cipherInit"));
639
640 for (j = 0; j < blkfac; ++j)
641 {
642 memcpy(inBlock, p, B_SIZ);
643 err_num = blockDecrypt(&cipherInst, &(skey->keyInstD),
644 inBlock, 128 * BNUM, outBlock);
645 if (err_num < 0)
646 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
647 errorExplain(err_num),
648 _("sh_forward_receive_intern: blockDecrypt"));
649 memcpy(q, outBlock, B_SIZ);
650 p += 16;
651 q += 16;
652 }
653 }
654#endif
655
656 if (countbytes == numbytes)
657 {
658 SL_RETURN(((long)numbytes), _("sh_forward_receive_intern"));
659 }
660 else
661 {
662 TPT(( 0, FIL__, __LINE__, _("msg=<short read>\n")));
663 SL_RETURN(flag_err, _("sh_forward_receive_intern"));
664 }
665}
666
667static
668long sh_forward_receive (int mysocket, char protocol, char * micro,
669 char * msgbuf, unsigned long length)
670{
671 long i;
672 SL_ENTER(_("sh_forward_receive"));
673 TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
674 i = sh_forward_receive_intern (mysocket, protocol, micro,
675 msgbuf, length, S_FALSE);
676 SL_RETURN(i, _("sh_forward_receive"));
677}
678
679static
680long sh_forward_receive_crypt (int mysocket, char protocol, char * micro,
681 char * msgbuf, unsigned long length)
682{
683 long i;
684 SL_ENTER(_("sh_forward_receive_crypt"));
685#ifdef SH_ENCRYPT
686 TPT(( 0, FIL__, __LINE__, _("msg=<Receive encrypted.>\n")));
687#else
688 TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
689#endif
690 i = sh_forward_receive_intern (mysocket, protocol, micro,
691 msgbuf, length, S_TRUE);
692 SL_RETURN(i, _("sh_forward_receive"));
693}
694
695/**************************************************
696 *
697 *
698 * C L I E N T
699 *
700 *
701 ***************************************************/
702
703
704#include <time.h>
705
706static SH_FIFO * fifo = NULL;
707
708static long sh_forward_try (char * errmsg);
709
710
711long sh_forward (char * errmsg)
712{
713 static int have_server = GOOD;
714 long status;
715 char * popmsg;
716 static int failed = GOOD;
717
718 SL_ENTER(_("sh_forward"));
719
720 /* --- No log server available. ---
721 */
722 if (have_server == GOOD && sh.srvexport.name[0] == '\0')
723 {
724 have_server = BAD;
725 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NONAME);
726 SL_RETURN (-1, _("sh_forward"));
727 }
728 else if (have_server == BAD)
729 {
730 SL_RETURN (-1, _("sh_forward"));
731 }
732
733 /* --- Allocate fifo. ---
734 */
735 if (fifo == NULL)
736 {
737 fifo = SH_ALLOC(sizeof(SH_FIFO));
738 fifo_init(fifo);
739 }
740
741 /* --- Check for messages on the queue, and send them first. ---
742 */
743 while (NULL != (popmsg = pop_list(fifo)) )
744 {
745 status = sh_forward_try (popmsg);
746 if (status != 0)
747 {
748 (void) push_tail_list (fifo, popmsg);
749 SH_FREE(popmsg);
750 if (SH_FIFO_MAX == push_list (fifo, errmsg))
751 {
752 SL_RETURN (-2, _("sh_forward"));
753 }
754 SL_RETURN (-1, _("sh_forward"));
755 }
756 SH_FREE(popmsg);
757 }
758
759 /* --- Now send the error message. ---
760 */
761 status = sh_forward_try (errmsg);
762 if (status != 0)
763 {
764 if (failed == GOOD)
765 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
766 _("log server"),
767 sh.srvexport.name);
768 failed = BAD;
769 if (SH_FIFO_MAX == push_list (fifo, errmsg)) /* push message on stack */
770 {
771 SL_RETURN (-2, _("sh_forward"));
772 }
773 SL_RETURN (-1, _("sh_forward"));
774 }
775
776 failed = GOOD;
777 SL_RETURN (0, _("sh_forward"));
778}
779
780static long sh_forward_try_impl (char * errmsg, char what);
781
782static long sh_forward_try (char * errmsg)
783{
784 long i;
785 SL_ENTER(_("sh_forward_try"));
786 i = sh_forward_try_impl (errmsg, (char)SH_PROTO_MSG);
787 SL_RETURN(i, _("sh_forward_try"));
788}
789
790long sh_forward_req_file (char * file)
791{
792 long i;
793 char tmp_file[8];
794 SL_ENTER(_("sh_forward_req_file"));
795 (void) sl_strlcpy(tmp_file, file, 8);
796 i = sh_forward_try_impl (tmp_file, (char)SH_PROTO_BIG);
797 SL_RETURN(i, _("sh_forward_req_file"));
798}
799
800static long sh_forward_try_impl (char * errmsg, char what)
801{
802 static int initialized = BAD;
803 static int conn_state = GOOD;
804 int sockfd;
805 int flag_err;
806 char * answer;
807
808 unsigned char theProto;
809
810 char hash[KEY_LEN+1];
811 size_t len;
812 char * buffer;
813#ifdef SH_ENCRYPT_2
814 size_t pos; /* for the server command */
815#endif
816 char head_u[5];
817
818 char nsrv[KEY_LEN+1];
819 char nclt[KEY_LEN+1];
820 SL_TICKET sfd = -1;
821 int transfercount;
822
823 char foo_M1[KEY_LEN+1];
824 UINT32 ticks;
825
826 char error_msg[256];
827 char error_call[SH_MINIBUF];
828 int error_num = 0;
829
830#ifdef USE_SRP_PROTOCOL
831 char u_real[SH_CHALLENGE_SIZE];
832 char * foo_A;
833 char * foo_Sc;
834 char * M;
835#else
836 char nounce[KEY_LEN+1];
837 char temp[2*KEY_LEN+1];
838 char nonce_u[KEY_LEN+1];
839#endif
840
841#ifdef SH_ENCRYPT
842 int err_num;
843#endif
844
845 static time_t time_now = 1200;
846 static time_t time_last = 0;
847
848 static time_t timeout_val = 1;
849
850 SL_ENTER(_("sh_forward_try_impl"));
851
852 /* --- No message to transmit. ---
853 */
854 if (errmsg == NULL && initialized == GOOD)
855 SL_RETURN( 0, _("sh_forward_try_impl"));
856
857 /* --- Connection in bad state. ---
858 */
859 if (initialized == BAD || conn_state == BAD)
860 {
861 timeout_val =
862 (time_t)((timeout_val > TIMEOUT_CON) ? TIMEOUT_CON : timeout_val);
863
864 /* --- Retry bad attempt only after some time. ---
865 */
866 time_now = time (NULL);
867 if ((time_now - time_last) < timeout_val)
868 {
869 TPT(( 0, FIL__, __LINE__, _("msg=<Within deadtime, no retry.>\n")));
870 SL_RETURN( (-1), _("sh_forward_try_impl"));
871 }
872 TPT(( 0, FIL__, __LINE__, _("msg=<Retry.>\n")));
873 }
874 time_last = time (NULL);
875
876
877 /* --- Try to connect to log server. ---
878 */
879 error_call[0] = '\0';
880
881 sockfd = connect_port_2 (sh.srvexport.name, sh.srvexport.alt,
882 SH_DEFAULT_PORT,
883 error_call, &error_num, error_msg, 256);
884
885 if (sockfd < 0)
886 {
887 conn_state = BAD;
888 timeout_val *= 2;
889 sh_error_handle ((-1), FIL__, __LINE__, error_num,
890 MSG_E_NET, error_msg, error_call,
891 _("export"), sh.srvexport.name);
892 SL_RETURN( (-1), _("sh_forward_try_impl"));
893 }
894
895 conn_state = GOOD;
896
897 /*************************
898 *
899 * initialization
900 *
901 */
902
903 flag_err = 0;
904 answer = SH_ALLOC(512);
905 MLOCK(answer, 512);
906
907
908#ifndef USE_SRP_PROTOCOL
909
910 /**************************************************
911 *
912 * --- challenge/response authentication ---
913 *
914 **************************************************/
915
916 if (initialized == BAD)
917 {
918 theProto = (unsigned char) SH_PROTO_SRP;
919
920 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: entry>\n")));
921
922 (void) sl_strlcpy (answer, sh.host.name, 512);
923
924 flag_err = sh_forward_send (sockfd, (char) theProto, _("SALT"),
925 answer, (unsigned long)sl_strlen(answer));
926
927 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent SALT, flag_err = %d>\n"),
928 flag_err));
929
930 /* get nonce from server
931 */
932 if (flag_err == 0)
933 {
934 flag_err = (int) sh_forward_receive (sockfd, (char)theProto, head_u,
935 answer, 511);
936 flag_err = (flag_err < 0) ? flag_err : 0;
937 TPT(( 0, FIL__, __LINE__,
938 _("msg=<c/r: rcvt nonce, flag_err = %d>\n"),
939 flag_err));
940 }
941
942 /* entry point for jump from message forward if session key must
943 * be re-initialized
944 */
945 initBlock:
946
947 if (0 == check_request (head_u, _("INIT")) &&
948 flag_err == 0 &&
949 sl_strlen(answer) > KEY_LEN )
950 (void) sl_strlcpy(nounce, &answer[KEY_LEN], KEY_LEN+1);
951 else
952 flag_err = (-1);
953
954 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: rcvt INIT, flag_err = %d>\n"),
955 flag_err));
956
957 /* verify random nonce v from server H(v, P)v
958 */
959 sh_passwd (nounce, NULL, NULL, temp);
960 if ( 0 != sl_strncmp(temp, answer, KEY_LEN))
961 flag_err = (-1);
962
963 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: vrfy nonce, flag_err = %d>\n"),
964 flag_err));
965
966
967 /* --- Create own nonce. ---
968 */
969 ticks = (UINT32) taus_get (&(skey->rng0[0]),
970 &(skey->rng1[0]),
971 &(skey->rng2[0]));
972 (void) sl_strlcpy(nonce_u,
973 sh_tiger_hash((char *) &ticks,
974 TIGER_DATA,
975 (unsigned long)sizeof(UINT32)),
976 KEY_LEN+1);
977
978 /* --- Form the message H(H(u,v),P)u ---
979 */
980 (void) sl_strlcpy(temp, nonce_u, 2*KEY_LEN+1);
981 (void) sl_strlcat(temp, nounce, 2*KEY_LEN+1);
982 (void) sl_strlcpy(temp,
983 sh_tiger_hash(temp,
984 TIGER_DATA,
985 (unsigned long)sl_strlen(temp)),
986 KEY_LEN+1);
987 sh_passwd (temp, NULL, NULL, foo_M1);
988 (void) sl_strlcpy(temp, foo_M1, 2*KEY_LEN+1);
989 (void) sl_strlcat(temp, nonce_u, 2*KEY_LEN+1);
990
991 /* --- Send it to server. ---
992 */
993 if (flag_err == 0)
994 {
995 flag_err = (int) sh_forward_send (sockfd,
996 (char)(theProto|SH_PROTO_SRP),
997 _("PASS"), temp,
998 (unsigned long)sl_strlen(temp));
999 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent PASS, flag_err = %d>\n"),
1000 flag_err));
1001 }
1002
1003 if (flag_err == 0)
1004 {
1005 flag_err = (int)sh_forward_receive (sockfd,
1006 (char)(theProto|SH_PROTO_SRP),
1007 head_u, answer, 511);
1008 sh_passwd (nounce, NULL, nonce_u, foo_M1);
1009 (void) sl_strlcpy (skey->session, foo_M1, KEY_LEN+1);
1010#ifdef SH_ENCRYPT
1011 err_num = makeKey(&(skey->keyInstE),
1012 (RIJ_BYTE)DIR_ENCRYPT, 192, skey->session);
1013 if (err_num < 0)
1014 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1015 errorExplain(err_num),
1016 _("sh_forward_try_impl: makeKey"));
1017
1018 err_num = makeKey(&(skey->keyInstD),
1019 (RIJ_BYTE)DIR_DECRYPT, 192, skey->session);
1020 if (err_num < 0)
1021 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
1022 errorExplain(err_num),
1023 _("sh_forward_try_impl: make_key"));
1024#endif
1025 initialized = GOOD;
1026 }
1027
1028 if (initialized == BAD)
1029 {
1030 timeout_val *= 2;
1031 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
1032 memset(answer, 0, sizeof(answer));
1033 MUNLOCK(answer, 512);
1034 SH_FREE(answer);
1035 SL_RETURN( (-1), _("sh_forward_try_impl"));
1036 }
1037 else
1038 {
1039 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
1040 }
1041 }
1042
1043#else
1044
1045
1046 /* This is the SRP authenticated key exchange protocol.
1047 * Produces a session key skey->session.
1048 */
1049 if (initialized == BAD)
1050 {
1051 TPT(( 0, FIL__, __LINE__, _("msg=<srp: entry>\n")));
1052
1053 theProto = SH_PROTO_SRP;
1054
1055 sl_strlcpy (answer, sh.host.name, 512);
1056 flag_err = sh_forward_send (sockfd, theProto, _("SALT "),
1057 answer, sl_strlen(answer));
1058
1059 TPT(( 0, FIL__, __LINE__, _("msg=<srp: sent SALT, flag_err = %d>\n"),
1060 flag_err));
1061
1062 if (flag_err == 0)
1063 {
1064 flag_err = sh_forward_receive (sockfd, theProto, head_u,
1065 answer, 511);
1066 flag_err = (flag_err < 0) ? flag_err : 0;
1067 TPT(( 0, FIL__, __LINE__,
1068 _("msg=<srp: rcvt nonce, flag_err = %d>\n"),
1069 flag_err));
1070 }
1071
1072 /* Entry point for jump from message forward if session key must
1073 * be re-initialized.
1074 */
1075 initBlock:
1076 TPT(( 0, FIL__, __LINE__, _("msg=<srp: INIT>\n")));
1077
1078 if (flag_err == 0 &&
1079 (0 == check_request (head_u, _("INIT"))))
1080 {
1081 if (0 != sh_srp_init())
1082 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EBGN);
1083 else /* if (0 == sh_srp_init()) */
1084 {
1085 TPT(( 0, FIL__, __LINE__, _("msg=<srp: bignum initialized>\n")));
1086
1087 sh_srp_x (answer, NULL); /* x password */
1088 sh_srp_make_a (); /* a random number */
1089 foo_A = sh_srp_A(); /* g^a */
1090
1091 TPT(( 0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), foo_A));
1092
1093 if (foo_A == NULL)
1094 flag_err = (-1);
1095
1096 if (flag_err == 0)
1097 flag_err = sh_forward_send (sockfd,
1098 (theProto|SH_PROTO_SRP),
1099 _("PC01"),
1100 foo_A, sl_strlen(foo_A)+1);
1101 if (flag_err == 0)
1102 {
1103 flag_err = sh_forward_receive (sockfd,
1104 (theProto|SH_PROTO_SRP),
1105 head_u,
1106 answer, 511);
1107 flag_err = (flag_err < 0) ? flag_err : 0;
1108 TPT(( 0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), answer));
1109 TPT(( 0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), head_u[0], head_u[1], head_u[2], head_u[3]));
1110 }
1111
1112 /* u nounce */
1113 /* B answer */
1114 /* S = (B-g^x)^(a+ux) */
1115
1116 if (flag_err == 0)
1117 {
1118 if (0 != sh_srp_check_zero (answer))
1119 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EZERO);
1120 else /* if (0 != sh_srp_check_zero (answer)) */
1121 {
1122 sl_strlcpy(u_real, sh_tiger_hash(head_u, TIGER_DATA, 4),
1123 SH_CHALLENGE_SIZE);
1124 foo_Sc = sh_srp_S_c (u_real, answer);
1125
1126 TPT(( 0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
1127 u_real));
1128 TPT(( 0, FIL__, __LINE__, _("msg=<srp:Sc = %s>\n"),
1129 foo_Sc));
1130
1131 /* --- Now send H(A,B,H(Sc)) and check. ---
1132 */
1133 if (foo_Sc != NULL)
1134 {
1135 sl_strlcpy(foo_M1,
1136 sh_srp_M(foo_A,
1137 answer,
1138 sh_tiger_hash(foo_Sc,
1139 TIGER_DATA,
1140 sl_strlen(foo_Sc))),
1141 KEY_LEN+1);
1142
1143 TPT(( 0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),
1144 foo_M1));
1145
1146 flag_err = sh_forward_send(sockfd,
1147 (theProto|SH_PROTO_SRP),
1148 _("PC02"),
1149 foo_M1, KEY_LEN+1);
1150 }
1151 else
1152 {
1153 flag_err = (-1);
1154 }
1155
1156 if (flag_err == 0)
1157 {
1158 flag_err =sh_forward_receive(sockfd,
1159 (theProto|SH_PROTO_SRP),
1160 head_u,
1161 answer, 511);
1162 flag_err = (flag_err < 0) ? flag_err : 0;
1163 TPT(( 0, FIL__, __LINE__, _("msg=<srp: M = %s>\n"),
1164 answer));
1165 }
1166
1167 if (flag_err == 0 &&
1168 (0 == check_request (head_u, _("PARP"))))
1169 {
1170 /* ------ verify M2 = H(A, M1, K) --------
1171 */
1172 M = sh_srp_M (foo_A, foo_M1,
1173 sh_tiger_hash(foo_Sc,
1174 TIGER_DATA,
1175 sl_strlen(foo_Sc)));
1176 if (M != NULL &&
1177 0 == sl_strncmp (answer, M, KEY_LEN+1))
1178 {
1179 sl_strlcpy (skey->session,
1180 sh_tiger_hash(foo_Sc,
1181 TIGER_DATA,
1182 sl_strlen(foo_Sc)),
1183 KEY_LEN+1);
1184 TPT(( 0, FIL__, __LINE__,
1185 _("msg=<srp: Key = %s>\n"),
1186 skey->session));
1187
1188#ifdef SH_ENCRYPT
1189 err_num = makeKey(&(skey->keyInstE),
1190 DIR_ENCRYPT,
1191 192, skey->session);
1192 if (err_num < 0)
1193 sh_error_handle((-1), FIL__, __LINE__, -1,
1194 MSG_E_SUBGEN,
1195 errorExplain(err_num),
1196 _("sh_forward_try_impl: makeKey"));
1197 err_num = makeKey(&(skey->keyInstD),
1198 DIR_DECRYPT,
1199 192, skey->session);
1200 if (err_num < 0)
1201 sh_error_handle((-1), FIL__, __LINE__, -1,
1202 MSG_E_SUBGEN,
1203 errorExplain(err_num),
1204 _("sh_forward_try_impl: makeKey"));
1205#endif
1206 initialized = GOOD;
1207 }
1208 }
1209 if (foo_Sc != NULL)
1210 SH_FREE(foo_Sc);
1211 }
1212 }
1213 if (foo_A != NULL)
1214 SH_FREE(foo_A);
1215 sh_srp_exit();
1216 }
1217 }
1218
1219 if (initialized == BAD)
1220 {
1221 timeout_val *= 2;
1222 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
1223 memset(answer, '\0', sizeof(answer));
1224 MUNLOCK(answer, 512);
1225 SH_FREE(answer);
1226 SL_RETURN( (-1), _("sh_forward_try_impl"));
1227 }
1228 else
1229 {
1230 if (flag_err_info == SL_TRUE)
1231 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
1232 }
1233 }
1234
1235#endif
1236
1237 /* no message, just session key negotiated
1238 */
1239 if (errmsg == NULL)
1240 {
1241 timeout_val = 1;
1242 memset(answer, 0, sizeof(answer));
1243 MUNLOCK(answer, 512);
1244 SH_FREE(answer);
1245 TPT(( 0, FIL__, __LINE__, _("msg=<No message.>\n")));
1246 SL_RETURN( (0), _("sh_forward_try_impl"));
1247 }
1248 else if (what == (char)SH_PROTO_BIG)
1249 {
1250 MUNLOCK(answer, 512);
1251 SH_FREE (answer);
1252 answer = SH_ALLOC(TRANS_BYTES + 256);
1253 MLOCK(answer, TRANS_BYTES + 256);
1254 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer.>\n")));
1255 }
1256
1257
1258 (void) sl_strlcpy (answer, sh_util_siggen(skey->session,
1259 sh.host.name,
1260 sl_strlen(sh.host.name)),
1261 KEY_LEN+1);
1262 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"), sh.host.name));
1263 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"), skey->session));
1264 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), answer));
1265
1266
1267 (void) sl_strlcat (answer, sh.host.name, 512);
1268
1269 TPT((0, FIL__, __LINE__, _("msg=<mesg %s>\n"), answer));
1270
1271 /***********************************************
1272 *
1273 * send the message
1274 *
1275 */
1276
1277 if (what == (char) SH_PROTO_MSG)
1278 {
1279 theProto = (unsigned char)SH_PROTO_MSG;
1280
1281 /* say HELO
1282 */
1283
1284 flag_err = sh_forward_send (sockfd,
1285 (char)theProto, _("HELO"),
1286 answer,
1287 (unsigned long)sl_strlen(answer));
1288 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1289 answer, flag_err));
1290 if (flag_err == 0)
1291 {
1292 /* --- Get challenge. ---
1293 */
1294 flag_err = (int) sh_forward_receive (sockfd,
1295 (char)SH_PROTO_MSG, head_u,
1296 answer, 255);
1297 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s, u %s, status %d.>\n"),
1298 answer, hu_trans(head_u), flag_err));
1299 flag_err = (flag_err < 0) ? flag_err : 0;
1300
1301 if (flag_err == 0)
1302 {
1303
1304 /* --- Re-negotiate key. ---
1305 */
1306 if (0 == check_request_nerr(head_u, _("INIT")))
1307 {
1308 flag_err = 0;
1309 initialized = BAD;
1310 goto initBlock;
1311 }
1312
1313 else if (0 == check_request(head_u, _("TALK")))
1314 {
1315
1316 /* --- Save the challenge. ---
1317 */
1318 (void) sl_strlcpy(nsrv, answer, KEY_LEN + 1);
1319
1320 /* --- Hash(msg,challenge,sessionkey). ---
1321 */
1322 len = sl_strlen(errmsg) + sl_strlen(answer)
1323 + KEY_LEN + 1;
1324 len = (size_t)((len < 256) ? 256 : len);
1325 buffer = SH_ALLOC(len);
1326 MLOCK(buffer, len);
1327 (void) sl_strlcpy(buffer, errmsg, len);
1328 (void) sl_strlcat(buffer, answer, len);
1329 (void) sl_strlcpy(hash,
1330 sh_util_siggen (skey->session,
1331 buffer,
1332 sl_strlen(buffer)),
1333 KEY_LEN+1);
1334 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1335 sh_util_siggen(skey->session, buffer,
1336 sl_strlen(buffer))));
1337
1338 (void) sl_strlcpy(buffer, errmsg, len);
1339 (void) sl_strlcat(buffer, hash, len);
1340
1341 flag_err =
1342 sh_forward_send_crypt (sockfd,
1343#ifdef SH_ENCRYPT
1344#ifdef SH_ENCRYPT_2
1345 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_EN2),
1346#else
1347 (char)(SH_PROTO_MSG|SH_PROTO_ENC),
1348#endif
1349#else
1350 (char)(SH_PROTO_MSG),
1351#endif
1352 _("MESG"),
1353 buffer,
1354 (unsigned long)(sl_strlen(buffer)+1));
1355 TPT(( 0, FIL__, __LINE__,
1356 _("msg=<Sent %s, status %d.>\n"),
1357 answer, flag_err));
1358
1359 /* --- Get confirmation. ---
1360 */
1361 if (flag_err == 0)
1362 {
1363 flag_err = (int)
1364 sh_forward_receive_crypt (sockfd,
1365#ifdef SH_ENCRYPT
1366#ifdef SH_ENCRYPT_2
1367 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_EN2|SH_PROTO_END),
1368#else
1369 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_END),
1370#endif
1371#else
1372 (char)(SH_PROTO_MSG|SH_PROTO_END),
1373#endif
1374 head_u,
1375 answer, 255);
1376 TPT(( 0, FIL__, __LINE__,
1377 _("msg=<Rcvt %s, u %s, status %d.>\n"),
1378 answer, hu_trans(head_u), flag_err));
1379 flag_err = (flag_err < 0) ? flag_err : 0;
1380 }
1381
1382
1383 /* --- Check confirmation. ---
1384 */
1385 if (flag_err == 0)
1386 {
1387 /* CLIENT CONF RECV
1388 *
1389 * first KEY_LEN bytes must be
1390 * sig(skey->session (errmsg nsrv))
1391 *
1392 */
1393 (void) sl_strlcpy(buffer, errmsg, len);
1394 (void) sl_strlcat(buffer, nsrv, len);
1395 flag_err = sl_strncmp(answer,
1396 sh_util_siggen(skey->session,
1397 buffer,
1398 sl_strlen(buffer)),
1399 KEY_LEN);
1400 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1401 sh_util_siggen(skey->session, buffer,
1402 sl_strlen(buffer))));
1403
1404 if (flag_err != 0)
1405 {
1406#ifdef ENOMSG
1407 flag_err = ENOMSG;
1408#else
1409 flag_err = EIO;
1410#endif
1411 sh_error_handle((-1), FIL__, __LINE__, flag_err,
1412 MSG_TCP_NOCONF);
1413 }
1414 else
1415 {
1416#ifdef SH_ENCRYPT_2
1417 /* --- SERVER CMD --- */
1418 if (answer[KEY_LEN] != '\0' &&
1419 sl_strlen(answer) > (2*KEY_LEN))
1420 {
1421 pos = sl_strlen(answer) - (2*KEY_LEN);
1422 /*
1423 * buffer is >= 256
1424 * answer has <= 255 bytes
1425 */
1426 (void) sl_strlcpy(buffer, &answer[KEY_LEN],
1427 pos+1);
1428 flag_err =
1429 sl_strncmp(&answer[KEY_LEN+pos],
1430 sh_util_siggen(skey->session,
1431 buffer,
1432 pos),
1433 KEY_LEN);
1434
1435 TPT((0, FIL__, __LINE__,
1436 _("CONF RECV <%d> <%s>\n"),
1437 flag_err, &answer[KEY_LEN]));
1438
1439 if (flag_err != 0) {
1440 sh_error_handle((-1), FIL__, __LINE__,
1441 flag_err,
1442 MSG_TCP_NOCONF);
1443 } else {
1444 sh_socket_server_cmd(buffer);
1445 }
1446 flag_err = 0;
1447
1448 } else {
1449
1450 TPT((0, FIL__, __LINE__,
1451 _("CONF RECV <0> <[null]>\n")));
1452
1453 }
1454 /* --- SERVER CMD END --- */
1455#endif
1456 if (flag_err_debug == SL_TRUE)
1457 sh_error_handle((-1), FIL__, __LINE__, 0,
1458 MSG_TCP_CONF);
1459 }
1460 }
1461
1462 memset(buffer, 0, len);
1463 MUNLOCK(buffer, len);
1464 SH_FREE(buffer);
1465 }
1466 else
1467 {
1468 /* --- Unexpected reply from server. ---
1469 */
1470 sh_error_handle((-1), FIL__, __LINE__, 0,
1471 MSG_TCP_UNEXP);
1472 flag_err = (-1);
1473 }
1474 }
1475 }
1476 }
1477
1478
1479 else if (what == (char)SH_PROTO_BIG)
1480 {
1481 theProto = (unsigned char) SH_PROTO_BIG;
1482
1483 /* --- Say HELO ---
1484 */
1485 flag_err = sh_forward_send (sockfd, (char) theProto, _("HELO"),
1486 answer, (unsigned long)sl_strlen(answer));
1487 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1488 answer, flag_err));
1489
1490 if (flag_err == 0)
1491 {
1492 /* --- Get NSRV. ---
1493 */
1494 flag_err = (int) sh_forward_receive (sockfd,
1495 (char)SH_PROTO_BIG, head_u,
1496 answer, 255);
1497 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s, u %s, status %d.>\n"),
1498 answer, hu_trans(head_u), flag_err));
1499 flag_err = (flag_err < 0) ? flag_err : 0;
1500 }
1501
1502 if (flag_err == 0)
1503 {
1504
1505 /* --- Re-negotiate key. ---
1506 */
1507 if (0 == check_request_nerr(head_u, _("INIT")))
1508 {
1509 flag_err = 0;
1510 initialized = BAD;
1511 goto initBlock;
1512 }
1513
1514
1515 else if (0 == check_request(head_u, _("NSRV")))
1516 {
1517#ifdef SH_ENCRYPT
1518 /* --- Set encryption flag. ---
1519 */
1520#ifdef SH_ENCRYPT_2
1521 theProto =
1522 (unsigned char)(SH_PROTO_BIG | SH_PROTO_ENC | SH_PROTO_EN2);
1523#else
1524 theProto = (unsigned char)(SH_PROTO_BIG | SH_PROTO_ENC);
1525#endif
1526#endif
1527
1528 (void) sl_strlcpy(nsrv, answer, KEY_LEN+1);
1529
1530 /* --- Generate a nonce. ---
1531 */
1532 ticks = (UINT32) taus_get (&(skey->rng0[0]),
1533 &(skey->rng1[0]),
1534 &(skey->rng2[0]));
1535
1536 (void) sl_strlcpy(nclt,
1537 sh_tiger_hash((char *) &ticks,
1538 TIGER_DATA,
1539 (unsigned long)sizeof(UINT32)),
1540 KEY_LEN+1);
1541
1542 /* --- Compute H(nsrv, nclt, skey). ---
1543 */
1544 buffer = sh_util_strconcat (nsrv, nclt,
1545 skey->session, NULL);
1546 (void)sl_strlcpy(foo_M1,
1547 sh_tiger_hash(buffer, TIGER_DATA,
1548 (unsigned long)sl_strlen(buffer)),
1549 KEY_LEN+1);
1550 memset (buffer, 0, sl_strlen(buffer));
1551
1552 /* --- Send (nclt, msg) ---
1553 */
1554 (void) sl_strlcpy(buffer, nclt, KEY_LEN+1);
1555 (void) sl_strlcat(buffer, errmsg, KEY_LEN+5);
1556
1557#ifndef SH_ENCRYPT
1558 buffer[KEY_LEN+4] = theProto;
1559 buffer[KEY_LEN+5] = '\0';
1560 sh_tools_hash_add(foo_M1, buffer, KEY_LEN+5);
1561#endif
1562
1563 flag_err =
1564 sh_forward_send_crypt (sockfd, (char) theProto, _("NCLT"),
1565 buffer,
1566 (unsigned long) sl_strlen(buffer));
1567
1568 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1569 buffer, flag_err));
1570 SH_FREE (buffer);
1571 }
1572 }
1573
1574 if (flag_err == 0)
1575 {
1576 /* --- Receive the file. ---
1577 */
1578
1579 /* --- Open a temporary file. ---
1580 */
1581
1582 if ( (sfd = open_tmp ()) < 0)
1583 {
1584 flag_err = (-1);
1585 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EFIL);
1586 }
1587 else
1588 {
1589 /* --- Read from socket into tmp file. ---
1590 */
1591 transfercount = 0;
1592 flag_err = 0;
1593
1594 do {
1595 flag_err = (int)
1596 sh_forward_receive_crypt (sockfd,
1597#ifdef SH_ENCRYPT
1598#ifdef SH_ENCRYPT_2
1599 (char)(SH_PROTO_BIG|SH_PROTO_EN2|SH_PROTO_ENC),
1600#else
1601 (char)(SH_PROTO_BIG|SH_PROTO_ENC),
1602#endif
1603#else
1604 (char)(SH_PROTO_BIG),
1605#endif
1606 head_u,
1607 answer,
1608 TRANS_BYTES + 256);
1609
1610 TPT(( 0, FIL__, __LINE__,
1611 _("msg=<Received: %d bytes, marked %s.>\n"),
1612 flag_err, hu_trans(head_u)));
1613
1614 if (flag_err > 0 && 0 == check_request_nerr(head_u, _("FILE")))
1615 {
1616 if (0 == hash_check (foo_M1, answer, flag_err))
1617 {
1618 (void) sl_write(sfd, &answer[KEY_LEN],
1619 flag_err-KEY_LEN);
1620 ++transfercount;
1621 flag_err =
1622 sh_forward_send_crypt (sockfd, (char) theProto,
1623 _("RECV"),
1624 nclt,
1625 (unsigned long)sl_strlen(nclt));
1626
1627 }
1628 else
1629 {
1630 TPT(( 0, FIL__, __LINE__,
1631 _("msg=<File transfer: Hash check failed.>\n")));
1632 break;
1633 }
1634 }
1635 else
1636 {
1637 TPT(( 0, FIL__, __LINE__,
1638 _("msg=<File transfer: No more data.>\n")));
1639 break;
1640 }
1641 } while (transfercount < 32000); /* 64 Mbyte */
1642
1643 if (0 == check_request_nerr(head_u, _("EEOT")) &&
1644 0 < flag_err &&
1645 0 == hash_check (foo_M1, answer, (int)strlen(answer)))
1646 {
1647 flag_err =
1648 sh_forward_send_crypt (sockfd, (char) theProto,
1649 _("EOTE"),
1650 nclt,
1651 (unsigned int) sl_strlen(nclt));
1652
1653 (void) rewind_tmp (sfd);
1654 (void) sl_sync(sfd);
1655 if (flag_err_info == SL_TRUE)
1656 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FOK);
1657 }
1658 else
1659 {
1660 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FBAD);
1661 (void) sl_close (sfd);
1662 sfd = (-1);
1663 }
1664
1665 (void) close (sockfd);
1666 memset(answer, 0, TRANS_BYTES + 256);
1667 MUNLOCK(answer, TRANS_BYTES + 256);
1668 SH_FREE(answer);
1669 timeout_val = 1;
1670
1671 SL_RETURN( (sfd), _("sh_forward_try_impl"));
1672 }
1673 }
1674
1675 (void) close (sockfd);
1676 memset(answer, 0, TRANS_BYTES + 256);
1677 MUNLOCK(answer, TRANS_BYTES + 256);
1678 SH_FREE(answer);
1679 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FBAD);
1680 timeout_val *= 2;
1681
1682 SL_RETURN( (-1), _("sh_forward_try_impl"));
1683 }
1684
1685
1686
1687 (void) close (sockfd);
1688 memset(answer, 0, 512);
1689 MUNLOCK(answer, 512);
1690 SH_FREE(answer);
1691
1692#ifndef EIO
1693#define EIO 5
1694#endif
1695
1696
1697#ifdef SH_ERROR_H
1698 if (flag_err != 0)
1699 {
1700 conn_state = BAD;
1701 timeout_val *= 2;
1702 if (flag_err < 0 || NULL == sh_error_message(flag_err))
1703 flag_err = EIO;
1704 sh_error_handle((-1), FIL__, __LINE__, flag_err, MSG_TCP_ECONN,
1705 sh_error_message(flag_err));
1706 SL_RETURN( (-1), _("sh_forward_try_impl"));
1707 }
1708#endif
1709 timeout_val = 1;
1710
1711 SL_RETURN( (0), _("sh_forward_try_impl"));
1712}
1713
1714/* #ifdef SH_WITH_CLIENT */
1715#endif
1716
1717
1718#if defined (SH_WITH_SERVER)
1719
1720#ifndef USE_SRP_PROTOCOL
1721
1722int sh_forward_make_client (char * str)
1723{
1724 /* char * safer; */
1725 char key[KEY_LEN+1];
1726 unsigned char in[PW_LEN+1];
1727 int i = 0, j, k, l = 0;
1728
1729 if (sl_strlen(str) != (PW_LEN * 2))
1730 {
1731 fprintf(stderr,
1732 _("Input must be a %d digit hexadecimal number"\
1733 " (only 0-9, a-f, A-F allowed in input)\n"),
1734 (PW_LEN * 2));
1735 _exit(EXIT_FAILURE);
1736 }
1737
1738 while (i < (PW_LEN * 2))
1739 {
1740 k = sh_util_hexchar(str[i]); j = sh_util_hexchar(str[i+1]);
1741 if (k != -1 && j != -1)
1742 {
1743 in[l] = (k * 16 + j);
1744 ++l; i+= 2;
1745 }
1746 else
1747 {
1748 fprintf(stderr, _("Invalid char %c\n"), str[i]);
1749 _exit(EXIT_FAILURE);
1750 }
1751 }
1752 in[PW_LEN] = '\0';
1753
1754 sl_strlcpy ((char *)key,
1755 sh_tiger_hash ((char*)in, TIGER_DATA, PW_LEN),
1756 KEY_LEN+1);
1757 key[KEY_LEN] = '\0';
1758
1759 fprintf(stdout, _("Client entry: Client=HOSTNAME@00000000@%s\n"),
1760 key);
1761 fflush(stdout);
1762
1763 _exit(EXIT_SUCCESS);
1764 return 0;
1765}
1766
1767#else
1768
1769int sh_forward_make_client (char * str)
1770{
1771 char * foo_v;
1772
1773 char salt[17];
1774 char key[KEY_LEN+1];
1775 char in[PW_LEN];
1776 int i = 0, j, k, l = 0;
1777
1778 if (sl_strlen(str) != (PW_LEN*2))
1779 {
1780 fprintf(stderr,
1781 _("Input must be a %d digit hexadecimal number"\
1782 " (only 0-9, a-f, A-F allowed in input)\n"),
1783 (PW_LEN*2));
1784 _exit(EXIT_FAILURE);
1785 }
1786
1787 while (i < (PW_LEN*2))
1788 {
1789 k = sh_util_hexchar(str[i]); j = sh_util_hexchar(str[i+1]);
1790 if (k != -1 && j != -1)
1791 {
1792 in[l] = (k * 16 + j);
1793 ++l; i+= 2;
1794 }
1795 else
1796 {
1797 fprintf(stderr, _("Invalid char %c\n"), str[i]);
1798 _exit(EXIT_FAILURE);
1799 }
1800 }
1801
1802
1803 if (0 == sh_srp_init())
1804 {
1805 sh_util_keyinit(key, KEY_LEN);
1806 sl_strlcpy(salt, sh_tiger_hash(key, TIGER_DATA, KEY_LEN), 17);
1807 sh_srp_x (salt, in);
1808 foo_v = sh_srp_verifier ();
1809 fprintf(stdout, _("Client=HOSTNAME@%s@%s\n"),
1810 salt, foo_v);
1811 fflush(stdout);
1812 SH_FREE(foo_v);
1813 sh_srp_exit();
1814 _exit(EXIT_SUCCESS);
1815 }
1816 fprintf(stdout, _("ERROR initializing BigNum library.\n"));
1817 fflush (stdout);
1818 _exit(EXIT_FAILURE);
1819 return -1;
1820}
1821#endif
1822
1823
1824int sh_forward_create_password (char * dummy)
1825{
1826 UINT32 val[2];
1827 char output[KEY_LEN+1];
1828
1829 val[0] = taus_get (&(skey->rng0[0]), &(skey->rng0[1]), &(skey->rng0[2]));
1830 val[1] = taus_get (&(skey->rng0[0]), &(skey->rng0[1]), &(skey->rng0[2]));
1831
1832 sl_strlcpy (output,
1833 sh_tiger_hash((char *)(&val[0]), TIGER_DATA, 2*sizeof(UINT32)),
1834 KEY_LEN);
1835
1836 output[16] = '\0';
1837
1838 fprintf(stdout, _("%s\n"), output);
1839 fflush (stdout);
1840
1841 if (dummy)
1842 _exit(EXIT_SUCCESS);
1843 else
1844 _exit(EXIT_SUCCESS);
1845 return (0); /* avoid compiler warning */
1846}
1847
1848/* #if defined (SH_WITH_SERVER) */
1849#endif
1850
1851/**************************************************
1852 *
1853 *
1854 * S E R V E R
1855 *
1856 *
1857 ***************************************************/
1858
1859#ifdef SH_WITH_SERVER
1860
1861#include "sh_readconf.h"
1862
1863
1864#define CONN_FREE 0
1865#define CONN_READING 1
1866#define CONN_SENDING 2
1867#define CONN_PAUSE 3
1868#define CONN_BUSY 4
1869
1870char * clt_stat[] = {
1871 N_("Inactive"),
1872 N_("Started"),
1873 N_("ILLEGAL"),
1874 N_("FAILED"),
1875 N_("Exited"),
1876 N_("PANIC"),
1877 N_("POLICY"),
1878 N_("File_transfer"),
1879 N_("Message"),
1880 N_("TIMEOUT_EXCEEDED"),
1881 N_("Suspended"),
1882 N_("Filecheck"),
1883};
1884
1885#include <time.h>
1886
1887/* in sh_html.h:
1888 * typedef struct client_entry {
1889 * } client_t;
1890 */
1891
1892#include "zAVLTree.h"
1893
1894/* Function to return the key for indexing
1895 * the argument
1896 */
1897zAVLKey sh_avl_key (void const * arg)
1898{
1899 const client_t * sa = (const client_t *) arg;
1900 return (zAVLKey) sa->hostname;
1901}
1902
1903zAVLTree * all_clients = NULL;
1904
1905void sh_forward_html_write()
1906{
1907 SL_ENTER(_("sh_forward_html_write"));
1908 sh_html_write(all_clients);
1909 SL_RET0(_("sh_forward_html_write"));
1910}
1911
1912
1913int sh_forward_use_clt_class (char * c)
1914{
1915 int i;
1916 SL_ENTER(_("sh_forward_use_clt_class"));
1917 i = sh_util_flagval(c, &(sh.flag.client_class));
1918 SL_RETURN(i, _("sh_forward_use_clt_class"));
1919}
1920
1921int sh_forward_use_clt_sev (char * c)
1922{
1923 int i;
1924 SL_ENTER(_("sh_forward_use_clt_sev"));
1925 i = sh_util_flagval(c, &(sh.flag.client_severity));
1926 SL_RETURN(i, _("sh_forward_use_clt_sev"));
1927}
1928
1929
1930/* the destructor
1931 */
1932void free_client(void * inptr)
1933{
1934 client_t * here;
1935
1936 SL_ENTER(_("free_client"));
1937 if (inptr == NULL)
1938 SL_RET0(_("free_client"));
1939 else
1940 here = (client_t *) inptr;
1941
1942 if (here->hostname != NULL)
1943 SH_FREE(here->hostname);
1944 if (here->salt != NULL)
1945 SH_FREE(here->salt);
1946 if (here->verifier != NULL)
1947 SH_FREE(here->verifier);
1948 SH_FREE(here);
1949 SL_RET0(_("free_client"));
1950}
1951
1952extern int safe_logger (int signal, int method, pid_t thepid);
1953
1954int sh_forward_register_client (char * str)
1955{
1956 client_t * newclt;
1957 client_t * testclt;
1958
1959 char * ptr;
1960 int sepnum = 0;
1961 int sep[2];
1962 register int i = 0;
1963 int siz_str = 0;
1964
1965 SL_ENTER(_("sh_forward_register_client"));
1966
1967 ptr = str;
1968 while (*ptr) {
1969 if (*ptr == '@' && sepnum < 2 )
1970 {
1971 sep[sepnum] = i;
1972 ++sepnum;
1973 }
1974 ++ptr; ++i;
1975 }
1976
1977 if (all_clients == NULL)
1978 {
1979 all_clients = zAVLAllocTree (sh_avl_key);
1980 if (all_clients == NULL)
1981 {
1982 (void) safe_logger (0, 0, getpid());
1983 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1984 }
1985 }
1986
1987 if (sepnum == 2 && sep[0] > 0)
1988 {
1989 newclt = SH_ALLOC (sizeof(client_t));
1990 newclt->hostname = SH_ALLOC (sep[0]+1);
1991 newclt->salt = SH_ALLOC (sep[1]-sep[0]);
1992 newclt->verifier = SH_ALLOC (sl_strlen(str)-sep[1]+1);
1993 newclt->exit_flag = 0;
1994 newclt->dead_flag = 0;
1995#ifdef SH_ENCRYPT
1996#ifdef SH_ENCRYPT_2
1997 newclt->encf_flag = SH_PROTO_ENC|SH_PROTO_EN2;
1998 newclt->ency_flag = SH_PROTO_ENC|SH_PROTO_EN2;
1999#else
2000 newclt->encf_flag = SH_PROTO_ENC;
2001 newclt->ency_flag = SH_PROTO_ENC;
2002#endif
2003#else
2004 newclt->encf_flag = 0;
2005 newclt->ency_flag = 0;
2006#endif
2007 newclt->session_key[0] = '\0';
2008 newclt->last_connect = (time_t) 0;
2009 newclt->session_key_timer = (time_t) 0;
2010 newclt->status_now = CLT_INACTIVE;
2011 for (i = 0; i < CLT_MAX; ++i)
2012 newclt->status_arr[i] = CLT_INACTIVE;
2013 sl_strlcpy(newclt->timestamp[CLT_INACTIVE], sh_unix_time(0), TIM_MAX);
2014 sl_strlcpy(newclt->hostname, &str[0], sep[0]+1);
2015 sl_strlcpy(newclt->salt, &str[sep[0]+1], sep[1]-sep[0]);
2016 sl_strlcpy(newclt->verifier, &str[sep[1]+1], sl_strlen(str)-sep[1]+1);
2017
2018 testclt = (client_t *) zAVLSearch (all_clients, newclt->hostname);
2019
2020 if (testclt != NULL)
2021 {
2022 SH_FREE(testclt->verifier);
2023 siz_str = strlen (newclt->verifier) + 1;
2024 testclt->verifier = SH_ALLOC (siz_str);
2025 sl_strlcpy(testclt->verifier, newclt->verifier, siz_str);
2026
2027 SH_FREE(testclt->salt);
2028 siz_str = strlen (newclt->salt) + 1;
2029 testclt->salt = SH_ALLOC (siz_str);
2030 sl_strlcpy(testclt->salt, newclt->salt, siz_str);
2031
2032 testclt->dead_flag = 0;
2033
2034 free_client(newclt);
2035 SL_RETURN( 0, _("sh_forward_register_client"));
2036 }
2037 else
2038 {
2039 if (0 == zAVLInsert (all_clients, newclt))
2040 {
2041 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CREG,
2042 newclt->hostname,
2043 newclt->salt, newclt->verifier);
2044 SL_RETURN( 0, _("sh_forward_register_client"));
2045 }
2046 }
2047 }
2048 SL_RETURN (-1, _("sh_forward_register_client"));
2049}
2050
2051typedef struct {
2052 int state;
2053 int fd;
2054 char * buf;
2055 unsigned char head[SH_HEADER_SIZE];
2056 char challenge[SH_CHALLENGE_SIZE];
2057 char peer[SH_MINIBUF+1];
2058 client_t * client_entry;
2059 char * K;
2060 char * M1;
2061 char * A;
2062 int headcount;
2063 unsigned long bytecount;
2064 unsigned long bytes_to_send;
2065 unsigned long bytes_to_get;
2066 int pass;
2067 unsigned long timer;
2068
2069 char * FileName;
2070 unsigned long FileLength;
2071 unsigned long FileSent;
2072 char FileType[5];
2073
2074 struct sockaddr_in addr_peer;
2075} sh_conn_t;
2076
2077
2078static char zap_challenge[SH_CHALLENGE_SIZE] = { 0 };
2079
2080void sh_forward_do_free (sh_conn_t * conn)
2081{
2082 SL_ENTER(_("sh_forward_do_free"));
2083
2084 if (conn->K != NULL)
2085 {
2086 SH_FREE(conn->K);
2087 conn->K = NULL;
2088 }
2089 if (conn->A != NULL)
2090 {
2091 SH_FREE(conn->A);
2092 conn->A = NULL;
2093 }
2094 if (conn->M1 != NULL)
2095 {
2096 SH_FREE(conn->M1);
2097 conn->M1 = NULL;
2098 }
2099 if (conn->buf != NULL)
2100 {
2101 SH_FREE(conn->buf);
2102 conn->buf = NULL;
2103 }
2104 if (conn->fd != (-1))
2105 {
2106 close (conn->fd);
2107 conn->fd = -1;
2108 }
2109 memcpy(conn->challenge, zap_challenge, SH_CHALLENGE_SIZE);
2110 conn->state = CONN_FREE;
2111 conn->headcount = 0;
2112 conn->bytecount = 0;
2113 conn->bytes_to_send = 0;
2114 conn->bytes_to_get = 0;
2115 conn->pass = 0;
2116 conn->timer = 0;
2117 conn->client_entry = NULL;
2118
2119 if (conn->FileName != NULL)
2120 {
2121 SH_FREE(conn->FileName);
2122 conn->FileName = NULL;
2123 }
2124 conn->FileLength = 0;
2125 conn->FileSent = 0;
2126 conn->FileType[0] = '\0';
2127 conn->FileType[1] = '\0';
2128 conn->FileType[2] = '\0';
2129 conn->FileType[3] = '\0';
2130 conn->FileType[4] = '\0';
2131
2132 --server_status.conn_open;
2133
2134 SL_RET0(_("sh_forward_do_free"));
2135}
2136
2137/****************************************
2138 *
2139 * -- Reconfiguration. --
2140 *
2141 * (1) Mark all clients as 'dead'.
2142 * (2) Reload configuration - clients
2143 * in config are non-dead now.
2144 * (3) Remove all clients still
2145 * marked as 'dead'.
2146 */
2147
2148/* -- Mark all clients as dead.
2149 */
2150void sh_forward_mark_dead ()
2151{
2152 zAVLCursor avlcursor;
2153 client_t * item;
2154
2155 SL_ENTER(_("sh_forward_mark_dead"));
2156
2157 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2158 item = (client_t *) zAVLNext(&avlcursor))
2159 {
2160 item->dead_flag = 1;
2161 }
2162 SL_RET0(_("sh_forward_mark_dead"));
2163}
2164
2165
2166/* -- Clean tree from dead clients.
2167 */
2168void sh_forward_clean_tree ()
2169{
2170 zAVLCursor avlcursor;
2171 client_t * item;
2172
2173 SL_ENTER(_("sh_forward_clean_tree"));
2174
2175 repeat_search:
2176
2177 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2178 item = (client_t *) zAVLNext(&avlcursor))
2179 {
2180 if (item->dead_flag == 1)
2181 {
2182 zAVLDelete (all_clients, item->hostname);
2183 free_client (item);
2184 goto repeat_search;
2185 }
2186 }
2187 SL_RET0(_("sh_forward_clean_tree"));
2188}
2189
2190/*
2191 *
2192 **********************************************/
2193
2194
2195
2196/* -- SERVER SEND FUNKTION. --
2197 */
2198void sh_forward_prep_send_int (sh_conn_t * conn,
2199 char * msg, unsigned long length,
2200 char * u, char protocol,
2201 int docrypt)
2202{
2203 register unsigned long i;
2204 unsigned long length2;
2205
2206#ifdef SH_ENCRYPT
2207 unsigned long blkfac = 0;
2208 int rem = 0;
2209 char * p, * q;
2210 RIJ_BYTE inBlock[B_SIZ];
2211 RIJ_BYTE outBlock[B_SIZ];
2212 unsigned int j;
2213 cipherInstance cipherInst;
2214 int err_num;
2215#else
2216 (void) docrypt;
2217#endif
2218
2219 SL_ENTER(_("sh_forward_prep_send_int"));
2220
2221 TPT((0, FIL__, __LINE__, _("msg=<%s>, docrypt=<%d>\n"), msg, docrypt ));
2222
2223#ifdef SH_ENCRYPT
2224 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0) )
2225 {
2226 length2 = length;
2227 }
2228 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0) )
2229 {
2230 blkfac = length/B_SIZ;
2231 rem = length - (B_SIZ * blkfac);
2232 length2 = (B_SIZ * blkfac) + ((rem == 0) ? 0 : B_SIZ);
2233 }
2234 else
2235 {
2236 length2 = length;
2237 }
2238#else
2239 length2 = length;
2240#endif
2241
2242 conn->headcount = 0;
2243 conn->bytecount = 0;
2244 conn->bytes_to_send = 0;
2245 conn->bytes_to_get = 0;
2246
2247 if (conn->buf != NULL)
2248 {
2249 SH_FREE(conn->buf);
2250 conn->buf = NULL;
2251 }
2252
2253
2254 put_header (conn->head, protocol, &length2, u);
2255 SH_SHOWPROT(conn->head,'>');
2256
2257 TPT((0, FIL__, __LINE__, _("msg=<put_header done>\n") ));
2258
2259 if (msg == NULL)
2260 length2 = 0;
2261
2262#ifdef SH_ENCRYPT
2263 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0))
2264 {
2265 TPT((0, FIL__, __LINE__, _("encrypting (version 2)\n")));
2266
2267 conn->buf = sh_tools_makePack (conn->head, msg, length2,
2268 &(conn->client_entry->keyInstE));
2269 }
2270 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
2271 {
2272 conn->buf = SH_ALLOC(length2 + 1);
2273
2274 p = msg;
2275 q = conn->buf;
2276
2277 TPT((0, FIL__, __LINE__, _("encrypting (version 1)\n")));
2278
2279 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
2280 if (err_num < 0)
2281 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2282 errorExplain(err_num),
2283 _("sh_forward_prep_send_int: cipherInit"));
2284
2285 for (j = 0; j < blkfac; ++j)
2286 {
2287 memcpy(inBlock, p, B_SIZ);
2288 err_num = blockEncrypt(&cipherInst, &(conn->client_entry->keyInstE),
2289 inBlock, 128 * BNUM, outBlock);
2290 if (err_num < 0)
2291 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2292 errorExplain(err_num),
2293 _("sh_forward_prep_send_int: blockEncrypt"));
2294 memcpy(q, outBlock, B_SIZ);
2295 p += B_SIZ;
2296 q += B_SIZ;
2297 }
2298 if (rem > 0)
2299 {
2300 /* incomplete block at end
2301 */
2302 memset(inBlock, '\0', B_SIZ);
2303 memcpy(inBlock, p, rem);
2304 err_num = blockEncrypt(&cipherInst, &(conn->client_entry->keyInstE),
2305 inBlock, 128 * BNUM, outBlock);
2306 if (err_num < 0)
2307 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2308 errorExplain(err_num),
2309 _("sh_forward_prep_send_int: blockEncrypt"));
2310 memcpy(q, outBlock, B_SIZ);
2311 q += B_SIZ;
2312 }
2313
2314 TPT((0, FIL__, __LINE__, _("msg=<encryption done>\n") ));
2315 }
2316 else
2317 {
2318 conn->buf = SH_ALLOC(length2 + 1);
2319
2320 for (i = 0; i < length2; ++i)
2321 conn->buf[i] = msg[i];
2322 conn->buf[length2] = '\0';
2323 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2324 }
2325#else
2326 conn->buf = SH_ALLOC(length2 + 1);
2327
2328 for (i = 0; i < length; ++i)
2329 conn->buf[i] = msg[i];
2330 conn->buf[length2] = '\0';
2331 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2332#endif
2333
2334 conn->state = CONN_SENDING;
2335 SL_RET0(_("sh_forward_prep_send_int"));
2336}
2337
2338/* -- Send/Receive. --
2339 */
2340void sh_forward_prep_send (sh_conn_t * conn,
2341 char * msg, unsigned long length,
2342 char * u, char protocol)
2343{
2344 SL_ENTER(_("sh_forward_prep_send"));
2345 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_FALSE);
2346 SL_RET0(_("sh_forward_prep_send"));
2347}
2348
2349void sh_forward_prep_send_crypt (sh_conn_t * conn,
2350 char * msg, unsigned long length,
2351 char * u, char protocol)
2352{
2353 SL_ENTER(_("sh_forward_prep_send_crypt"));
2354 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_TRUE);
2355 SL_RET0(_("sh_forward_prep_send_crypt"));
2356}
2357
2358/* #include <sys/times.h> */
2359
2360#if defined(WITH_EXTERNAL)
2361#include "sh_extern.h"
2362#endif
2363
2364/* -- Update the client status. --
2365 *
2366 * Update the status array for the client,
2367 * and eventually call external program.
2368 */
2369static void status_update (client_t * conn, int status)
2370{
2371#if defined(WITH_EXTERNAL)
2372 char msg[2 * SH_MINIBUF + TIM_MAX + 3];
2373#endif
2374
2375 SL_ENTER(_("status_update"));
2376
2377 if (conn == NULL ||
2378 status < 0 || status >= CLT_MAX)
2379 SL_RET0(_("status_update"));
2380
2381 conn->status_now = status;
2382 conn->status_arr[status] = status;
2383 sl_strlcpy(conn->timestamp[status],
2384 sh_unix_time(0),
2385 TIM_MAX);
2386
2387#if defined(WITH_EXTERNAL)
2388 sprintf(msg, _("%s %s %s"), /* known to fit */
2389 conn->hostname,
2390 conn->timestamp[status],
2391 _(clt_stat[status]));
2392 sh_ext_execute('s', 'r', 'v', msg, 0);
2393#endif
2394
2395 SL_RET0(_("status_update"));
2396}
2397
2398static time_t time_client_limit = 86400;
2399
2400int sh_forward_set_time_limit (char * c)
2401{
2402 long val;
2403
2404 SL_ENTER(_("sh_forward_set_time_limit"));
2405
2406 val = strtol (c, (char **)NULL, 10);
2407 if (val <= 0)
2408 SL_RETURN( (-1), _("sh_forward_set_time_limit"));
2409
2410 val = (val < 0 ? 0 : val);
2411
2412 time_client_limit = (time_t) val;
2413 SL_RETURN( (0), _("sh_forward_set_time_limit"));
2414}
2415
2416
2417/* -- Check for time limit exceeded. --
2418 */
2419static int client_time_check()
2420{
2421 zAVLCursor avlcursor;
2422 client_t * item;
2423
2424 SL_ENTER(_("client_time_check"));
2425
2426 if (time_client_limit == (time_t) 0)
2427 SL_RETURN( 0, _("client_time_check"));
2428
2429 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2430 item = (client_t *) zAVLNext(&avlcursor))
2431 {
2432 if (item->exit_flag == 0 && item->last_connect != (time_t) 0)
2433 {
2434 if ( (time(NULL) - item->last_connect) > time_client_limit)
2435 {
2436 if (item->status_now != CLT_TOOLONG)
2437 {
2438 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMEXC,
2439 item->hostname);
2440 status_update (item, CLT_TOOLONG);
2441 }
2442 }
2443 }
2444 }
2445 SL_RETURN( 0, _("client_time_check"));
2446}
2447
2448static int lookup_err = SH_ERR_SEVERE;
2449
2450int sh_forward_lookup_level (char * c)
2451{
2452 int ci = sh_error_convert_level (c);
2453
2454 SL_ENTER(_("sh_forward_lookup_level"));
2455
2456 if (ci >= 0)
2457 {
2458 lookup_err = ci;
2459 SL_RETURN( 0, _("sh_forward_lookup_level"));
2460 }
2461 else
2462 SL_RETURN( (-1), _("sh_forward_lookup_level"));
2463}
2464
2465#ifndef MAXHOSTNAMELEN
2466#define MAXHOSTNAMELEN 127
2467#endif
2468
2469int check_addr (const char * claim, struct sockaddr_in addr_peer)
2470{
2471 char h_name[MAXHOSTNAMELEN + 1];
2472 char h_peer[MAXHOSTNAMELEN + 1];
2473 char h_peer_IP[16];
2474 char tmp_peer_IP[16];
2475 struct hostent * he;
2476 char ** p = NULL;
2477 int i;
2478 int flag = 0;
2479
2480 SL_ENTER(_("check_addr"));
2481
2482 if (claim == NULL)
2483 {
2484 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2485 _("NULL input"), _("check_addr"));
2486 SL_RETURN ((-1), _("check_addr"));
2487 }
2488
2489 /* Make sure we have the canonical name for the client
2490 */
2491 he = sh_gethostbyname (claim);
2492
2493 if (he != NULL && he->h_name != NULL)
2494 {
2495 if (NULL == strchr(he->h_name, '.') && he->h_addr_list != NULL)
2496 {
2497 he = sh_gethostbyaddr(he->h_addr_list[0],
2498 he->h_length,
2499 he->h_addrtype);
2500 }
2501 }
2502
2503 /* copy canonical name into h_name
2504 */
2505 if (he != NULL && he->h_name != NULL)
2506 sl_strlcpy(h_name, he->h_name, MAXHOSTNAMELEN + 1);
2507 else
2508 {
2509 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESCLT,
2510 claim);
2511 SL_RETURN ((0), _("check_addr"));
2512 }
2513
2514
2515 /* get canonical name of socket peer
2516 */
2517 he = sh_gethostbyaddr ((char *) &(addr_peer.sin_addr),
2518 sizeof(addr_peer.sin_addr),
2519 AF_INET);
2520
2521 if (he != NULL && he->h_name != NULL)
2522 {
2523 if (0 == sl_strcmp(he->h_name, _("localhost")))
2524 sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
2525 else
2526 sl_strlcpy(h_peer, he->h_name, MAXHOSTNAMELEN + 1);
2527 }
2528 else
2529 {
2530 sl_strlcpy(tmp_peer_IP,
2531 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2532 16);
2533 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
2534 claim, tmp_peer_IP);
2535 SL_RETURN ((0), _("check_addr"));
2536 }
2537
2538 sl_strlcpy(h_peer_IP,
2539 inet_ntoa (*(struct in_addr *) he->h_addr),
2540 16);
2541
2542#if 0
2543 if (S_FALSE == DoReverseLookup)
2544 {
2545 SL_RETURN ((0), _("check_addr"));
2546 }
2547#endif
2548
2549 /* reverse lookup
2550 */
2551 if (0 != sl_strncmp(_("127."),
2552 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2553 4))
2554 {
2555 he = sh_gethostbyname(h_peer);
2556
2557 if (he != NULL)
2558 {
2559 for (p = he->h_addr_list; *p; ++p)
2560 {
2561 if (0 == memcmp (*p, &(addr_peer.sin_addr),
2562 sizeof(addr_peer.sin_addr)))
2563 break;
2564 ++i;
2565 }
2566 }
2567 if (he == NULL || *p == NULL)
2568 {
2569 sl_strlcpy(tmp_peer_IP,
2570 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2571 16);
2572 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
2573 claim, h_peer, tmp_peer_IP);
2574 SL_RETURN ((0), _("check_addr"));
2575 }
2576 }
2577
2578
2579 if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
2580 {
2581 SL_RETURN ((0), _("check_addr"));
2582 }
2583 else
2584 {
2585 i = 0;
2586 while (he->h_aliases[i] != NULL)
2587 {
2588 if (0 == sl_strcmp(he->h_aliases[i], h_name))
2589 {
2590 flag = 1;
2591 break;
2592 }
2593 ++i;
2594 }
2595 if (flag == 0)
2596 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKUP,
2597 claim, h_peer);
2598 }
2599
2600 SL_RETURN ((0), _("check_addr"));
2601}
2602
2603static int UseSocketPeer = S_FALSE;
2604
2605int set_socket_peer (char * c)
2606{
2607 return sh_util_flagval(c, &UseSocketPeer);
2608}
2609
2610
2611/* -- Search register. --
2612 */
2613client_t * search_register(sh_conn_t * conn, int pos)
2614{
2615 client_t * this_client;
2616 char peer_ip[16];
2617 char peer_name[MAXHOSTNAMELEN+1];
2618 char * search_string;
2619 struct sockaddr_in peer_addr;
2620 struct hostent * he;
2621 char ** p = NULL;
2622
2623 SL_ENTER(_("search_register"));
2624
2625 if (UseSocketPeer == S_TRUE)
2626 {
2627 peer_addr = conn->addr_peer;
2628 sl_strlcpy(peer_ip,
2629 inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
2630
2631 /* get canonical name of socket peer
2632 */
2633 he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr),
2634 sizeof(peer_addr.sin_addr),
2635 AF_INET);
2636
2637 if (he != NULL && he->h_name != NULL)
2638 {
2639 if (0 == sl_strcmp(he->h_name, _("localhost")))
2640 sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
2641 else
2642 sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
2643
2644 /* Reverse lookup
2645 */
2646 if (0 != sl_strncmp(peer_ip, _("127."), 4))
2647 {
2648 he = sh_gethostbyname(peer_name);
2649
2650 if (he != NULL)
2651 {
2652 for (p = he->h_addr_list; *p; ++p)
2653 {
2654 if (0 == memcmp (*p, &(peer_addr.sin_addr),
2655 sizeof(peer_addr.sin_addr)))
2656 break;
2657 }
2658 }
2659 if (he == NULL || *p == NULL)
2660 {
2661 /*
2662 sh_error_handle(lookup_err, FIL__, __LINE__, 0,
2663 MSG_TCP_LOOKERS,
2664 conn->buf[pos], peer_name, peer_ip);
2665 */
2666 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2667 }
2668 }
2669 }
2670 else
2671 {
2672 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2673 }
2674 search_string = peer_name;
2675 }
2676 else
2677 {
2678 search_string = &(conn->buf[pos]);
2679
2680 if (0 != check_addr (search_string, conn->addr_peer))
2681 {
2682 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2683 _("Reverse lookup failed"), search_string);
2684 sh_forward_do_free (conn);
2685 SL_RETURN( NULL, _("search_register"));
2686 }
2687 }
2688
2689 /* ---- search the register -----
2690 */
2691 this_client = zAVLSearch(all_clients, search_string);
2692
2693 if (this_client == NULL)
2694 {
2695 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2696 _("Not in client list"), search_string);
2697 sh_forward_do_free (conn);
2698 SL_RETURN( NULL, _("search_register"));
2699 }
2700 if (this_client->exit_flag == 1)
2701 {
2702 TPT((0, FIL__, __LINE__, _("msg=<this_client->exit_flag == 1>\n")));
2703 this_client->session_key_timer = (time_t) 0;
2704 this_client->session_key[0] = '\0';
2705 this_client->exit_flag = 0;
2706 }
2707 TPT((0, FIL__, __LINE__, _("msg=<search_register: client %s>\n"),
2708 this_client->hostname));
2709 TPT((0, FIL__, __LINE__, _("msg=<search_register: key %s>\n"),
2710 this_client->session_key));
2711 SL_RETURN( this_client, _("search_register"));
2712}
2713
2714
2715/************************************************************************
2716 *
2717 * Here we check the message received, and decide on the answer to send
2718 * (if any). The connection is in CONN_PAUSED state, thus we must:
2719 * (i) define the proper reaction
2720 * (ii) reset to CONN_READING or CONN_WRITING or CONN_FREE
2721 * (iii) eventually reset the connection entry
2722 *
2723 *************************************************************************/
2724static
2725void check_protocol(sh_conn_t * conn, int state)
2726{
2727 client_t * this_client;
2728
2729 char * cmd;
2730
2731 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
2732 char * buffer;
2733 long len;
2734
2735 int clt_sev;
2736 char * ptok;
2737
2738 UINT32 ticks;
2739 int i;
2740 char * test;
2741 char u[5] = "OOOO";
2742
2743 SL_TICKET sfd = -1;
2744 char * read_buf = 0;
2745 char * send_buf;
2746 int bytes;
2747
2748#ifdef SH_ENCRYPT
2749 int blkfac;
2750 int rem;
2751 int send_bytes;
2752 int err_num;
2753#endif
2754
2755
2756#ifdef USE_SRP_PROTOCOL
2757 char * foo_B;
2758 char * foo_Ss;
2759#endif
2760
2761 SL_ENTER(_("check_protocol"));
2762
2763 /* seed / re-seed the PRNG if required
2764 */
2765 (void) taus_seed();
2766
2767
2768 /* protocols:
2769 * -- (iii) file transfer
2770 * -- (ii) authenticated message transfer
2771 * -- (i) SRP key exchange
2772 */
2773
2774 /* --------- FILE TRANSFER -----------
2775 */
2776 if ( (conn->head[0] & SH_PROTO_SRP) == 0 &&
2777 (conn->head[0] & SH_PROTO_BIG) != 0 /* is set */ )
2778 {
2779
2780 if (state == SH_DO_READ) /* finished reading */
2781 {
2782 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
2783
2784 /* -- Client requests challenge. --
2785 */
2786 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
2787 {
2788
2789 TPT(( 0, FIL__, __LINE__,
2790 _("msg=<File transfer - HELO (1).>\n")));
2791
2792 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN)
2793 {
2794 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
2795 sh_forward_do_free (conn);
2796 SL_RET0(_("check_protocol"));
2797 }
2798
2799 /* ---- search the register -----
2800 */
2801
2802 this_client = search_register (conn, KEY_LEN);
2803 if (this_client == NULL)
2804 SL_RET0(_("check_protocol"));
2805
2806 /* ---- force authentication -----
2807 */
2808
2809 if (this_client->session_key[0] == '\0' ||
2810 (time(NULL) - this_client->session_key_timer)
2811 > (time_t) TIMEOUT_KEY )
2812 {
2813 /* fake an auth request and jump there
2814 */
2815 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
2816 conn->head[3] = 'S';
2817 conn->head[4] = 'A';
2818 conn->head[5] = 'L';
2819 conn->head[6] = 'T';
2820 if (flag_err_info == SL_TRUE)
2821 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
2822 &(conn->buf[KEY_LEN]));
2823 strcpy(conn->buf, /* known to fit */
2824 &(conn->buf[KEY_LEN]));
2825 this_client->session_key[0] = '\0';
2826 this_client->session_key_timer = (time_t) 1;
2827 goto servInit;
2828 }
2829
2830 /* --- check whether hostname is properly signed ---
2831 */
2832 if (conn->K != NULL)
2833 {
2834 SH_FREE(conn->K);
2835 conn->K = NULL;
2836 }
2837 i = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
2838 conn->K = SH_ALLOC(i);
2839
2840 sl_strlcpy (conn->K,
2841 sh_util_siggen(this_client->session_key,
2842 &(conn->buf[KEY_LEN]),
2843 sl_strlen(&(conn->buf[KEY_LEN]))),
2844 KEY_LEN+1);
2845 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
2846 &(conn->buf[KEY_LEN])));
2847 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
2848 this_client->session_key));
2849 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
2850 sh_util_siggen(this_client->session_key,
2851 &(conn->buf[KEY_LEN]),
2852 sl_strlen(&(conn->buf[KEY_LEN])))));
2853
2854 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
2855 {
2856 TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf));
2857 TPT((0, FIL__, __LINE__, _("msg=<srv %s>\n"), conn->K));
2858 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2859 _("Signature mismatch"),
2860 &(conn->buf[KEY_LEN]));
2861
2862 this_client->session_key_timer =
2863 time(NULL) - (2*TIMEOUT_KEY);
2864
2865 sh_forward_do_free (conn);
2866 SL_RET0(_("check_protocol"));
2867 }
2868 SH_FREE(conn->K);
2869 conn->K = NULL;
2870
2871 /* --- create and send a nonce ---
2872 */
2873
2874 conn->client_entry = this_client;
2875 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
2876
2877 ticks = (UINT32) taus_get (&(skey->rng0[0]),
2878 &(skey->rng1[0]),
2879 &(skey->rng2[0]));
2880 if (conn->K != NULL)
2881 {
2882 SH_FREE(conn->K);
2883 conn->K = NULL;
2884 }
2885 conn->K = SH_ALLOC(KEY_LEN+1);
2886 sl_strlcpy (conn->K,
2887 sh_tiger_hash ((char *) &ticks,
2888 TIGER_DATA, sizeof(UINT32)),
2889 KEY_LEN+1);
2890
2891 TPT((0, FIL__, __LINE__, _("msg=<send nonce>\n")));
2892 sh_forward_prep_send (conn, conn->K, KEY_LEN+1, _("NSRV"),
2893 SH_PROTO_BIG);
2894 }
2895
2896 /* --- Client has send a message. Check state and message. ---
2897 */
2898 else if (0 == check_request_nerr((char *)&(conn->head[3]), _("NCLT")) &&
2899 conn->client_entry != NULL &&
2900 sl_strlen(conn->buf) > KEY_LEN &&
2901 conn->K != NULL)
2902 {
2903
2904 TPT(( 0, FIL__, __LINE__,
2905 _("msg=<File transfer - NCLT (3).>\n")));
2906
2907 /* --- get client nonce and compute hash ---
2908 */
2909 if (conn->A != NULL)
2910 {
2911 SH_FREE(conn->A);
2912 conn->A = NULL;
2913 }
2914 conn->A = SH_ALLOC(3*KEY_LEN+1);
2915 sl_strlcpy (conn->A, conn->K, KEY_LEN+1);
2916 sl_strlcat(conn->A, conn->buf, /* ignore remainder */
2917 2*KEY_LEN+1);
2918 sl_strlcat(conn->A, conn->client_entry->session_key,
2919 3*KEY_LEN+1);
2920 sl_strlcpy (conn->K, sh_tiger_hash(conn->A,TIGER_DATA,3*KEY_LEN),
2921 KEY_LEN+1);
2922 SH_FREE(conn->A);
2923 conn->A = NULL;
2924
2925
2926#ifdef SH_ENCRYPT
2927 if ((conn->client_entry->encf_flag != 0) &&
2928 ((conn->head[0] & SH_PROTO_ENC) == 0))
2929 {
2930 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
2931 _("file download"),
2932#ifdef SH_ENCRYPT_2
2933 _("version2"),
2934#else
2935 _("version1"),
2936#endif
2937 _("none"));
2938 if (sl_strlen(conn->buf) > (KEY_LEN + 5)) {
2939 if (sh_tools_hash_vfy(conn->K, conn->buf, KEY_LEN+5)) {
2940 if (conn->buf[KEY_LEN+4] == conn->head[0]) {
2941 /* conn->client_entry->encf_flag = 0 */ ; /* FIXME */
2942 }
2943 }
2944 }
2945 }
2946 else if ((conn->client_entry->encf_flag != 0) &&
2947 ((conn->head[0] & SH_MASK_ENC) !=
2948 conn->client_entry->encf_flag))
2949 {
2950 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
2951 MSG_TCP_MISENC,
2952 _("file download"),
2953#ifdef SH_ENCRYPT_2
2954 _("version2"),
2955#else
2956 _("version1"),
2957#endif
2958 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1")
2959 );
2960 conn->client_entry->encf_flag =
2961 (conn->head[0] & SH_MASK_ENC);
2962 }
2963#else
2964 if ((conn->head[0] & SH_PROTO_ENC) != 0)
2965 {
2966 sh_error_handle((-1), FIL__, __LINE__, 0,
2967 MSG_TCP_MISENC,
2968 _("file download"),
2969 _("none"),
2970 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
2971 }
2972#endif
2973
2974
2975 /* ---- K = H(NSRV, NCLT, session_key) -------
2976 */
2977
2978 if (conn->FileName != NULL)
2979 {
2980 SH_FREE(conn->FileName);
2981 conn->FileName = NULL;
2982 }
2983
2984 if (0 == sl_strncmp (_("CONF"), &(conn->buf[KEY_LEN]), 4))
2985 {
2986 strcpy(conn->FileType, _("CONF")); /* known to fit */
2987 conn->FileName = get_client_conf_file(conn->peer,
2988 &(conn->FileLength));
2989 conn->FileSent = 0;
2990 }
2991 else if (0 == sl_strncmp (_("DATA"), &(conn->buf[KEY_LEN]), 4))
2992 {
2993 strcpy(conn->FileType, _("DATA")); /* known to fit */
2994 conn->FileName = get_client_data_file(conn->peer,
2995 &(conn->FileLength));
2996 conn->FileSent = 0;
2997 }
2998 else
2999 {
3000 ptok = sh_util_safe_name(&(conn->buf[KEY_LEN]));
3001 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FFILE,
3002 conn->peer,
3003 ptok);
3004 SH_FREE(ptok);
3005 status_update (conn->client_entry, CLT_FAILED);
3006 sh_forward_do_free (conn);
3007 }
3008
3009 bytes = -1;
3010
3011 if (conn != NULL && conn->FileName != NULL)
3012 {
3013 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3014 if (!SL_ISERROR(sfd))
3015 {
3016 read_buf = SH_ALLOC(TRANS_BYTES);
3017 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3018 sl_close(sfd);
3019 }
3020
3021 else
3022 {
3023 sh_error_handle((-1), FIL__, __LINE__, sfd,
3024 MSG_E_ACCESS,
3025 (long) geteuid(),
3026 conn->FileName);
3027 }
3028 if (bytes >= 0)
3029 {
3030#ifdef SH_ENCRYPT
3031 /* need to send N * B_SIZ bytes
3032 */
3033 blkfac = bytes / B_SIZ;
3034 rem = bytes - (blkfac * B_SIZ);
3035 if (rem != 0)
3036 {
3037 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3038 ++blkfac;
3039 send_bytes = blkfac * B_SIZ;
3040 }
3041 else
3042 send_bytes = bytes;
3043
3044 send_buf = hash_me(conn->K, read_buf,
3045 send_bytes);
3046
3047 sh_forward_prep_send_crypt (conn, send_buf,
3048 send_bytes+KEY_LEN,
3049 _("FILE"),
3050 SH_PROTO_BIG|conn->client_entry->encf_flag);
3051#else
3052 send_buf = hash_me(conn->K, read_buf, bytes);
3053 sh_forward_prep_send_crypt (conn, send_buf,
3054 bytes+KEY_LEN,
3055 _("FILE"), SH_PROTO_BIG);
3056#endif
3057 conn->FileSent += bytes;
3058 if (send_buf != NULL)
3059 {
3060 SH_FREE(send_buf);
3061 }
3062 SH_FREE(read_buf);
3063 }
3064 }
3065
3066 if (conn == NULL || conn->FileName == NULL ||
3067 SL_ISERROR(sfd) || bytes < 0)
3068 {
3069 sh_error_handle((-1), FIL__, __LINE__, sfd, MSG_TCP_NFILE,
3070 conn->peer,
3071 (conn->FileName == NULL) ?
3072 _("(NULL)") : conn->FileName);
3073 status_update (conn->client_entry, CLT_FAILED);
3074 sh_forward_do_free (conn);
3075 }
3076
3077 }
3078
3079 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3080 _("RECV")) &&
3081 conn->client_entry != NULL &&
3082 conn->K != NULL &&
3083 conn->FileName != NULL)
3084 {
3085
3086 TPT(( 0, FIL__, __LINE__,
3087 _("msg=<File transfer - RCVT (5+).>\n")));
3088
3089 if (conn->FileSent == conn->FileLength)
3090 {
3091 send_buf = hash_me(conn->K, conn->peer,
3092 sl_strlen(conn->peer));
3093#ifdef SH_ENCRYPT
3094 sh_forward_prep_send_crypt (conn, send_buf,
3095 sl_strlen(conn->peer)+KEY_LEN,
3096 _("EEOT"),
3097 SH_PROTO_BIG|conn->client_entry->encf_flag);
3098#else
3099 sh_forward_prep_send_crypt (conn, send_buf,
3100 sl_strlen(conn->peer)+KEY_LEN,
3101 _("EEOT"),
3102 SH_PROTO_BIG);
3103#endif
3104 SH_FREE(send_buf);
3105 }
3106 else
3107 {
3108 bytes = -1;
3109 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3110 if (!SL_ISERROR(sfd))
3111 {
3112 read_buf = SH_ALLOC(TRANS_BYTES);
3113 sl_seek (sfd, (off_t) conn->FileSent);
3114 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3115 sl_close(sfd);
3116 }
3117 else
3118 {
3119 sh_error_handle((-1), FIL__, __LINE__, sfd,
3120 MSG_E_ACCESS,
3121 (long) geteuid(),
3122 conn->FileName);
3123 }
3124 if (bytes >= 0)
3125 {
3126#ifdef SH_ENCRYPT
3127 /* need to send N * B_SIZ bytes
3128 */
3129 blkfac = bytes / B_SIZ;
3130 rem = bytes - (blkfac * B_SIZ);
3131 if (rem != 0)
3132 {
3133 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3134 ++blkfac;
3135 send_bytes = blkfac * B_SIZ;
3136 }
3137 else
3138 send_bytes = bytes;
3139
3140 send_buf = hash_me(conn->K, read_buf,
3141 send_bytes);
3142
3143 sh_forward_prep_send_crypt (conn, send_buf,
3144 send_bytes+KEY_LEN,
3145 _("FILE"),
3146 SH_PROTO_BIG|conn->client_entry->encf_flag);
3147#else
3148
3149 send_buf = hash_me(conn->K, read_buf, bytes);
3150 sh_forward_prep_send_crypt (conn, send_buf,
3151 bytes+KEY_LEN,
3152 _("FILE"),
3153 SH_PROTO_BIG);
3154#endif
3155
3156 conn->FileSent += bytes;
3157 SH_FREE(send_buf);
3158 SH_FREE(read_buf);
3159 }
3160 else
3161 {
3162 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NFILE,
3163 conn->peer,
3164 (conn->FileName == NULL) ?
3165 _("(NULL)") : conn->FileName);
3166 status_update (conn->client_entry, CLT_FAILED);
3167 sh_forward_do_free (conn);
3168 }
3169 }
3170 }
3171
3172
3173 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3174 _("EOTE")) &&
3175 conn->client_entry != NULL)
3176 {
3177
3178 TPT(( 0, FIL__, __LINE__,
3179 _("msg=<File transfer - EOTE (7).>\n")));
3180
3181 if (flag_err_info == SL_TRUE)
3182 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKFILE,
3183 conn->peer);
3184
3185 if ((conn->client_entry->status_now != CLT_SUSPEND) &&
3186 (conn->client_entry->status_now != CLT_TOOLONG))
3187 { status_update (conn->client_entry, CLT_FILE); }
3188 else
3189 { conn->client_entry->session_key[0] = '\0'; }
3190 conn->client_entry->last_connect = time (NULL);
3191 sh_forward_do_free (conn);
3192 }
3193
3194
3195 /* client does something unexpected
3196 */
3197 else /* ---- ??? ----- */
3198 {
3199 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3200 1, conn->pass, conn->peer,
3201 '\\', conn->head[3], '\\',conn->head[4],
3202 '\\', conn->head[5], '\\',conn->head[6]);
3203 status_update (conn->client_entry, CLT_FAILED);
3204 sh_forward_do_free (conn);
3205 }
3206 }
3207
3208 else if (state == SH_DO_WRITE) /* finished writing */
3209 {
3210 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - (wait).>\n")));
3211
3212 /* challenge is sent, now wait for message from client
3213 */
3214 conn->headcount = 0;
3215 conn->bytecount = 0;
3216 conn->bytes_to_send = 0;
3217 conn->bytes_to_get = 0;
3218 if (conn->buf != NULL)
3219 {
3220 SH_FREE(conn->buf);
3221 conn->buf = NULL;
3222 }
3223 conn->state = CONN_READING;
3224 }
3225 SL_RET0(_("check_protocol"));
3226 }
3227
3228 /* --------- message exchange -----------
3229 */
3230 if ((conn->head[0] & SH_PROTO_SRP) == 0 &&
3231 (conn->head[0] & SH_PROTO_MSG) != 0 /* is set */ )
3232 {
3233
3234 if (state == SH_DO_READ) /* finished reading */
3235 {
3236
3237 TPT(( 0, FIL__, __LINE__, _("msg=<Message transfer - entry.>\n")));
3238
3239 /* client requests challenge
3240 */
3241 if (0 == check_request_nerr ((char *)&(conn->head[3]), _("HELO")))
3242 {
3243
3244 TPT(( 0, FIL__, __LINE__,
3245 _("msg=<Message transfer - HELO (1).>\n")));
3246
3247 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN )
3248 {
3249 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3250 sh_forward_do_free (conn);
3251 SL_RET0(_("check_protocol"));
3252 }
3253
3254 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3255
3256 /* ---- search the register -----
3257 */
3258 this_client = search_register (conn, KEY_LEN);
3259 if (NULL == this_client)
3260 SL_RET0(_("check_protocol"));
3261
3262 /* ---- force authentication -----
3263 */
3264 if ( (this_client->session_key[0] == '\0') ||
3265 ((time(NULL)-this_client->session_key_timer)
3266 > (time_t) TIMEOUT_KEY)
3267 )
3268 {
3269
3270 /* fake an auth request and jump there
3271 */
3272 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
3273 conn->head[3] = 'S';
3274 conn->head[4] = 'A';
3275 conn->head[5] = 'L';
3276 conn->head[6] = 'T';
3277 if (flag_err_info == SL_TRUE)
3278 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
3279 &(conn->buf[KEY_LEN]));
3280 strcpy(conn->buf, /* known to fit */
3281 &(conn->buf[KEY_LEN]));
3282 this_client->session_key[0] = '\0';
3283 this_client->session_key_timer = (time_t) 1;
3284
3285 goto servInit;
3286 }
3287
3288 /* check whether hostname is properly signed
3289 */
3290 if (conn->K != NULL)
3291 {
3292 SH_FREE(conn->K);
3293 conn->K = NULL;
3294 }
3295 i = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
3296 conn->K = SH_ALLOC(i);
3297
3298 sl_strlcpy (conn->K,
3299 sh_util_siggen(this_client->session_key,
3300 &(conn->buf[KEY_LEN]),
3301 sl_strlen(&(conn->buf[KEY_LEN]))),
3302 KEY_LEN+1);
3303 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
3304 &(conn->buf[KEY_LEN])));
3305 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
3306 this_client->session_key));
3307 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), conn->K));
3308
3309 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
3310 {
3311 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s>\n"), conn->buf));
3312 TPT(( 0, FIL__, __LINE__, _("msg=<Want %s>\n"), conn->K));
3313 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3314 _("Signature mismatch"),
3315 &(conn->buf[KEY_LEN]));
3316
3317 this_client->session_key_timer =
3318 time(NULL) - (2*TIMEOUT_KEY);
3319
3320 sh_forward_do_free (conn);
3321 SL_RET0(_("check_protocol"));
3322 }
3323 SH_FREE(conn->K);
3324 conn->K = NULL;
3325
3326 /* -- create a nonce and send it --
3327 */
3328
3329 conn->client_entry = this_client;
3330 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
3331
3332 ticks = (UINT32) taus_get (&(skey->rng0[0]),
3333 &(skey->rng1[0]),
3334 &(skey->rng2[0]));
3335 test = (char *) &ticks;
3336 sh_util_cpylong (conn->challenge, test, 4);
3337 conn->challenge[4] = '\0';
3338 for (i = 0; i < 4; ++i)
3339 if (conn->challenge[i] == '\0')
3340 conn->challenge[i] = 0x01;
3341
3342 sh_forward_prep_send (conn, conn->challenge, 5, _("TALK"),
3343 SH_PROTO_MSG);
3344 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s.>\n"),
3345 hu_trans(conn->challenge)));
3346 }
3347
3348 /* Client has send a message. Check whether we are in proper
3349 * state, and verify message.
3350 */
3351 else if (0 ==
3352 check_request_nerr((char *)&(conn->head[3]), _("MESG")) &&
3353 conn->client_entry != NULL &&
3354 conn->client_entry->session_key[0] != '\0' &&
3355 (len = sl_strlen(conn->buf) - KEY_LEN) > 0 &&
3356 sl_strlen(conn->challenge) == 4)
3357 {
3358 TPT(( 0, FIL__, __LINE__,
3359 _("msg=<Message transfer - MESG (3).>\n")));
3360
3361#ifdef SH_ENCRYPT
3362 if (conn->client_entry->encf_flag == 0) {
3363 conn->client_entry->ency_flag = 0;
3364 }
3365 if ((conn->client_entry->ency_flag != 0) &&
3366 ((conn->head[0] & SH_PROTO_ENC) == 0))
3367 {
3368 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3369 _("message transfer"),
3370#ifdef SH_ENCRYPT_2
3371 _("version2"),
3372#else
3373 _("version1"),
3374#endif
3375 _("none"));
3376 /* conn->client_entry->ency_flag = 0; */
3377 }
3378 else if ((conn->client_entry->ency_flag != 0) &&
3379 ((conn->head[0] & SH_MASK_ENC) !=
3380 conn->client_entry->ency_flag))
3381 {
3382 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3383 MSG_TCP_MISENC,
3384 _("message transfer"),
3385#ifdef SH_ENCRYPT_2
3386 _("version2"),
3387#else
3388 _("version1"),
3389#endif
3390 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3391 conn->client_entry->ency_flag =
3392 (conn->head[0] & SH_MASK_ENC);
3393 }
3394#else
3395 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3396 {
3397 sh_error_handle((-1), FIL__, __LINE__, 0,
3398 MSG_TCP_MISENC,
3399 _("message transfer"),
3400 _("none"),
3401 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3402 }
3403#endif
3404
3405 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3406 /* get hash from message end, truncate message
3407 */
3408 sl_strlcpy(hash, &(conn->buf[len]), KEY_LEN+1);
3409 conn->buf[len] = '\0';
3410
3411 /* verify hash
3412 */
3413 buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL);
3414 i = sl_strncmp(hash,
3415 sh_util_siggen(conn->client_entry->session_key,
3416 buffer,
3417 sl_strlen(buffer)),
3418 KEY_LEN);
3419 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3420 sh_util_siggen(conn->client_entry->session_key,
3421 buffer,
3422 sl_strlen(buffer))));
3423
3424
3425 if (0 != i)
3426 {
3427 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3428 status_update (conn->client_entry, CLT_FAILED);
3429 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3430 _("Msg signature mismatch"), conn->peer);
3431 conn->client_entry->session_key_timer =
3432 time(NULL) - (2*TIMEOUT_KEY);
3433 sh_forward_do_free (conn);
3434 SL_RET0(_("check_protocol"));
3435 }
3436 else
3437 {
3438 conn->client_entry->last_connect = time (NULL);
3439
3440 if (NULL != sl_strstr(conn->buf, _("EXIT")))
3441 {
3442 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3443 conn->client_entry->exit_flag = 1;
3444 status_update (conn->client_entry, CLT_EXITED);
3445 }
3446 else if (NULL != sl_strstr(conn->buf, _("PANIC")))
3447 {
3448 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3449 status_update (conn->client_entry, CLT_PANIC);
3450 }
3451 else if (NULL != sl_strstr(conn->buf, _("SUSPEND")))
3452 {
3453 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3454 status_update (conn->client_entry, CLT_SUSPEND);
3455 }
3456 else if (NULL != sl_strstr(conn->buf, _("POLICY")))
3457 {
3458 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3459 status_update (conn->client_entry, CLT_POLICY);
3460 }
3461 else if (NULL != sl_strstr(conn->buf,
3462 _("File check completed")))
3463 {
3464 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3465 status_update (conn->client_entry, CLT_CHECK);
3466 }
3467 else if (NULL != sl_strstr(conn->buf, _("START")))
3468 {
3469 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3470 sh_socket_add2reload (conn->client_entry->hostname);
3471 if (conn->client_entry->status_now == CLT_SUSPEND) {
3472 status_update (conn->client_entry, CLT_ILLEGAL);
3473 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3474 conn->peer);
3475 }
3476 else
3477 status_update (conn->client_entry, CLT_STARTED);
3478 }
3479 else
3480 {
3481 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3482 if (0 != sl_strcmp(conn->buf,
3483 _("Runtime configuration reloaded")))
3484 {
3485 sh_socket_add2reload (conn->client_entry->hostname);
3486 }
3487 status_update (conn->client_entry, CLT_MSG);
3488 }
3489
3490 TPT((0, FIL__, __LINE__, _("msg=<status updated>\n")));
3491 clt_sev = atoi(conn->buf);
3492 clt_class = (-1);
3493 ptok = strchr(conn->buf, '?');
3494 if (ptok != NULL)
3495 {
3496 ++ptok;
3497 if (ptok != NULL && sh.flag.client_class == S_TRUE)
3498 clt_class = atoi(ptok); /* is a global */
3499 ptok = strchr(ptok, '?');
3500 if (ptok != NULL)
3501 ++ptok;
3502 }
3503 if (sh.flag.client_severity == S_FALSE)
3504 clt_sev = (-1);
3505
3506 /* here we expect an xml formatted message, thus we don't
3507 escape xml special chars (flag == 0) */
3508 ptok =
3509 sh_tools_safe_name ((ptok!=NULL) ? ptok : conn->buf, 0);
3510
3511 /* push client name to error routine
3512 */
3513 sh_error_set_peer(sh_strip_domain (conn->peer));
3514 sh_error_handle(clt_sev, FIL__, __LINE__, 0, MSG_TCP_MSG,
3515 sh_strip_domain (conn->peer),
3516 ptok);
3517 sh_error_set_peer(NULL);
3518
3519 TPT((0, FIL__, __LINE__, _("msg=<%s>\n"), ptok));
3520 SH_FREE(ptok);
3521 clt_class = (-1);
3522 }
3523 memset(buffer, '\0', sl_strlen(buffer));
3524 SH_FREE(buffer);
3525
3526 /* SERVER CONF SEND
3527 */
3528 buffer = sh_util_strconcat(conn->buf,
3529 conn->challenge,
3530 NULL);
3531 sl_strlcpy(hash,
3532 sh_util_siggen ( conn->client_entry->session_key,
3533 buffer,
3534 sl_strlen(buffer)),
3535 KEY_LEN+1);
3536
3537 /* --- SERVER CMD --- */
3538 cmd = sh_socket_check (conn->peer);
3539
3540 if (cmd != NULL)
3541 {
3542 /* max cmd size is SH_MAXMSGLEN bytes
3543 */
3544 sl_strlcpy(&hash[KEY_LEN], cmd, SH_MAXMSGLEN);
3545 sl_strlcat(&hash[KEY_LEN],
3546 sh_util_siggen ( conn->client_entry->session_key,
3547 &hash[KEY_LEN],
3548 sl_strlen(&hash[KEY_LEN])),
3549 SH_MAXMSGLEN+KEY_LEN+1);
3550
3551 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <%s>\n"),
3552 &hash[KEY_LEN]));
3553
3554 } else {
3555
3556 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <[NULL]>\n")));
3557
3558 }
3559 /* --- SERVER CMD END --- */
3560
3561 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3562 sh_util_siggen(conn->client_entry->session_key,
3563 buffer,
3564 sl_strlen(buffer))));
3565
3566#ifdef SH_ENCRYPT
3567 sh_forward_prep_send_crypt (conn, hash,
3568 sl_strlen(hash) /* KEY_LEN */,
3569 _("CONF"),
3570 SH_PROTO_MSG|SH_PROTO_END|conn->client_entry->ency_flag);
3571#else
3572 sh_forward_prep_send_crypt (conn, hash,
3573 sl_strlen(hash) /* KEY_LEN */,
3574 _("CONF"),
3575 SH_PROTO_MSG|SH_PROTO_END);
3576#endif
3577
3578 memset(buffer, '\0', sl_strlen(buffer));
3579 SH_FREE(buffer);
3580
3581 /* sh_forward_do_free (conn); */
3582 }
3583
3584 /* client does something unexpected
3585 */
3586 else /* ---- ??? ----- */
3587 {
3588 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3589 2, conn->pass, conn->peer,
3590 '\\', conn->head[3], '\\',conn->head[4],
3591 '\\', conn->head[5], '\\',conn->head[6]);
3592 status_update (conn->client_entry, CLT_FAILED);
3593 conn->client_entry->session_key_timer =
3594 time(NULL) - (2*TIMEOUT_KEY);
3595 sh_forward_do_free (conn);
3596 }
3597 }
3598 else if (state == SH_DO_WRITE) /* finished writing */
3599 {
3600 if (0 != (conn->head[0] & SH_PROTO_END))
3601 {
3602 if (flag_err_debug == SL_TRUE)
3603 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKMSG,
3604 sh_strip_domain (conn->peer));
3605 sh_forward_do_free (conn);
3606 SL_RET0(_("check_protocol"));
3607 }
3608
3609 TPT(( 0, FIL__, __LINE__, _("msg=<Msg transfer - (wait).>\n")));
3610
3611 /* challenge is sent, now wait for message from client
3612 */
3613 conn->headcount = 0;
3614 conn->bytecount = 0;
3615 conn->bytes_to_send = 0;
3616 conn->bytes_to_get = 0;
3617 if (conn->buf != NULL)
3618 {
3619 SH_FREE(conn->buf);
3620 conn->buf = NULL;
3621 }
3622 conn->state = CONN_READING;
3623 }
3624 TPT((0, FIL__, __LINE__, _("msg=<return>\n") ));
3625 SL_RET0(_("check_protocol"));
3626 }
3627
3628 /* --------- authentication -----------
3629 */
3630
3631 /* entry point for jump from message forward if session key must
3632 * be re-initialized
3633 */
3634 servInit:
3635
3636 if ( (conn->head[0] & SH_PROTO_SRP) != 0 /* is set */ )
3637 {
3638
3639#ifndef USE_SRP_PROTOCOL
3640
3641 if (state == SH_DO_READ) /* finished reading */
3642 {
3643 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3644
3645 /* first pass -- client request salt
3646 */
3647 if (conn->pass == 1)
3648 {
3649
3650 TPT((0, FIL__, __LINE__,
3651 _("msg=<Authentication - SALT (1).>\n")));
3652
3653 if (conn->buf == NULL || sl_strlen(conn->buf) == 0)
3654 {
3655 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3656 sh_forward_do_free (conn);
3657 SL_RET0(_("check_protocol"));
3658 }
3659
3660
3661 /* search the register
3662 */
3663
3664 this_client = search_register (conn, 0);
3665 if (NULL == this_client)
3666 SL_RET0(_("check_protocol"));
3667
3668
3669 conn->client_entry = this_client;
3670 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3671
3672 if (0 != check_request_s((char *)&(conn->head[3]),
3673 _("SALT"),conn->peer))
3674 {
3675 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3676 _("No salt requested"), conn->peer);
3677 status_update (conn->client_entry, CLT_FAILED);
3678 conn->client_entry->session_key_timer =
3679 time(NULL) - (2*TIMEOUT_KEY);
3680 sh_forward_do_free (conn);
3681 SL_RET0(_("check_protocol"));
3682 }
3683
3684
3685 /* -- create server nounce v --
3686 */
3687 ticks = (UINT32) taus_get (&(skey->rng0[0]),
3688 &(skey->rng1[0]),
3689 &(skey->rng2[0]));
3690
3691 if (conn->A != NULL)
3692 {
3693 SH_FREE(conn->A);
3694 conn->A = NULL;
3695 }
3696 conn->A = SH_ALLOC(KEY_LEN+1);
3697
3698 sl_strlcpy(conn->A,
3699 sh_tiger_hash((char *) &ticks,
3700 TIGER_DATA, sizeof(UINT32)),
3701 KEY_LEN+1);
3702 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3703
3704 if (conn->M1 != NULL)
3705 {
3706 SH_FREE(conn->M1);
3707 conn->M1 = NULL;
3708 }
3709 conn->M1 = SH_ALLOC(2*KEY_LEN+1);
3710
3711 /* compute hash key H(v(server), P)v(server)
3712 */
3713 sh_passwd (conn->A, conn->client_entry->verifier,
3714 NULL, conn->M1);
3715
3716 sl_strlcat(conn->M1, conn->A, 2*KEY_LEN+1);
3717
3718
3719 /* --- send H(v(server), P)v(server) ----
3720 */
3721 sh_forward_prep_send (conn,
3722 conn->M1,
3723 sl_strlen(conn->M1),
3724 u,
3725 (conn->head[0]|SH_PROTO_SRP));
3726
3727 SH_FREE(conn->M1);
3728 conn->M1 = NULL;
3729 }
3730
3731 /* client -- third pass
3732 * Message is H(H(u,v),P)u
3733 *
3734 * A := v, verifier := H(password),
3735 */
3736 else if (conn->pass == 3 &&
3737 conn->client_entry != NULL)
3738 {
3739
3740 TPT((0, FIL__, __LINE__,
3741 _("msg=<Authentication - PASS (3).>\n")));
3742
3743 if (0 != check_request_s((char *) &(conn->head[3]), _("PASS"),
3744 conn->peer) ||
3745 sl_strlen(conn->buf) <= KEY_LEN ||
3746 conn->A == NULL)
3747 {
3748 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3749 _("Invalid client request"), conn->peer);
3750 status_update (conn->client_entry, CLT_FAILED);
3751 conn->client_entry->session_key_timer =
3752 time(NULL) - (2*TIMEOUT_KEY);
3753 sh_forward_do_free (conn);
3754 SL_RET0(_("check_protocol"));
3755 }
3756
3757 /* store random nonce u from client
3758 */
3759 if (conn->K != NULL)
3760 {
3761 SH_FREE(conn->K);
3762 conn->K = NULL;
3763 }
3764 conn->K = SH_ALLOC(KEY_LEN+1);
3765 sl_strlcpy(conn->K, &(conn->buf[KEY_LEN]), KEY_LEN+1);
3766
3767 /* verify random nonce u from client
3768 */
3769 if (conn->M1 != NULL)
3770 {
3771 SH_FREE(conn->M1);
3772 conn->M1 = NULL;
3773 }
3774 conn->M1 = sh_util_strconcat(conn->K, conn->A, NULL);
3775
3776 TPT((0, FIL__, __LINE__, _("msg=<c/r: K = %s>\n"), conn->K));
3777 TPT((0, FIL__, __LINE__, _("msg=<c/r: A = %s>\n"), conn->A));
3778 TPT((0, FIL__, __LINE__, _("msg=<c/r: M = %s>\n"), conn->M1));
3779
3780 sl_strlcpy(hash, sh_tiger_hash (conn->M1,
3781 TIGER_DATA,
3782 sl_strlen(conn->M1)), KEY_LEN+1);
3783 sh_passwd (hash, conn->client_entry->verifier, NULL, conn->M1);
3784
3785 TPT((0, FIL__, __LINE__, _("msg=<c/r: H = %s>\n"), hash));
3786 TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1));
3787
3788 if ( 0 != sl_strncmp(conn->M1, conn->buf, KEY_LEN))
3789 {
3790 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3791 _("Session key mismatch"), conn->peer);
3792 status_update (conn->client_entry, CLT_FAILED);
3793 conn->client_entry->session_key_timer =
3794 time(NULL) - (2*TIMEOUT_KEY);
3795 sh_forward_do_free (conn);
3796 SL_RET0(_("check_protocol"));
3797 }
3798
3799
3800 /* ---- compute hash key H(v, P, u) ----
3801 */
3802
3803 sh_passwd (conn->A, conn->client_entry->verifier, conn->K,
3804 conn->M1);
3805
3806 sl_strlcpy(conn->client_entry->session_key,
3807 conn->M1, KEY_LEN+1);
3808 TPT((0, FIL__, __LINE__, _("msg=<c/r: Key = %s>\n"),
3809 conn->client_entry->session_key));
3810
3811#ifdef SH_ENCRYPT
3812 err_num = makeKey(&(conn->client_entry->keyInstE),
3813 DIR_ENCRYPT, 192,
3814 conn->client_entry->session_key);
3815 if (err_num < 0)
3816 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3817 errorExplain(err_num),
3818 _("check_protocol: makeKey"));
3819 err_num = makeKey(&(conn->client_entry->keyInstD),
3820 DIR_DECRYPT, 192,
3821 conn->client_entry->session_key);
3822 if (err_num < 0)
3823 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3824 errorExplain(err_num),
3825 _("check_protocol: makeKey"));
3826#endif
3827
3828 if (conn->K != NULL) SH_FREE (conn->K);
3829 conn->K = NULL;
3830 if (conn->A != NULL) SH_FREE (conn->A);
3831 conn->A = NULL;
3832 if (conn->M1 != NULL) SH_FREE (conn->M1);
3833 conn->M1 = NULL;
3834
3835 /* if (conn->client_entry->status_now == CLT_STARTED */
3836 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
3837 (conn->client_entry->status_now != CLT_EXITED) &&
3838 (conn->client_entry->status_now != CLT_SUSPEND))
3839 && conn->client_entry->session_key_timer > (time_t) 1)
3840 {
3841 status_update (conn->client_entry, CLT_ILLEGAL);
3842 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3843 conn->peer);
3844 }
3845 else if (conn->client_entry->session_key_timer == (time_t) 0)
3846 {
3847 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NEW,
3848 conn->peer);
3849 if (conn->client_entry->status_now != CLT_SUSPEND)
3850 status_update (conn->client_entry, CLT_STARTED);
3851 }
3852
3853 conn->client_entry->session_key_timer = time (NULL);
3854 conn->client_entry->last_connect = time (NULL);
3855
3856 /* put in read state
3857 */
3858 sh_forward_prep_send (conn,
3859 _("AUTH"),
3860 5,
3861 _("AUTH"),
3862 (conn->head[0]|SH_PROTO_SRP));
3863
3864 }
3865 else
3866 {
3867 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3868 3, conn->pass, conn->peer,
3869 '\\', conn->head[3], '\\', conn->head[4],
3870 '\\', conn->head[5], '\\', conn->head[6]);
3871 sh_forward_do_free (conn);
3872 }
3873 }
3874
3875#else
3876 /* use SRP */
3877
3878
3879 if (state == SH_DO_READ) /* finished reading */
3880 {
3881
3882 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3883
3884 /* first pass -- client request salt
3885 */
3886 if (conn->pass == 1)
3887 {
3888 TPT((0, FIL__, __LINE__,
3889 _("msg=<Authentication - SALT (1).>\n")));
3890
3891 if (conn->buf == NULL)
3892 {
3893 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3894 sh_forward_do_free (conn);
3895 SL_RET0(_("check_protocol"));
3896 }
3897
3898 /* search the register
3899 */
3900 this_client = search_register(conn, 0);
3901 if (NULL == this_client)
3902 SL_RET0(_("check_protocol"));
3903
3904 conn->client_entry = this_client;
3905 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3906
3907 if (0 != check_request_s((char *)&(conn->head[3]), _("SALT"),
3908 conn->peer))
3909 {
3910 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3911 _("No salt requested"), conn->peer);
3912 status_update (conn->client_entry, CLT_FAILED);
3913 conn->client_entry->session_key_timer =
3914 time(NULL) - (2*TIMEOUT_KEY);
3915 sh_forward_do_free (conn);
3916 SL_RET0(_("check_protocol"));
3917 }
3918
3919
3920 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3921
3922 sh_forward_prep_send (conn,
3923 conn->client_entry->salt,
3924 sl_strlen(conn->client_entry->salt),
3925 u,
3926 (conn->head[0]|SH_PROTO_SRP));
3927 }
3928
3929 /* client has sent A -- third pass
3930 */
3931 else if (conn->pass == 3 &&
3932 conn->client_entry != NULL)
3933 {
3934
3935 TPT((0, FIL__, __LINE__,
3936 _("msg=<Authentication - PC01 (3).>\n")));
3937
3938 if (0 != check_request_s((char *)&(conn->head[3]),_("PC01"),conn->peer)||
3939 conn->buf == NULL
3940 )
3941 {
3942 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3943 _("Invalid client request"), conn->peer);
3944 status_update (conn->client_entry, CLT_FAILED);
3945 conn->client_entry->session_key_timer =
3946 time(NULL) - (2*TIMEOUT_KEY);
3947 sh_forward_do_free (conn);
3948 SL_RET0(_("check_protocol"));
3949 }
3950
3951 if (0 != sh_srp_init())
3952 {
3953 status_update (conn->client_entry, CLT_FAILED);
3954 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
3955 MSG_TCP_EBGN);
3956 sh_forward_do_free (conn);
3957 SL_RET0(_("check_protocol"));
3958 }
3959
3960
3961 /* check A, only send B if correct
3962 */
3963 if ( sl_strlen(conn->buf) < SH_BUFSIZE &&
3964 0 == sh_srp_check_zero (conn->buf) )
3965 {
3966 len = sl_strlen(conn->buf)+1;
3967
3968 if (conn->A != NULL)
3969 {
3970 SH_FREE(conn->A);
3971 conn->A = NULL;
3972 }
3973 conn->A = SH_ALLOC(len);
3974 sl_strlcpy (conn->A, conn->buf, len);
3975
3976 /*
3977 * compute B
3978 */
3979 if (0 != sh_srp_make_a ()) /* b random number */
3980 {
3981 status_update (conn->client_entry, CLT_FAILED);
3982
3983 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
3984 MSG_TCP_EBGN);
3985 sh_srp_exit();
3986 sh_forward_do_free (conn);
3987 SL_RET0(_("check_protocol"));
3988 }
3989
3990 foo_B = sh_srp_B /* B = v + g^b */
3991 (conn->client_entry->verifier);
3992
3993 if (foo_B == NULL)
3994 {
3995 status_update (conn->client_entry, CLT_FAILED);
3996
3997 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
3998 MSG_TCP_EBGN);
3999 sh_srp_exit();
4000 sh_forward_do_free (conn);
4001 SL_RET0(_("check_protocol"));
4002 }
4003
4004 TPT((0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), conn->A));
4005 TPT((0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), foo_B));
4006
4007 /*
4008 * create nonce u
4009 */
4010 ticks = (UINT32) taus_get (&(skey->rng0[0]),
4011 &(skey->rng1[0]),
4012 &(skey->rng2[0]));
4013 test = (char *) &ticks;
4014 sh_util_cpylong (u, test, 4); /* u nounce */
4015 u[4] = '\0';
4016 sl_strlcpy(conn->challenge,
4017 sh_tiger_hash(u, TIGER_DATA, 4),
4018 SH_CHALLENGE_SIZE);
4019
4020 TPT((0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), u[0], u[1], u[2], u[3]));
4021 TPT((0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
4022 conn->challenge));
4023
4024 /*
4025 * compute the session key K and M1 = Hash(A,B,K)
4026 */
4027 foo_Ss = sh_srp_S_s (conn->challenge,
4028 conn->A,
4029 conn->client_entry->verifier);
4030 if (foo_Ss == NULL)
4031 {
4032 status_update (conn->client_entry, CLT_FAILED);
4033
4034 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4035 MSG_TCP_EBGN);
4036 sh_srp_exit();
4037 sh_forward_do_free (conn);
4038 SL_RET0(_("check_protocol"));
4039 }
4040
4041 if (conn->K != NULL)
4042 {
4043 SH_FREE(conn->K);
4044 conn->K = NULL;
4045 }
4046 conn->K = SH_ALLOC(KEY_LEN+1);
4047 sl_strlcpy(conn->K,
4048 sh_tiger_hash(foo_Ss, TIGER_DATA,
4049 sl_strlen(foo_Ss)),
4050 KEY_LEN+1);
4051
4052 if (conn->M1 != NULL)
4053 {
4054 SH_FREE(conn->M1);
4055 conn->M1 = NULL;
4056 }
4057 conn->M1 = SH_ALLOC(KEY_LEN+1);
4058 sl_strlcpy(conn->M1,
4059 sh_srp_M (conn->A, foo_B, conn->K),
4060 KEY_LEN+1);
4061
4062 TPT((0, FIL__, __LINE__, _("msg=<srp:Ss = %s>\n"), foo_Ss));
4063 TPT((0, FIL__, __LINE__, _("msg=<srp: K = %s>\n"), conn->K));
4064 TPT((0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),conn->M1));
4065
4066 /*
4067 * send B
4068 */
4069 sh_forward_prep_send (conn,
4070 foo_B,
4071 sl_strlen(foo_B)+1,
4072 u,
4073 (conn->head[0]|SH_PROTO_SRP));
4074 if (foo_Ss != NULL)
4075 {
4076 SH_FREE(foo_Ss);
4077 foo_Ss = NULL;
4078 }
4079 if (foo_B != NULL)
4080 {
4081 SH_FREE(foo_B);
4082 foo_B = NULL;
4083 }
4084 }
4085 else
4086 {
4087 status_update (conn->client_entry, CLT_FAILED);
4088
4089 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4090 MSG_TCP_EZERO);
4091 sh_forward_do_free (conn);
4092 }
4093
4094 sh_srp_exit();
4095 }
4096
4097 /* client has sent M1 -- fifth pass
4098 */
4099 else if (conn->pass == 5 &&
4100 conn->client_entry != NULL)
4101 {
4102 TPT((0, FIL__, __LINE__,
4103 _("msg=<Authentication - PC02 (5).>\n")));
4104
4105 /* check that the state is valid
4106 */
4107 if (0 != check_request_s((char *)&(conn->head[3]), _("PC02"),
4108 conn->peer) ||
4109 conn->A == NULL || conn->K == NULL || conn->M1 == NULL)
4110 {
4111 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4112 _("Invalid client request"), conn->peer);
4113 status_update (conn->client_entry, CLT_FAILED);
4114 conn->client_entry->session_key_timer =
4115 time(NULL) - (2*TIMEOUT_KEY);
4116 sh_forward_do_free (conn);
4117 SL_RET0(_("check_protocol"));
4118 }
4119
4120 /* ------ verify M1 = H(A, B, K) -------
4121 * ----- send M2 = H(A, M1, K) -------
4122 */
4123 if (conn->buf != NULL &&
4124 sl_strncmp(conn->buf, conn->M1, KEY_LEN) == 0)
4125 {
4126 /*
4127 * send M2
4128 */
4129 sh_forward_prep_send (conn,
4130 sh_srp_M (conn->A, conn->M1, conn->K),
4131 KEY_LEN+1,
4132 _("PARP"),
4133 (conn->head[0]|SH_PROTO_SRP));
4134
4135 if (conn->A != NULL) SH_FREE(conn->A); conn->A = NULL;
4136 if (conn->M1 != NULL) SH_FREE(conn->M1); conn->M1 = NULL;
4137 sl_strlcpy(conn->client_entry->session_key,
4138 conn->K, KEY_LEN+1);
4139 TPT((0, FIL__, __LINE__, _("msg=<key %s>\n"),
4140 conn->client_entry->session_key));
4141
4142#ifdef SH_ENCRYPT
4143 err_num = makeKey(&(conn->client_entry->keyInstE),
4144 DIR_ENCRYPT, 192,
4145 conn->client_entry->session_key);
4146 if (err_num < 0)
4147 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4148 errorExplain(err_num),
4149 _("sh_forward_prep_send_int: makeKey"));
4150 err_num = makeKey(&(conn->client_entry->keyInstD),
4151 DIR_DECRYPT, 192,
4152 conn->client_entry->session_key);
4153 if (err_num < 0)
4154 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4155 errorExplain(err_num),
4156 _("sh_forward_prep_send_int: makeKey"));
4157#endif
4158
4159 if (conn->K != NULL) SH_FREE(conn->K); conn->K = NULL;
4160
4161 conn->client_entry->last_connect = time (NULL);
4162
4163 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
4164 (conn->client_entry->status_now != CLT_EXITED) &&
4165 (conn->client_entry->status_now != CLT_SUSPEND))
4166 && conn->client_entry->session_key_timer > (time_t) 1)
4167 {
4168 status_update (conn->client_entry, CLT_ILLEGAL);
4169
4170 sh_error_handle((-1), FIL__, __LINE__, 0,
4171 MSG_TCP_ILL,
4172 conn->peer);
4173 }
4174 else if (conn->client_entry->session_key_timer == (time_t) 0)
4175 {
4176 sh_error_handle((-1), FIL__, __LINE__, 0,
4177 MSG_TCP_NEW,
4178 conn->peer);
4179 if (conn->client_entry->status_now != CLT_SUSPEND)
4180 status_update (conn->client_entry, CLT_STARTED);
4181 }
4182 conn->client_entry->session_key_timer = time (NULL);
4183
4184 }
4185 else
4186 {
4187 status_update (conn->client_entry, CLT_FAILED);
4188 conn->client_entry->session_key_timer =
4189 time(NULL) - (2*TIMEOUT_KEY);
4190
4191 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4192 _("Session key mismatch"), conn->peer);
4193 sh_forward_do_free (conn);
4194 }
4195 }
4196
4197 else
4198 {
4199 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
4200 4, conn->pass, conn->peer,
4201 '\\', conn->head[3], '\\', conn->head[4],
4202 '\\', conn->head[5], '\\', conn->head[6]);
4203 sh_forward_do_free (conn);
4204 }
4205 }
4206
4207#endif
4208
4209 else if (state == SH_DO_WRITE) /* finished writing */
4210 {
4211 TPT((0, FIL__, __LINE__, _("msg=<Authentication -- (wait).>\n")));
4212
4213 conn->headcount = 0;
4214 conn->bytecount = 0;
4215 conn->bytes_to_send = 0;
4216 conn->bytes_to_get = 0;
4217 if (conn->buf != NULL)
4218 {
4219 SH_FREE(conn->buf);
4220 conn->buf = NULL;
4221 }
4222 conn->state = CONN_READING;
4223 }
4224 }
4225 SL_RET0(_("check_protocol"));
4226}
4227
4228
4229/***********************************************************
4230 *
4231 * SERVER RECEIVE FUNCTION
4232 *
4233 ***********************************************************
4234 */
4235int sh_forward_do_read (sh_conn_t * conn)
4236{
4237 unsigned long byteread; /* bytes read */
4238
4239#ifdef SH_ENCRYPT
4240
4241 unsigned long blkfac = 0;
4242 /* unsigned long length2; */
4243 char * p = NULL, * q = NULL;
4244 RIJ_BYTE inBlock[B_SIZ];
4245 RIJ_BYTE outBlock[B_SIZ];
4246 unsigned int j;
4247 cipherInstance cipherInst;
4248 int err_num;
4249#endif
4250
4251 SL_ENTER(_("sh_forward_do_read"));
4252
4253 if (conn->state == CONN_SENDING)
4254 {
4255 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4256 conn->peer);
4257 SL_RETURN( (-1), _("sh_forward_do_read"));
4258 }
4259
4260 if (conn->headcount < SH_HEADER_SIZE)
4261 {
4262 conn->bytes_to_get = SH_HEADER_SIZE - conn->headcount;
4263 byteread = read (conn->fd, &(conn->head[conn->headcount]),
4264 conn->bytes_to_get);
4265 if (byteread > 0 || errno == EINTR)
4266 {
4267 if (byteread > 0)
4268 conn->headcount += byteread;
4269 if (conn->headcount == SH_HEADER_SIZE)
4270 {
4271 conn->bytes_to_get =
4272 (256 * (unsigned int)conn->head[1] +
4273 (unsigned int)conn->head[2]);
4274 SH_SHOWPROT(conn->head, '<');
4275 conn->bytecount = 0;
4276 }
4277 }
4278 else
4279 {
4280 goto conn_reset;
4281 }
4282 SL_RETURN( (0), _("sh_forward_do_read"));
4283 }
4284
4285
4286 /* limit message size
4287 */
4288 /*
4289 conn->bytes_to_get =
4290 (conn->bytes_to_get > (16*SH_BUFSIZE - 1)) ?
4291 (16*SH_BUFSIZE - 1) : conn->bytes_to_get;
4292 */
4293 conn->bytes_to_get = (conn->bytes_to_get > TRANS_BYTES) ?
4294 TRANS_BYTES : conn->bytes_to_get;
4295
4296 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get > 0)
4297 {
4298 if ((conn->bytecount > 0) && (conn->bytes_to_get > conn->bytecount))
4299 {
4300 /* do nothing */;
4301 }
4302 else
4303 {
4304 if (conn->buf != NULL)
4305 SH_FREE (conn->buf);
4306 conn->buf = SH_ALLOC (conn->bytes_to_get + 1);
4307 conn->bytecount = 0;
4308 }
4309
4310 byteread = read (conn->fd, &(conn->buf[conn->bytecount]),
4311 conn->bytes_to_get - conn->bytecount);
4312 if (byteread > 0 || errno == EINTR)
4313 {
4314 if (byteread > 0)
4315 conn->bytecount += byteread;
4316 if (conn->bytecount == conn->bytes_to_get)
4317 {
4318 ++conn->pass;
4319 /* always terminate with NULL - we might use sl_strcmp()
4320 */
4321 conn->buf[conn->bytecount] = '\0';
4322 conn->state = CONN_PAUSE;
4323
4324#ifdef SH_ENCRYPT
4325 if ((conn->head[0] & SH_PROTO_EN2) != 0) /* if encrypted */
4326 {
4327 conn->buf =
4328 sh_tools_revertPack (conn->head, conn->buf,
4329 &(conn->client_entry->keyInstD),
4330 conn->bytecount);
4331 }
4332 else if ((conn->head[0] & SH_PROTO_ENC) != 0) /* if encrypted */
4333 {
4334 /* Decrypt only complete blocks.
4335 * If there is an incomplete block,
4336 * something is wrong anyway.
4337 * Decrypt in place.
4338 */
4339 blkfac = conn->bytecount / B_SIZ;
4340 /* length2 = (B_SIZ * blkfac); */
4341 p = conn->buf;
4342 q = conn->buf;
4343
4344 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
4345 if (err_num < 0)
4346 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4347 errorExplain(err_num),
4348 _("sh_forward_do_read: cipherInit"));
4349
4350 for (j = 0; j < blkfac; ++j)
4351 {
4352 memcpy(inBlock, p, B_SIZ);
4353 err_num = blockDecrypt(&cipherInst,
4354 &(conn->client_entry->keyInstD),
4355 inBlock, 128 * BNUM, outBlock);
4356 if (err_num < 0)
4357 sh_error_handle((-1), FIL__, __LINE__, -1,
4358 MSG_E_SUBGEN,
4359 errorExplain(err_num),
4360 _("sh_forward_do_read: blockDecrypt"));
4361 memcpy(q, outBlock, B_SIZ);
4362 p += 16;
4363 q += 16;
4364 }
4365 }
4366#endif
4367
4368 /* ------ HERE CALL check_protocol(conn) ------- */
4369 check_protocol(conn, SH_DO_READ);
4370 }
4371 }
4372 else
4373 {
4374 goto conn_reset;
4375 }
4376 }
4377
4378 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get == 0)
4379 {
4380 if (conn->buf != NULL)
4381 SH_FREE (conn->buf);
4382 conn->buf = NULL;
4383 conn->bytecount = 0;
4384 ++conn->pass;
4385 conn->state = CONN_PAUSE;
4386 /* fprintf(stderr, "\n**** FIXME null read ****\n\n"); */
4387 /* ------ HERE CALL check_protocol(conn) ------- */
4388 check_protocol(conn, SH_DO_READ);
4389 }
4390
4391 SL_RETURN( (0), _("sh_forward_do_read"));
4392
4393 conn_reset:
4394 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4395 conn->peer);
4396 sh_forward_do_free ( conn );
4397 SL_RETURN( (-1), _("sh_forward_do_read"));
4398}
4399
4400#if !defined(O_NONBLOCK)
4401#if defined(O_NDELAY)
4402#define O_NONBLOCK O_NDELAY
4403#else
4404#define O_NONBLOCK 0
4405#endif
4406#endif
4407
4408/* send to the client
4409 */
4410int sh_forward_do_write (sh_conn_t * conn)
4411{
4412 int flags;
4413 long arg = 0;
4414 long bytesent; /* bytes read */
4415
4416 SL_ENTER(_("sh_forward_do_write"));
4417
4418 /* ---- consistency check ------
4419 */
4420 if (conn->state == CONN_READING)
4421 {
4422 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4423 conn->peer);
4424 SL_RETURN( (-1), _("sh_forward_do_write"));
4425 }
4426
4427
4428 flags = retry_fcntl (FIL__, __LINE__, conn->fd, F_GETFL, arg);
4429 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags|O_NONBLOCK);
4430
4431 /* ---- send the header ------
4432 */
4433 if (conn->headcount < SH_HEADER_SIZE)
4434 {
4435 conn->bytes_to_send = SH_HEADER_SIZE - conn->headcount;
4436 bytesent = write (conn->fd,
4437 &(conn->head[conn->headcount]),
4438 conn->bytes_to_send);
4439 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4440 {
4441 if (bytesent > 0)
4442 conn->headcount += bytesent;
4443 if (conn->headcount == SH_HEADER_SIZE)
4444 {
4445 conn->bytes_to_send =
4446 (256 * (int)conn->head[1] + (int)conn->head[2]);
4447 }
4448 }
4449 else
4450 {
4451 goto conn_reset_w;
4452 }
4453 if (conn->fd >= 0)
4454 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4455 SL_RETURN( (0), _("sh_forward_do_write"));
4456 }
4457
4458
4459 /* ---- send the body ------
4460 */
4461
4462 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send > 0 &&
4463 conn->buf != NULL)
4464 {
4465 bytesent = write (conn->fd, &(conn->buf[conn->bytecount]),
4466 conn->bytes_to_send - conn->bytecount);
4467 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4468 {
4469 if (bytesent > 0)
4470 conn->bytecount += bytesent;
4471 if (conn->bytecount == conn->bytes_to_send)
4472 {
4473 ++conn->pass;
4474 conn->state = CONN_PAUSE;
4475 /* ------ HERE CALL check_protocol(conn) ------- */
4476 check_protocol(conn, SH_DO_WRITE);
4477 }
4478 }
4479 else
4480 {
4481 goto conn_reset_w;
4482 }
4483 }
4484
4485 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send == 0)
4486 {
4487 ++conn->pass;
4488 conn->state = CONN_PAUSE;
4489 /* fprintf(stderr, "\n**** FIXME null write ****\n\n"); */
4490 /* ------ HERE CALL check_protocol(conn) ------- */
4491 check_protocol(conn, SH_DO_WRITE);
4492 }
4493
4494 if (conn->fd >= 0)
4495 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4496 SL_RETURN( (0), _("sh_forward_do_write"));
4497
4498 conn_reset_w:
4499 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4500 conn->peer);
4501 sh_forward_do_free ( conn );
4502 SL_RETURN( (-1), _("sh_forward_do_write"));
4503}
4504
4505/* accept a connection from a client
4506 */
4507#include <syslog.h>
4508#ifdef SH_USE_LIBWRAP
4509#include <tcpd.h>
4510
4511#ifndef ALLOW_SEVERITY
4512#define ALLOW_SEVERITY LOG_INFO
4513#define DENY_SEVERITY LOG_WARNING
4514#endif
4515
4516int allow_severity;
4517int deny_severity;
4518#endif
4519
4520int sh_forward_accept (int sock, sh_conn_t * newconn)
4521{
4522 int errflag;
4523 int rc;
4524 struct sockaddr_in addr;
4525#ifdef SH_USE_LIBWRAP
4526 struct request_info request;
4527 char errbuf[128];
4528 char daemon[128];
4529#endif
4530
4531 /* handle AIX (size_t addrlen) in wrapper
4532 */
4533 int addrlen = sizeof(addr);
4534
4535 SL_ENTER(_("sh_forward_accept"));
4536
4537 rc = retry_accept(FIL__, __LINE__, sock,
4538 (struct sockaddr *) &addr, &addrlen);
4539
4540 if (rc >= 0)
4541 {
4542
4543 if (addrlen == 0)
4544 {
4545 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4546 _("Connecting entity unknown"), _("accept"));
4547 newconn->fd = -1;
4548 newconn->state = CONN_FREE;
4549 close(rc);
4550 SL_RETURN( (-1), _("sh_forward_accept"));
4551 }
4552
4553#ifdef SH_USE_LIBWRAP
4554 sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
4555 request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
4556 fromhost(&request);
4557 if (!hosts_access(&request))
4558 {
4559 sl_strlcpy(errbuf, _("Refused connection from "), 128);
4560 sl_strlcat(errbuf, eval_client(&request), 128);
4561
4562 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4563 errbuf, _("libwrap"));
4564 newconn->fd = -1;
4565 newconn->state = CONN_FREE;
4566 close(rc);
4567 SL_RETURN( (-1), _("sh_forward_accept"));
4568 }
4569#endif
4570
4571 memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
4572
4573 /* prepare for usage of connection
4574 */
4575 (void) retry_fcntl( FIL__, __LINE__, rc, F_SETFD, 1 );
4576 newconn->fd = rc;
4577 newconn->state = CONN_READING;
4578 newconn->timer = (unsigned long) time (NULL);
4579
4580 if (flag_err_info == SL_TRUE)
4581 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CNEW, newconn->fd);
4582
4583 SL_RETURN( (0), _("sh_forward_accept"));
4584 }
4585 else
4586 {
4587 errflag = errno;
4588 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4589 sh_error_message(errflag), _("accept"));
4590 newconn->fd = -1;
4591 newconn->state = CONN_FREE;
4592 SL_RETURN( (-1), _("sh_forward_accept"));
4593 }
4594}
4595
4596extern char sh_sig_msg[64]; /* defined in sh_unix.c */
4597
4598/* ------------ port and interface -------
4599 */
4600static unsigned int server_port = SH_DEFAULT_PORT;
4601
4602int sh_forward_set_port (char * str)
4603{
4604 int retval = 0;
4605 unsigned long i;
4606 char * endptr = str;
4607
4608 SL_ENTER(_("sh_forward_set_port"));
4609 i = strtoul (str, &endptr, 0);
4610 if (endptr == str) {
4611 retval = -1;
4612 } else if (i > 65535) {
4613 retval = -1;
4614 } else {
4615 server_port = i;
4616 }
4617 SL_RETURN( (retval), _("sh_forward_set_port"));
4618}
4619
4620static struct in_addr server_interface;
4621static int use_server_interface = 0;
4622
4623int sh_forward_set_interface (char * str)
4624{
4625 if (0 == strcmp(str, _("INADDR_ANY")))
4626 {
4627 use_server_interface = 0;
4628 return 0;
4629 }
4630 if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/)
4631 {
4632 use_server_interface = 0;
4633 return -1;
4634 }
4635 use_server_interface = 1;
4636 return 0;
4637}
4638
4639/* ------------ print error --------------
4640 */
4641struct sock_err_st {
4642 char msg[128];
4643 int errnum;
4644 int port;
4645 int line;
4646 int euid;
4647};
4648
4649static struct sock_err_st sock_err[2];
4650
4651void sh_forward_printerr(char * str, int errnum, unsigned int port, int line)
4652{
4653 int slot = 0;
4654
4655 if (port != server_port)
4656 slot = 1;
4657 if (str == NULL)
4658 sock_err[slot].msg[0] = '\0';
4659 else
4660 sl_strlcpy(sock_err[slot].msg, str, 128);
4661 sock_err[slot].errnum = errnum;
4662 sock_err[slot].port = port;
4663 sock_err[slot].line = line;
4664 sock_err[slot].euid = (int) geteuid();
4665}
4666
4667int sh_forward_printerr_final(int slot)
4668{
4669 SL_ENTER(_("sh_forward_printerr_final"));
4670 if (sock_err[slot].msg[0] != '\0')
4671 {
4672 dlog(1, FIL__, __LINE__,
4673 _("Could not set up the listening socket for the server because of the\nfollowing error: %s\nPossible reasons include:\n - insufficient privilege for UID %d, or\n - the port %d is already used by another program.\n"),
4674 sh_error_message(sock_err[slot].errnum), sock_err[slot].euid,
4675 sock_err[slot].port);
4676 sh_error_handle((-1), FIL__, sock_err[slot].line,
4677 sock_err[slot].errnum, MSG_EXIT_ABORTS,
4678 sh_error_message(sock_err[slot].errnum),
4679 sh.prg_name,
4680 sock_err[slot].msg);
4681 SL_RETURN((-1), _("sh_forward_printerr_final"));
4682 }
4683 SL_RETURN(0, _("sh_forward_printerr_final"));
4684}
4685
4686static sh_conn_t * conns = NULL;
4687#define TIME_OUT_DEF 300
4688static int maxconn = 0; /* maximum number of simultaneous connections */
4689
4690
4691#ifdef INET_SYSLOG
4692#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
4693#define SH_MINSOCK 3
4694int create_syslog_socket (int flag);
4695static int recv_syslog_socket (int fd);
4696static int syslog_sock = -1;
4697#else
4698#define SH_MINSOCK 2
4699#endif
4700
4701extern int pf_unix_fd;
4702
4703/* the tcp socket, and the function to establish it
4704 */
4705static int sh_tcp_sock = -1;
4706
4707int sh_create_tcp_socket ()
4708{
4709 struct sockaddr_in addr;
4710 int addrlen = sizeof(addr);
4711
4712 int sock = -1;
4713 int errnum = 0;
4714 int flag = 1; /* non-zero to enable an option */
4715
4716 SL_ENTER(_("sh_create_tcp_socket"));
4717
4718 sh_forward_printerr (NULL, 0, server_port, __LINE__);
4719
4720 /* create the socket, bind() it and listen()
4721 */
4722 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
4723 {
4724 errnum = errno;
4725 sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
4726 SL_RETURN((-1), _("sl_create_tcp_socket"));
4727 }
4728 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
4729
4730 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
4731 (void *) &flag, sizeof(flag)) < 0 )
4732 {
4733 errnum = errno;
4734 sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
4735 SL_RETURN((-1), _("sl_create_tcp_socket"));
4736 }
4737
4738 addr.sin_family = AF_INET;
4739 addr.sin_port = htons(server_port);
4740 if (use_server_interface == 0)
4741 addr.sin_addr.s_addr = INADDR_ANY;
4742 else
4743 memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
4744
4745 if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0)
4746 {
4747 errnum = errno;
4748 sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
4749 SL_RETURN((-1), _("sl_create_tcp_socket"));
4750 }
4751
4752 if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
4753 {
4754 errnum = errno;
4755 sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
4756 SL_RETURN((-1), _("sl_create_tcp_socket"));
4757 }
4758
4759 if ( listen(sock, 5) < 0)
4760 {
4761 errnum = errno;
4762 sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
4763 SL_RETURN((-1), _("sl_create_tcp_socket"));
4764 }
4765
4766 sh_tcp_sock = sock;
4767
4768 SL_RETURN((sock), _("sl_create_tcp_socket"));
4769}
4770
4771/*****************************************
4772 *
4773 * This is the server main loop.
4774 *
4775 * The server is set up for listening, and
4776 * and starts a select() loop.
4777 *
4778 *****************************************/
4779
4780void sh_receive()
4781{
4782#ifdef SH_USE_XML
4783 extern int sh_log_file (char * message, char * inet_peer);
4784#endif
4785
4786 int sock = -1;
4787 sh_conn_t * cx;
4788 fd_set readset;
4789 fd_set writeset;
4790 struct timeval tv;
4791 int num_sel;
4792 int errnum;
4793 int nowconn;
4794 int status;
4795 int high_fd;
4796 register int i;
4797 long dummy = 0;
4798 unsigned long time_now;
4799 unsigned long time_last = 0;
4800 unsigned long time_out = TIME_OUT_DEF;
4801
4802 time_t told;
4803 time_t tcurrent;
4804
4805 unsigned long tchkold;
4806
4807 struct sigaction new_act;
4808 struct sigaction old_act;
4809
4810 SL_ENTER(_("sh_receive"));
4811
4812 /* ignore SIGPIPE (instead get EPIPE if connection is closed)
4813 * --- we have called sh_unix_init() already ---
4814 */
4815 new_act.sa_handler = SIG_IGN;
4816 retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
4817
4818 if ( sh_forward_printerr_final(0) < 0)
4819 {
4820 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4821 }
4822 sock = sh_tcp_sock;
4823
4824 /* ****************************************************************
4825 *
4826 * This is a non-forking server. We use select() on the listen()
4827 * socket to watch for new connections. For new connections, accept()
4828 * will return a new socket that is put in the read/write filesets.
4829 * Data about active connections are kept in the 'conns' table.
4830 *
4831 ******************************************************************/
4832
4833 /* The table to hold info on sockets.
4834 * We reserve 6 file descriptors for misc. use.
4835 * The POSIX lower limit on open files seems to be eight.
4836 */
4837 maxconn = get_open_max() - 6;
4838 maxconn = (((int)FD_SETSIZE) < maxconn) ? FD_SETSIZE : maxconn;
4839
4840 conns = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
4841
4842 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
4843 (maxconn-1), sock);
4844
4845 /* timer
4846 */
4847 tcurrent = (unsigned long) time (NULL);
4848 told = tcurrent;
4849
4850 tchkold = tcurrent;
4851
4852 for (i = SH_MINSOCK; i < maxconn; ++i)
4853 {
4854 conns[i].buf = NULL;
4855 conns[i].K = NULL;
4856 conns[i].A = NULL;
4857 conns[i].M1 = NULL;
4858 conns[i].FileName = NULL;
4859 conns[i].fd = -1;
4860 sh_forward_do_free ( &conns[i]);
4861 }
4862
4863 /* status init
4864 */
4865 server_status.conn_open = 0;
4866 server_status.conn_total = 0;
4867 server_status.conn_max = maxconn-1;
4868 server_status.start = time (NULL);
4869 server_status.last = (time_t) 0;
4870
4871 nowconn = 1;
4872 tv.tv_sec = 5;
4873 tv.tv_usec = 0;
4874
4875 /* conns[0] is the listen() socket. Always in read mode.
4876 */
4877 conns[0].fd = sock;
4878 conns[0].state = CONN_READING;
4879 high_fd = sock;
4880
4881 conns[1].fd = pf_unix_fd;
4882 conns[1].state = CONN_READING;
4883 high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
4884
4885#ifdef INET_SYSLOG
4886 conns[2].fd = -1;
4887 if ( sh_forward_printerr_final(1) < 0)
4888 {
4889 SH_FREE(conns);
4890 conns = NULL;
4891 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4892 }
4893 sock = syslog_sock;
4894
4895 if (sock >= 0)
4896 {
4897 conns[2].fd = sock;
4898 conns[2].state = CONN_READING;
4899 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
4900 }
4901#endif
4902
4903 sh_html_write(all_clients);
4904
4905 /* This is the select() loop.
4906 */
4907 while (1 == 1)
4908 {
4909
4910 if (sig_raised > 0)
4911 {
4912 TPT((0, FIL__, __LINE__, _("msg=<Process a signal.>\n")))
4913
4914 if (sig_termfast == 1) /* SIGTERM */
4915 {
4916 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
4917 strncpy (sh_sig_msg, _("SIGTERM"), 20);
4918 --sig_raised; --sig_urgent;
4919 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
4920 }
4921
4922 if (sig_config_read_again == 1)
4923 {
4924 TPT((0, FIL__, __LINE__, _("msg=<Re-read configuration.>\n")));
4925 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
4926
4927
4928 /* -- Delete the name server cache. --
4929 */
4930
4931 delete_cache();
4932#if defined(WITH_EXTERNAL)
4933 /* -- Delete list of external tasks. --
4934 */
4935 (void) sh_ext_cleanup();
4936#endif
4937 /* - mark all clients dead
4938 * - read configuration file
4939 * - remove clients still dead
4940 */
4941 sh_forward_mark_dead ();
4942
4943#if defined(SH_WITH_MAIL)
4944 reset_count_dev_mail();
4945#endif
4946 reset_count_dev_console();
4947 reset_count_dev_time();
4948 sl_trust_purge_user();
4949
4950 (void) sh_readconf_read ();
4951 for (i = SH_MINSOCK; i < maxconn; ++i)
4952 if (conns[i].state != CONN_FREE &&
4953 conns[i].client_entry != NULL &&
4954 conns[i].client_entry->dead_flag == 1)
4955 sh_forward_do_free ( &conns[i]);
4956 sh_forward_clean_tree ();
4957
4958 sig_config_read_again = 0;
4959 --sig_raised;
4960 }
4961
4962 if (sig_fresh_trail == 1) /* SIGIOT */
4963 {
4964 /* Logfile access
4965 */
4966#ifdef SH_USE_XML
4967 sh_log_file (NULL, NULL);
4968#endif
4969 TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
4970 sh_error_only_stderr (S_TRUE);
4971 sh_unix_rm_lock_file(sh.srvlog.name);
4972 retry_msleep(3, 0);
4973 sh.flag.log_start = S_TRUE;
4974 sh_error_only_stderr (S_FALSE);
4975 sig_fresh_trail = 0;
4976 --sig_raised;
4977 }
4978
4979
4980 if (sig_terminate == 1 && nowconn < 2) /* SIGQUIT */
4981 {
4982 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
4983 strncpy (sh_sig_msg, _("SIGQUIT"), 20);
4984 --sig_raised; --sig_urgent;
4985 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
4986 }
4987
4988
4989 if (sig_debug_switch == 1) /* SIGUSR1 */
4990 {
4991 TPT((0, FIL__, __LINE__, _("msg=<Debug switch.>\n")));
4992 sh_error_dbg_switch();
4993 sig_debug_switch = 0;
4994 --sig_raised;
4995 }
4996
4997 if (sig_suspend_switch > 0) /* SIGUSR2 */
4998 {
4999 TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
5000 if (sh_global_suspend_flag == 1) {
5001 sh_global_suspend_flag = 0;
5002 } else {
5003 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND,
5004 sh.prg_name);
5005 sh_global_suspend_flag = 1;
5006 }
5007 --sig_suspend_switch;
5008 --sig_raised; --sig_urgent;
5009 }
5010
5011 sig_raised = (sig_raised < 0) ? 0 : sig_raised;
5012 sig_urgent = (sig_urgent < 0) ? 0 : sig_urgent;
5013 TPT((0, FIL__, __LINE__, _("msg=<End signal processing.>\n")));
5014 }
5015
5016 if (sh_global_suspend_flag == 1)
5017 {
5018 (void) retry_msleep (1, 0);
5019 continue;
5020 }
5021
5022 /* Recompute the descriptor set. select() modifies it,
5023 * thus we update it using the info from the connection table.
5024 * Also recompute the number of open connections.
5025 */
5026 FD_ZERO( &readset );
5027 FD_ZERO( &writeset );
5028 FD_SET(conns[0].fd, &readset );
5029 high_fd = conns[0].fd;
5030
5031 if (conns[1].fd > -1)
5032 {
5033 FD_SET(conns[1].fd, &readset );
5034 high_fd = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
5035 }
5036
5037#ifdef INET_SYSLOG
5038 if (conns[2].fd > -1)
5039 {
5040 FD_SET(conns[2].fd, &readset );
5041 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5042 }
5043#endif
5044
5045 time_now = (unsigned long) time (NULL);
5046 nowconn = 1;
5047
5048 for (i = SH_MINSOCK; i < maxconn; ++i)
5049 {
5050 /* eliminate timed out connections
5051 */
5052 if (conns[i].state != CONN_FREE)
5053 {
5054 if (time_now-conns[i].timer > time_out)
5055 {
5056 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMOUT,
5057 conns[i].peer);
5058 sh_forward_do_free ( &conns[i]);
5059 }
5060 else
5061 ++nowconn;
5062 }
5063
5064
5065 if (conns[i].state == CONN_READING)
5066 {
5067 FD_SET(conns[i].fd, &readset);
5068 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5069 }
5070 else if (conns[i].state == CONN_SENDING)
5071 {
5072 FD_SET(conns[i].fd, &writeset);
5073 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5074 }
5075 }
5076
5077 /* -- Exponentially reduce timeout limit if more than 1/2 full. --
5078 */
5079 if (nowconn > (maxconn/2))
5080 time_out = ( (time_out/2) > 1) ? (time_out/2) : 1;
5081 else
5082 time_out = TIME_OUT_DEF;
5083
5084
5085
5086 /* -- Do the select(). --
5087 */
5088 num_sel = select(high_fd+1, &readset, &writeset, NULL, &tv);
5089 errnum = errno;
5090
5091 /* reset timeout - modified by select() on some systems
5092 */
5093 tv.tv_sec = 5;
5094 tv.tv_usec = 0;
5095
5096
5097 if ( (time_now - time_last) > 2L)
5098 {
5099 time_last = time_now;
5100 if (sh_html_write(all_clients) < 0)
5101 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5102 }
5103
5104
5105 /* Error handling.
5106 */
5107 if ( num_sel < 0 ) /* some error */
5108 {
5109 if (sig_raised == 1)
5110 {
5111 sig_raised = 2;
5112 continue;
5113 }
5114
5115 if ( errnum == EINTR)
5116 continue; /* try again */
5117
5118 if ( errnum == EBADF)
5119 {
5120 /* seek and destroy the bad fd
5121 */
5122 for (i = SH_MINSOCK; i < high_fd; ++i)
5123 {
5124 if ((conns[i].state == CONN_READING) ||
5125 (conns[i].state == CONN_SENDING))
5126 {
5127 if (-1 == retry_fcntl(FIL__, __LINE__,
5128 conns[i].fd, F_GETFL, dummy))
5129 sh_forward_do_free ( &conns[i]);
5130 }
5131 }
5132 continue;
5133 }
5134
5135 sh_error_handle((-1), FIL__, __LINE__, errnum, MSG_EXIT_ABORTS,
5136 sh_error_message(errnum),
5137 sh.prg_name,
5138 _("select"));
5139 aud_exit(FIL__, __LINE__, EXIT_FAILURE );
5140 }
5141
5142
5143 /* log the timestamp
5144 */
5145 if ((tcurrent - told) > sh.looptime )
5146 {
5147 told = tcurrent;
5148#ifdef MEM_DEBUG
5149 sh_mem_check();
5150 sh_unix_count_mlock();
5151#else
5152 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_STAMP);
5153#endif
5154 }
5155
5156#if defined(SH_WITH_MAIL)
5157 /*
5158 * flush the mail queue
5159 */
5160 if (tcurrent - sh.mailTime.alarm_last > sh.mailTime.alarm_interval)
5161 {
5162 TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
5163 (void) sh_mail_msg (NULL);
5164 sh.mailTime.alarm_last = tcurrent;
5165 }
5166#endif
5167#ifdef MEM_DEBUG
5168 sh_mem_dump();
5169#endif
5170
5171 tcurrent = (unsigned long) time (NULL);
5172
5173 /* check for time limit exceeded
5174 */
5175 if ((tcurrent - tchkold) > (unsigned int) 3 )
5176 {
5177 tchkold = tcurrent;
5178 client_time_check(/* all_clients */);
5179 }
5180
5181 /* seed / re-seed the PRNG if required
5182 */
5183 (void) taus_seed();
5184
5185 /* select() timeout handling.
5186 */
5187 if ( num_sel == 0 ) /* timeout - no connection */
5188 {
5189 if (sh_html_write(all_clients) < 0)
5190 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5191 continue;
5192 }
5193
5194 /* New connection.
5195 */
5196 if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection */
5197 {
5198 --num_sel;
5199 status = 0;
5200 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
5201 {
5202 i = SH_MINSOCK;
5203 while (i < maxconn)
5204 {
5205 if (conns[i].state == CONN_FREE)
5206 {
5207 status = sh_forward_accept (conns[0].fd, &conns[i]);
5208 if (status == 0)
5209 {
5210 high_fd =
5211 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
5212 ++server_status.conn_open;
5213 ++server_status.conn_total;
5214 server_status.last = time (NULL);
5215 }
5216 break;
5217 }
5218 ++i;
5219 }
5220 }
5221 if (status == 0)
5222 continue;
5223 }
5224
5225 /* check for commands on the socket
5226 */
5227 if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
5228 {
5229 sh_socket_poll();
5230 }
5231
5232#ifdef INET_SYSLOG
5233 if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
5234 {
5235 recv_syslog_socket (conns[2].fd);
5236 }
5237#endif
5238
5239 /* Check for pending read/write on the rest of the sockets.
5240 */
5241 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
5242 {
5243 if (sig_termfast == 1)
5244 break;
5245
5246 cx = &conns[i];
5247 if ( cx->state == CONN_READING &&
5248 FD_ISSET( cx->fd, &readset ) )
5249 {
5250 --num_sel;
5251 sh_forward_do_read ( cx );
5252 }
5253 else if ( cx->state == CONN_SENDING &&
5254 FD_ISSET( cx->fd, &writeset ) )
5255 {
5256 --num_sel;
5257 sh_forward_do_write ( cx );
5258 }
5259 }
5260 /* continue */
5261 }
5262 /* notreached */
5263}
5264
5265void free_client_tree ()
5266{
5267 SL_ENTER(_("free_client_tree"));
5268 zAVLFreeTree (all_clients, free_client);
5269 SL_RET0(_("free_client_tree"));
5270}
5271
5272void sh_forward_free_all ()
5273{
5274 register int i;
5275
5276 SL_ENTER(_("sh_forward_free_all"));
5277
5278 if (conns != NULL)
5279 for (i = SH_MINSOCK; i < maxconn; ++i)
5280 {
5281 sh_forward_do_free ( &conns[i]);
5282 }
5283
5284
5285 free_client_tree ();
5286
5287 if (conns != NULL)
5288 SH_FREE (conns);
5289
5290 SL_RET0(_("sh_forward_free_all"));
5291}
5292
5293#ifdef INET_SYSLOG
5294
5295#ifdef HAVE_INET_ATON
5296static char * my_inet_ntoa(struct in_addr in)
5297{
5298 return inet_ntoa(in);
5299}
5300#else
5301static char * my_inet_ntoa(struct in_addr in)
5302{
5303 unsigned char a, b, c, d;
5304 static char foo[16];
5305 char bar[4];
5306 memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
5307 memcpy (&a, &bar[0], 1);
5308 memcpy (&b, &bar[1], 1);
5309 memcpy (&c, &bar[2], 1);
5310 memcpy (&d, &bar[3], 1);
5311 sprintf(foo, "%d.%d.%d.%d", /* known to fit */
5312 (int) a, (int) b, (int) c, (int) d);
5313 return foo;
5314}
5315#endif
5316
5317
5318/* Unlike Linux / FreeBSD, most systems don't define the stuff below
5319 * in syslog.h
5320 */
5321
5322#ifndef LOG_FAC
5323#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
5324#endif
5325
5326#ifndef LOG_PRI
5327#define LOG_PRI(p) ((p) & LOG_PRIMASK)
5328#endif
5329
5330typedef struct sh_code {
5331 char *c_name;
5332 int c_val;
5333} SH_CODE;
5334
5335SH_CODE sh_facilitynames[] =
5336{
5337#ifdef LOG_AUTH
5338 { N_("auth"), LOG_AUTH },
5339#endif
5340#ifdef LOG_AUTHPRIV
5341 { N_("authpriv"), LOG_AUTHPRIV },
5342#endif
5343#ifdef LOG_CRON
5344 { N_("cron"), LOG_CRON },
5345#endif
5346#ifdef LOG_DAEMON
5347 { N_("daemon"), LOG_DAEMON },
5348#endif
5349#ifdef LOG_FTP
5350 { N_("ftp"), LOG_FTP },
5351#endif
5352#ifdef LOG_KERN
5353 { N_("kern"), LOG_KERN },
5354#endif
5355#ifdef LOG_LPR
5356 { N_("lpr"), LOG_LPR },
5357#endif
5358#ifdef LOG_MAIL
5359 { N_("mail"), LOG_MAIL },
5360#endif
5361#ifdef INTERNAL_MARK
5362 { N_("mark"), INTERNAL_MARK }, /* INTERNAL */
5363#endif
5364#ifdef LOG_NEWS
5365 { N_("news"), LOG_NEWS },
5366#endif
5367#ifdef LOG_AUTH
5368 { N_("security"), LOG_AUTH }, /* DEPRECATED */
5369#endif
5370#ifdef LOG_SYSLOG
5371 { N_("syslog"), LOG_SYSLOG },
5372#endif
5373#ifdef LOG_USER
5374 { N_("user"), LOG_USER },
5375#endif
5376#ifdef LOG_UUCP
5377 { N_("uucp"), LOG_UUCP },
5378#endif
5379#ifdef LOG_LOCAL0
5380 { N_("local0"), LOG_LOCAL0 },
5381#endif
5382#ifdef LOG_LOCAL1
5383 { N_("local1"), LOG_LOCAL1 },
5384#endif
5385#ifdef LOG_LOCAL2
5386 { N_("local2"), LOG_LOCAL2 },
5387#endif
5388#ifdef LOG_LOCAL3
5389 { N_("local3"), LOG_LOCAL3 },
5390#endif
5391#ifdef LOG_LOCAL4
5392 { N_("local4"), LOG_LOCAL4 },
5393#endif
5394#ifdef LOG_LOCAL5
5395 { N_("local5"), LOG_LOCAL5 },
5396#endif
5397#ifdef LOG_LOCAL6
5398 { N_("local6"), LOG_LOCAL6 },
5399#endif
5400#ifdef LOG_LOCAL7
5401 { N_("local7"), LOG_LOCAL7 },
5402#endif
5403 { NULL, -1 }
5404};
5405
5406
5407SH_CODE sh_prioritynames[] =
5408{
5409#ifdef LOG_ALERT
5410 { N_("alert"), LOG_ALERT },
5411#endif
5412#ifdef LOG_CRIT
5413 { N_("crit"), LOG_CRIT },
5414#endif
5415#ifdef LOG_DEBUG
5416 { N_("debug"), LOG_DEBUG },
5417#endif
5418#ifdef LOG_EMERG
5419 { N_("emerg"), LOG_EMERG },
5420#endif
5421#ifdef LOG_ERR
5422 { N_("err"), LOG_ERR },
5423#endif
5424#ifdef LOG_ERR
5425 { N_("error"), LOG_ERR }, /* DEPRECATED */
5426#endif
5427#ifdef LOG_INFO
5428 { N_("info"), LOG_INFO },
5429#endif
5430#ifdef INTERNAL_NOPRI
5431 { N_("none"), INTERNAL_NOPRI }, /* INTERNAL */
5432#endif
5433#ifdef LOG_NOTICE
5434 { N_("notice"), LOG_NOTICE },
5435#endif
5436#ifdef LOG_EMERG
5437 { N_("panic"), LOG_EMERG }, /* DEPRECATED */
5438#endif
5439#ifdef LOG_WARNING
5440 { N_("warn"), LOG_WARNING }, /* DEPRECATED */
5441#endif
5442#ifdef LOG_WARNING
5443 { N_("warning"), LOG_WARNING },
5444#endif
5445 { NULL, -1 }
5446};
5447
5448static int enable_syslog_socket = S_FALSE;
5449
5450static int recv_syslog_socket (int fd)
5451{
5452 static time_t return_next = 0;
5453 int priority = 0;
5454 int fac, pri;
5455 int i;
5456 char * cfac = NULL;
5457 char * cpri = NULL;
5458 int res;
5459 char * tmp;
5460 char * bptr;
5461 char * ptr = NULL;
5462 char buf[1048];
5463 struct sockaddr_in from;
5464
5465 /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
5466 * but *int everywhere else. Because socklen_t is unsigned int, there
5467 * should be no problem as long as sizeof(struct sockaddr_in) < INT_MAX ...
5468 */
5469 int fromlen = sizeof(from);
5470
5471 if (enable_syslog_socket == S_FALSE)
5472 return 0;
5473
5474 SL_ENTER(_("recv_syslog_socket"));
5475
5476 if (return_next > 0)
5477 {
5478 if ( (time(NULL) - return_next) < 2)
5479 SL_RETURN( 0, _("recv_syslog_socket"));
5480 else
5481 return_next = 0;
5482 }
5483
5484 res = recvfrom(fd, buf, 1047, 0, (struct sockaddr *) &from, &fromlen);
5485
5486 if (res > 0)
5487 {
5488 res = (res < 1047) ? res : 1047;
5489 buf[res] = '\0';
5490 if (res > 1 && buf[res-1] == '\n')
5491 buf[res-1] = '\0';
5492
5493 /* here we expect an xml formatted message, thus we don't
5494 escape xml special chars (flag == 0) */
5495 /* commented out to not escape twice */
5496 /* bptr = sh_tools_safe_name(buf, 0); */
5497 bptr = buf;
5498
5499 if (!bptr || !(*bptr))
5500 {
5501 res = errno;
5502 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5503 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5504 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5505 SL_RETURN( (-1), _("recv_syslog_socket"));
5506 }
5507
5508 TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
5509 my_inet_ntoa(from.sin_addr)));
5510 ptr = bptr;
5511 i = 0;
5512 if (*ptr == '<')
5513 {
5514 ++ptr; ++i;
5515 while (i < res &&
5516 (unsigned char) *ptr > 47 && (unsigned char) *ptr < 58)
5517 {
5518 priority = 10 * priority + (*ptr - '0');
5519 ++ptr;
5520 ++i;
5521 }
5522 if (*ptr == '>')
5523 ++ptr;
5524 }
5525 fac = LOG_FAC(priority);
5526 i = 0;
5527 while (sh_facilitynames[i].c_name != NULL)
5528 {
5529 if (sh_facilitynames[i].c_val == (fac<<3))
5530 { cfac = sh_util_strdup(_(sh_facilitynames[i].c_name)); break; }
5531 ++i;
5532 }
5533 pri = LOG_PRI(priority);
5534 i = 0;
5535 while (sh_prioritynames[i].c_name != NULL)
5536 {
5537 if (sh_prioritynames[i].c_val == pri)
5538 { cpri = sh_util_strdup(_(sh_prioritynames[i].c_name)); break; }
5539 ++i;
5540 }
5541
5542 /* here we do not expect an xml formatted message, thus we escape
5543 xml special chars (flag == 1) */
5544 tmp = sh_tools_safe_name (ptr, 1);
5545 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_INET_SYSLOG,
5546 my_inet_ntoa(from.sin_addr),
5547 (cfac == NULL) ? _("none") : cfac,
5548 (cpri == NULL) ? _("none") : cpri,
5549 (ptr == NULL) ? _("none") : ptr);
5550 if (cfac != NULL)
5551 SH_FREE(cfac);
5552 if (cpri != NULL)
5553 SH_FREE(cpri);
5554 SH_FREE(tmp);
5555 /* SH_FREE(bptr); */
5556 }
5557
5558 else if (res < 0 && errno != EINTR)
5559 {
5560 res = errno;
5561 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5562 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5563 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5564
5565 /* don't accept anything the next 2 seconds
5566 */
5567 return_next = time(NULL);
5568 SL_RETURN( (-1), _("recv_syslog_socket"));
5569 }
5570 SL_RETURN( (0), _("recv_syslog_socket"));
5571}
5572
5573int set_syslog_active(char * c)
5574{
5575 return sh_util_flagval(c, &enable_syslog_socket);
5576}
5577
5578/* callerFlag == S_TRUE means override the enable_syslog_socket flag
5579 */
5580int create_syslog_socket (int callerFlag)
5581{
5582 int flag = 1; /* non-zero to enable an option */
5583 int sock;
5584 int errnum;
5585 int res;
5586 struct sockaddr_in addr;
5587 int addrlen = sizeof(addr);
5588
5589 SL_ENTER(_("create_syslog_socket"));
5590
5591 if (callerFlag == S_FALSE)
5592 {
5593 if (enable_syslog_socket == S_FALSE && syslog_sock >= 0)
5594 {
5595 /* user does not wish to use this facility
5596 */
5597 TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
5598 close(syslog_sock);
5599 syslog_sock = -1;
5600 }
5601 SL_RETURN((-1), _("create_syslog_socket"));
5602 }
5603
5604 sh_forward_printerr (NULL, 0, 514, __LINE__);
5605
5606 /* create the socket, bind() it and listen()
5607 */
5608 sock = socket(AF_INET, SOCK_DGRAM, 0);
5609
5610 if (sock < 0)
5611 {
5612 errnum = errno;
5613 sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
5614 SL_RETURN((-1), _("create_syslog_socket"));
5615 }
5616 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
5617
5618 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5619 (void *) &flag, sizeof(flag)) < 0 )
5620 {
5621 errnum = errno;
5622 sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
5623 errnum, 514, __LINE__);
5624 SL_RETURN((-1), _("create_syslog_socket"));
5625 }
5626
5627#if defined(SO_BSDCOMPAT)
5628 if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
5629 (void *) &flag, sizeof(flag)) < 0 )
5630 {
5631 errnum = errno;
5632 sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
5633 errnum, 514, __LINE__);
5634 SL_RETURN((-1), _("create_syslog_socket"));
5635 }
5636#endif
5637
5638 memset(&addr, 0, sizeof(addr));
5639 addr.sin_family = AF_INET;
5640 addr.sin_port = htons(514);
5641
5642 res = bind(sock, (struct sockaddr *) &addr, addrlen);
5643
5644 if ( res < 0)
5645 {
5646 errnum = errno;
5647 sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
5648 close(sock);
5649 SL_RETURN((-1), _("create_syslog_socket"));
5650 }
5651
5652 syslog_sock = sock;
5653
5654 SL_RETURN((sock), _("create_syslog_socket"));
5655}
5656/* #ifdef INET_SYSLOG */
5657#endif
5658
5659
5660
5661/* #ifdef SH_WITH_SERVER */
5662#endif
5663
5664
5665
5666
5667
5668
Note: See TracBrowser for help on using the repository browser.