source: trunk/src/sh_forward.c@ 18

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

More optimisation

File size: 140.5 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 == 1) /* 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 = 0;
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 /* select() timeout handling.
5174 */
5175 if ( num_sel == 0 ) /* timeout - no connection */
5176 {
5177 if (sh_html_write(all_clients) < 0)
5178 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5179 continue;
5180 }
5181
5182 /* New connection.
5183 */
5184 if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection */
5185 {
5186 --num_sel;
5187 status = 0;
5188 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
5189 {
5190 i = SH_MINSOCK;
5191 while (i < maxconn)
5192 {
5193 if (conns[i].state == CONN_FREE)
5194 {
5195 status = sh_forward_accept (conns[0].fd, &conns[i]);
5196 if (status == 0)
5197 {
5198 high_fd =
5199 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
5200 ++server_status.conn_open;
5201 ++server_status.conn_total;
5202 server_status.last = time (NULL);
5203 }
5204 break;
5205 }
5206 ++i;
5207 }
5208 }
5209 if (status == 0)
5210 continue;
5211 }
5212
5213 /* check for commands on the socket
5214 */
5215 if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
5216 {
5217 sh_socket_poll();
5218 }
5219
5220#ifdef INET_SYSLOG
5221 if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
5222 {
5223 recv_syslog_socket (conns[2].fd);
5224 }
5225#endif
5226
5227 /* Check for pending read/write on the rest of the sockets.
5228 */
5229 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
5230 {
5231 if (sig_termfast == 1)
5232 break;
5233
5234 cx = &conns[i];
5235 if ( cx->state == CONN_READING &&
5236 FD_ISSET( cx->fd, &readset ) )
5237 {
5238 --num_sel;
5239 sh_forward_do_read ( cx );
5240 }
5241 else if ( cx->state == CONN_SENDING &&
5242 FD_ISSET( cx->fd, &writeset ) )
5243 {
5244 --num_sel;
5245 sh_forward_do_write ( cx );
5246 }
5247 }
5248
5249 /* check for time limit exceeded
5250 */
5251 if ((tcurrent - tchkold) > (unsigned int) 3 )
5252 {
5253 tchkold = tcurrent;
5254 client_time_check(/* all_clients */);
5255 }
5256 tcurrent = tcurrent;
5257
5258 /* seed / re-seed the PRNG if required
5259 */
5260 (void) taus_seed();
5261
5262 }
5263 /* notreached */
5264}
5265
5266void free_client_tree ()
5267{
5268 SL_ENTER(_("free_client_tree"));
5269 zAVLFreeTree (all_clients, free_client);
5270 SL_RET0(_("free_client_tree"));
5271}
5272
5273void sh_forward_free_all ()
5274{
5275 register int i;
5276
5277 SL_ENTER(_("sh_forward_free_all"));
5278
5279 if (conns != NULL)
5280 for (i = SH_MINSOCK; i < maxconn; ++i)
5281 {
5282 sh_forward_do_free ( &conns[i]);
5283 }
5284
5285
5286 free_client_tree ();
5287
5288 if (conns != NULL)
5289 SH_FREE (conns);
5290
5291 SL_RET0(_("sh_forward_free_all"));
5292}
5293
5294#ifdef INET_SYSLOG
5295
5296#ifdef HAVE_INET_ATON
5297static char * my_inet_ntoa(struct in_addr in)
5298{
5299 return inet_ntoa(in);
5300}
5301#else
5302static char * my_inet_ntoa(struct in_addr in)
5303{
5304 unsigned char a, b, c, d;
5305 static char foo[16];
5306 char bar[4];
5307 memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
5308 memcpy (&a, &bar[0], 1);
5309 memcpy (&b, &bar[1], 1);
5310 memcpy (&c, &bar[2], 1);
5311 memcpy (&d, &bar[3], 1);
5312 sprintf(foo, "%d.%d.%d.%d", /* known to fit */
5313 (int) a, (int) b, (int) c, (int) d);
5314 return foo;
5315}
5316#endif
5317
5318
5319/* Unlike Linux / FreeBSD, most systems don't define the stuff below
5320 * in syslog.h
5321 */
5322
5323#ifndef LOG_FAC
5324#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
5325#endif
5326
5327#ifndef LOG_PRI
5328#define LOG_PRI(p) ((p) & LOG_PRIMASK)
5329#endif
5330
5331typedef struct sh_code {
5332 char *c_name;
5333 int c_val;
5334} SH_CODE;
5335
5336SH_CODE sh_facilitynames[] =
5337{
5338#ifdef LOG_AUTH
5339 { N_("auth"), LOG_AUTH },
5340#endif
5341#ifdef LOG_AUTHPRIV
5342 { N_("authpriv"), LOG_AUTHPRIV },
5343#endif
5344#ifdef LOG_CRON
5345 { N_("cron"), LOG_CRON },
5346#endif
5347#ifdef LOG_DAEMON
5348 { N_("daemon"), LOG_DAEMON },
5349#endif
5350#ifdef LOG_FTP
5351 { N_("ftp"), LOG_FTP },
5352#endif
5353#ifdef LOG_KERN
5354 { N_("kern"), LOG_KERN },
5355#endif
5356#ifdef LOG_LPR
5357 { N_("lpr"), LOG_LPR },
5358#endif
5359#ifdef LOG_MAIL
5360 { N_("mail"), LOG_MAIL },
5361#endif
5362#ifdef INTERNAL_MARK
5363 { N_("mark"), INTERNAL_MARK }, /* INTERNAL */
5364#endif
5365#ifdef LOG_NEWS
5366 { N_("news"), LOG_NEWS },
5367#endif
5368#ifdef LOG_AUTH
5369 { N_("security"), LOG_AUTH }, /* DEPRECATED */
5370#endif
5371#ifdef LOG_SYSLOG
5372 { N_("syslog"), LOG_SYSLOG },
5373#endif
5374#ifdef LOG_USER
5375 { N_("user"), LOG_USER },
5376#endif
5377#ifdef LOG_UUCP
5378 { N_("uucp"), LOG_UUCP },
5379#endif
5380#ifdef LOG_LOCAL0
5381 { N_("local0"), LOG_LOCAL0 },
5382#endif
5383#ifdef LOG_LOCAL1
5384 { N_("local1"), LOG_LOCAL1 },
5385#endif
5386#ifdef LOG_LOCAL2
5387 { N_("local2"), LOG_LOCAL2 },
5388#endif
5389#ifdef LOG_LOCAL3
5390 { N_("local3"), LOG_LOCAL3 },
5391#endif
5392#ifdef LOG_LOCAL4
5393 { N_("local4"), LOG_LOCAL4 },
5394#endif
5395#ifdef LOG_LOCAL5
5396 { N_("local5"), LOG_LOCAL5 },
5397#endif
5398#ifdef LOG_LOCAL6
5399 { N_("local6"), LOG_LOCAL6 },
5400#endif
5401#ifdef LOG_LOCAL7
5402 { N_("local7"), LOG_LOCAL7 },
5403#endif
5404 { NULL, -1 }
5405};
5406
5407
5408SH_CODE sh_prioritynames[] =
5409{
5410#ifdef LOG_ALERT
5411 { N_("alert"), LOG_ALERT },
5412#endif
5413#ifdef LOG_CRIT
5414 { N_("crit"), LOG_CRIT },
5415#endif
5416#ifdef LOG_DEBUG
5417 { N_("debug"), LOG_DEBUG },
5418#endif
5419#ifdef LOG_EMERG
5420 { N_("emerg"), LOG_EMERG },
5421#endif
5422#ifdef LOG_ERR
5423 { N_("err"), LOG_ERR },
5424#endif
5425#ifdef LOG_ERR
5426 { N_("error"), LOG_ERR }, /* DEPRECATED */
5427#endif
5428#ifdef LOG_INFO
5429 { N_("info"), LOG_INFO },
5430#endif
5431#ifdef INTERNAL_NOPRI
5432 { N_("none"), INTERNAL_NOPRI }, /* INTERNAL */
5433#endif
5434#ifdef LOG_NOTICE
5435 { N_("notice"), LOG_NOTICE },
5436#endif
5437#ifdef LOG_EMERG
5438 { N_("panic"), LOG_EMERG }, /* DEPRECATED */
5439#endif
5440#ifdef LOG_WARNING
5441 { N_("warn"), LOG_WARNING }, /* DEPRECATED */
5442#endif
5443#ifdef LOG_WARNING
5444 { N_("warning"), LOG_WARNING },
5445#endif
5446 { NULL, -1 }
5447};
5448
5449static int enable_syslog_socket = S_FALSE;
5450
5451static int recv_syslog_socket (int fd)
5452{
5453 static time_t return_next = 0;
5454 int priority = 0;
5455 int fac, pri;
5456 int i;
5457 char * cfac = NULL;
5458 char * cpri = NULL;
5459 int res;
5460 char * tmp;
5461 char * bptr;
5462 char * ptr = NULL;
5463 char buf[1048];
5464 struct sockaddr_in from;
5465
5466 /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
5467 * but *int everywhere else. Because socklen_t is unsigned int, there
5468 * should be no problem as long as sizeof(struct sockaddr_in) < INT_MAX ...
5469 */
5470 int fromlen = sizeof(from);
5471
5472 if (enable_syslog_socket == S_FALSE)
5473 return 0;
5474
5475 SL_ENTER(_("recv_syslog_socket"));
5476
5477 if (return_next > 0)
5478 {
5479 if ( (time(NULL) - return_next) < 2)
5480 SL_RETURN( 0, _("recv_syslog_socket"));
5481 else
5482 return_next = 0;
5483 }
5484
5485 res = recvfrom(fd, buf, 1047, 0, (struct sockaddr *) &from, &fromlen);
5486
5487 if (res > 0)
5488 {
5489 res = (res < 1047) ? res : 1047;
5490 buf[res] = '\0';
5491 if (res > 1 && buf[res-1] == '\n')
5492 buf[res-1] = '\0';
5493
5494 /* here we expect an xml formatted message, thus we don't
5495 escape xml special chars (flag == 0) */
5496 /* commented out to not escape twice */
5497 /* bptr = sh_tools_safe_name(buf, 0); */
5498 bptr = buf;
5499
5500 if (!bptr || !(*bptr))
5501 {
5502 res = errno;
5503 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5504 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5505 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5506 SL_RETURN( (-1), _("recv_syslog_socket"));
5507 }
5508
5509 TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
5510 my_inet_ntoa(from.sin_addr)));
5511 ptr = bptr;
5512 i = 0;
5513 if (*ptr == '<')
5514 {
5515 ++ptr; ++i;
5516 while (i < res &&
5517 (unsigned char) *ptr > 47 && (unsigned char) *ptr < 58)
5518 {
5519 priority = 10 * priority + (*ptr - '0');
5520 ++ptr;
5521 ++i;
5522 }
5523 if (*ptr == '>')
5524 ++ptr;
5525 }
5526 fac = LOG_FAC(priority);
5527 i = 0;
5528 while (sh_facilitynames[i].c_name != NULL)
5529 {
5530 if (sh_facilitynames[i].c_val == (fac<<3))
5531 { cfac = sh_util_strdup(_(sh_facilitynames[i].c_name)); break; }
5532 ++i;
5533 }
5534 pri = LOG_PRI(priority);
5535 i = 0;
5536 while (sh_prioritynames[i].c_name != NULL)
5537 {
5538 if (sh_prioritynames[i].c_val == pri)
5539 { cpri = sh_util_strdup(_(sh_prioritynames[i].c_name)); break; }
5540 ++i;
5541 }
5542
5543 /* here we do not expect an xml formatted message, thus we escape
5544 xml special chars (flag == 1) */
5545 tmp = sh_tools_safe_name (ptr, 1);
5546 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_INET_SYSLOG,
5547 my_inet_ntoa(from.sin_addr),
5548 (cfac == NULL) ? _("none") : cfac,
5549 (cpri == NULL) ? _("none") : cpri,
5550 (ptr == NULL) ? _("none") : ptr);
5551 if (cfac != NULL)
5552 SH_FREE(cfac);
5553 if (cpri != NULL)
5554 SH_FREE(cpri);
5555 SH_FREE(tmp);
5556 /* SH_FREE(bptr); */
5557 }
5558
5559 else if (res < 0 && errno != EINTR)
5560 {
5561 res = errno;
5562 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5563 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5564 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5565
5566 /* don't accept anything the next 2 seconds
5567 */
5568 return_next = time(NULL);
5569 SL_RETURN( (-1), _("recv_syslog_socket"));
5570 }
5571 SL_RETURN( (0), _("recv_syslog_socket"));
5572}
5573
5574int set_syslog_active(char * c)
5575{
5576 return sh_util_flagval(c, &enable_syslog_socket);
5577}
5578
5579/* callerFlag == S_TRUE means override the enable_syslog_socket flag
5580 */
5581int create_syslog_socket (int callerFlag)
5582{
5583 int flag = 1; /* non-zero to enable an option */
5584 int sock;
5585 int errnum;
5586 int res;
5587 struct sockaddr_in addr;
5588 int addrlen = sizeof(addr);
5589
5590 SL_ENTER(_("create_syslog_socket"));
5591
5592 if (callerFlag == S_FALSE)
5593 {
5594 if (enable_syslog_socket == S_FALSE && syslog_sock >= 0)
5595 {
5596 /* user does not wish to use this facility
5597 */
5598 TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
5599 close(syslog_sock);
5600 syslog_sock = -1;
5601 }
5602 SL_RETURN((-1), _("create_syslog_socket"));
5603 }
5604
5605 sh_forward_printerr (NULL, 0, 514, __LINE__);
5606
5607 /* create the socket, bind() it and listen()
5608 */
5609 sock = socket(AF_INET, SOCK_DGRAM, 0);
5610
5611 if (sock < 0)
5612 {
5613 errnum = errno;
5614 sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
5615 SL_RETURN((-1), _("create_syslog_socket"));
5616 }
5617 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
5618
5619 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5620 (void *) &flag, sizeof(flag)) < 0 )
5621 {
5622 errnum = errno;
5623 sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
5624 errnum, 514, __LINE__);
5625 SL_RETURN((-1), _("create_syslog_socket"));
5626 }
5627
5628#if defined(SO_BSDCOMPAT)
5629 if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
5630 (void *) &flag, sizeof(flag)) < 0 )
5631 {
5632 errnum = errno;
5633 sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
5634 errnum, 514, __LINE__);
5635 SL_RETURN((-1), _("create_syslog_socket"));
5636 }
5637#endif
5638
5639 memset(&addr, 0, sizeof(addr));
5640 addr.sin_family = AF_INET;
5641 addr.sin_port = htons(514);
5642
5643 res = bind(sock, (struct sockaddr *) &addr, addrlen);
5644
5645 if ( res < 0)
5646 {
5647 errnum = errno;
5648 sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
5649 close(sock);
5650 SL_RETURN((-1), _("create_syslog_socket"));
5651 }
5652
5653 syslog_sock = sock;
5654
5655 SL_RETURN((sock), _("create_syslog_socket"));
5656}
5657/* #ifdef INET_SYSLOG */
5658#endif
5659
5660
5661
5662/* #ifdef SH_WITH_SERVER */
5663#endif
5664
5665
5666
5667
5668
5669
Note: See TracBrowser for help on using the repository browser.