source: trunk/src/sh_forward.c@ 25

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

Minor code revisions.

File size: 140.8 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 (const 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 (const 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 (const 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 (const 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 (const 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 (const 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 (const 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
1952
1953int sh_forward_register_client (const char * str)
1954{
1955 client_t * newclt;
1956 client_t * testclt;
1957
1958 const char * ptr;
1959 int sepnum = 0;
1960 int sep[2];
1961 register int i = 0;
1962 int siz_str = 0;
1963
1964 SL_ENTER(_("sh_forward_register_client"));
1965
1966 ptr = str;
1967 while (*ptr) {
1968 if (*ptr == '@' && sepnum < 2 )
1969 {
1970 sep[sepnum] = i;
1971 ++sepnum;
1972 }
1973 ++ptr; ++i;
1974 }
1975
1976 if (all_clients == NULL)
1977 {
1978 all_clients = zAVLAllocTree (sh_avl_key);
1979 if (all_clients == NULL)
1980 {
1981 (void) safe_logger (0, 0, NULL);
1982 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
1983 }
1984 }
1985
1986 if (sepnum == 2 && sep[0] > 0)
1987 {
1988 newclt = SH_ALLOC (sizeof(client_t));
1989 newclt->hostname = SH_ALLOC (sep[0]+1);
1990 newclt->salt = SH_ALLOC (sep[1]-sep[0]);
1991 newclt->verifier = SH_ALLOC (sl_strlen(str)-sep[1]+1);
1992 newclt->exit_flag = 0;
1993 newclt->dead_flag = 0;
1994#ifdef SH_ENCRYPT
1995#ifdef SH_ENCRYPT_2
1996 newclt->encf_flag = SH_PROTO_ENC|SH_PROTO_EN2;
1997 newclt->ency_flag = SH_PROTO_ENC|SH_PROTO_EN2;
1998#else
1999 newclt->encf_flag = SH_PROTO_ENC;
2000 newclt->ency_flag = SH_PROTO_ENC;
2001#endif
2002#else
2003 newclt->encf_flag = 0;
2004 newclt->ency_flag = 0;
2005#endif
2006 newclt->session_key[0] = '\0';
2007 newclt->last_connect = (time_t) 0;
2008 newclt->session_key_timer = (time_t) 0;
2009 newclt->status_now = CLT_INACTIVE;
2010 for (i = 0; i < CLT_MAX; ++i)
2011 newclt->status_arr[i] = CLT_INACTIVE;
2012 sl_strlcpy(newclt->timestamp[CLT_INACTIVE], sh_unix_time(0), TIM_MAX);
2013 /* truncate */
2014 sl_strlcpy(newclt->hostname, &str[0], sep[0]+1);
2015 /* truncate */
2016 sl_strlcpy(newclt->salt, &str[sep[0]+1], sep[1]-sep[0]);
2017 sl_strlcpy(newclt->verifier, &str[sep[1]+1], sl_strlen(str)-sep[1]+1);
2018
2019 testclt = (client_t *) zAVLSearch (all_clients, newclt->hostname);
2020
2021 if (testclt != NULL)
2022 {
2023 SH_FREE(testclt->verifier);
2024 siz_str = strlen (newclt->verifier) + 1;
2025 testclt->verifier = SH_ALLOC (siz_str);
2026 sl_strlcpy(testclt->verifier, newclt->verifier, siz_str);
2027
2028 SH_FREE(testclt->salt);
2029 siz_str = strlen (newclt->salt) + 1;
2030 testclt->salt = SH_ALLOC (siz_str);
2031 sl_strlcpy(testclt->salt, newclt->salt, siz_str);
2032
2033 testclt->dead_flag = 0;
2034
2035 free_client(newclt);
2036 SL_RETURN( 0, _("sh_forward_register_client"));
2037 }
2038 else
2039 {
2040 if (0 == zAVLInsert (all_clients, newclt))
2041 {
2042 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CREG,
2043 newclt->hostname,
2044 newclt->salt, newclt->verifier);
2045 SL_RETURN( 0, _("sh_forward_register_client"));
2046 }
2047 }
2048 }
2049 SL_RETURN (-1, _("sh_forward_register_client"));
2050}
2051
2052typedef struct {
2053 int state;
2054 int fd;
2055 char * buf;
2056 unsigned char head[SH_HEADER_SIZE];
2057 char challenge[SH_CHALLENGE_SIZE];
2058 char peer[SH_MINIBUF+1];
2059 client_t * client_entry;
2060 char * K;
2061 char * M1;
2062 char * A;
2063 int headcount;
2064 unsigned long bytecount;
2065 unsigned long bytes_to_send;
2066 unsigned long bytes_to_get;
2067 int pass;
2068 unsigned long timer;
2069
2070 char * FileName;
2071 unsigned long FileLength;
2072 unsigned long FileSent;
2073 char FileType[5];
2074
2075 struct sockaddr_in addr_peer;
2076} sh_conn_t;
2077
2078
2079static char zap_challenge[SH_CHALLENGE_SIZE] = { 0 };
2080
2081void sh_forward_do_free (sh_conn_t * conn)
2082{
2083 SL_ENTER(_("sh_forward_do_free"));
2084
2085 if (conn->K != NULL)
2086 {
2087 SH_FREE(conn->K);
2088 conn->K = NULL;
2089 }
2090 if (conn->A != NULL)
2091 {
2092 SH_FREE(conn->A);
2093 conn->A = NULL;
2094 }
2095 if (conn->M1 != NULL)
2096 {
2097 SH_FREE(conn->M1);
2098 conn->M1 = NULL;
2099 }
2100 if (conn->buf != NULL)
2101 {
2102 SH_FREE(conn->buf);
2103 conn->buf = NULL;
2104 }
2105 if (conn->fd != (-1))
2106 {
2107 close (conn->fd);
2108 conn->fd = -1;
2109 }
2110 memcpy(conn->challenge, zap_challenge, SH_CHALLENGE_SIZE);
2111 conn->state = CONN_FREE;
2112 conn->headcount = 0;
2113 conn->bytecount = 0;
2114 conn->bytes_to_send = 0;
2115 conn->bytes_to_get = 0;
2116 conn->pass = 0;
2117 conn->timer = 0;
2118 conn->client_entry = NULL;
2119
2120 if (conn->FileName != NULL)
2121 {
2122 SH_FREE(conn->FileName);
2123 conn->FileName = NULL;
2124 }
2125 conn->FileLength = 0;
2126 conn->FileSent = 0;
2127 conn->FileType[0] = '\0';
2128 conn->FileType[1] = '\0';
2129 conn->FileType[2] = '\0';
2130 conn->FileType[3] = '\0';
2131 conn->FileType[4] = '\0';
2132
2133 --server_status.conn_open;
2134
2135 SL_RET0(_("sh_forward_do_free"));
2136}
2137
2138/****************************************
2139 *
2140 * -- Reconfiguration. --
2141 *
2142 * (1) Mark all clients as 'dead'.
2143 * (2) Reload configuration - clients
2144 * in config are non-dead now.
2145 * (3) Remove all clients still
2146 * marked as 'dead'.
2147 */
2148
2149/* -- Mark all clients as dead.
2150 */
2151void sh_forward_mark_dead ()
2152{
2153 zAVLCursor avlcursor;
2154 client_t * item;
2155
2156 SL_ENTER(_("sh_forward_mark_dead"));
2157
2158 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2159 item = (client_t *) zAVLNext(&avlcursor))
2160 {
2161 item->dead_flag = 1;
2162 }
2163 SL_RET0(_("sh_forward_mark_dead"));
2164}
2165
2166
2167/* -- Clean tree from dead clients.
2168 */
2169void sh_forward_clean_tree ()
2170{
2171 zAVLCursor avlcursor;
2172 client_t * item;
2173
2174 SL_ENTER(_("sh_forward_clean_tree"));
2175
2176 repeat_search:
2177
2178 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2179 item = (client_t *) zAVLNext(&avlcursor))
2180 {
2181 if (item->dead_flag == 1)
2182 {
2183 zAVLDelete (all_clients, item->hostname);
2184 free_client (item);
2185 goto repeat_search;
2186 }
2187 }
2188 SL_RET0(_("sh_forward_clean_tree"));
2189}
2190
2191/*
2192 *
2193 **********************************************/
2194
2195
2196
2197/* -- SERVER SEND FUNKTION. --
2198 */
2199void sh_forward_prep_send_int (sh_conn_t * conn,
2200 char * msg, unsigned long length,
2201 char * u, char protocol,
2202 int docrypt)
2203{
2204 register unsigned long i;
2205 unsigned long length2;
2206
2207#ifdef SH_ENCRYPT
2208 unsigned long blkfac = 0;
2209 int rem = 0;
2210 char * p, * q;
2211 RIJ_BYTE inBlock[B_SIZ];
2212 RIJ_BYTE outBlock[B_SIZ];
2213 unsigned int j;
2214 cipherInstance cipherInst;
2215 int err_num;
2216#else
2217 (void) docrypt;
2218#endif
2219
2220 SL_ENTER(_("sh_forward_prep_send_int"));
2221
2222 TPT((0, FIL__, __LINE__, _("msg=<%s>, docrypt=<%d>\n"), msg, docrypt ));
2223
2224#ifdef SH_ENCRYPT
2225 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0) )
2226 {
2227 length2 = length;
2228 }
2229 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0) )
2230 {
2231 blkfac = length/B_SIZ;
2232 rem = length - (B_SIZ * blkfac);
2233 length2 = (B_SIZ * blkfac) + ((rem == 0) ? 0 : B_SIZ);
2234 }
2235 else
2236 {
2237 length2 = length;
2238 }
2239#else
2240 length2 = length;
2241#endif
2242
2243 conn->headcount = 0;
2244 conn->bytecount = 0;
2245 conn->bytes_to_send = 0;
2246 conn->bytes_to_get = 0;
2247
2248 if (conn->buf != NULL)
2249 {
2250 SH_FREE(conn->buf);
2251 conn->buf = NULL;
2252 }
2253
2254
2255 put_header (conn->head, protocol, &length2, u);
2256 SH_SHOWPROT(conn->head,'>');
2257
2258 TPT((0, FIL__, __LINE__, _("msg=<put_header done>\n") ));
2259
2260 if (msg == NULL)
2261 length2 = 0;
2262
2263#ifdef SH_ENCRYPT
2264 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0))
2265 {
2266 TPT((0, FIL__, __LINE__, _("encrypting (version 2)\n")));
2267
2268 conn->buf = sh_tools_makePack (conn->head, msg, length2,
2269 &(conn->client_entry->keyInstE));
2270 }
2271 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
2272 {
2273 conn->buf = SH_ALLOC(length2 + 1);
2274
2275 p = msg;
2276 q = conn->buf;
2277
2278 TPT((0, FIL__, __LINE__, _("encrypting (version 1)\n")));
2279
2280 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
2281 if (err_num < 0)
2282 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2283 errorExplain(err_num),
2284 _("sh_forward_prep_send_int: cipherInit"));
2285
2286 for (j = 0; j < blkfac; ++j)
2287 {
2288 memcpy(inBlock, p, B_SIZ);
2289 err_num = blockEncrypt(&cipherInst, &(conn->client_entry->keyInstE),
2290 inBlock, 128 * BNUM, outBlock);
2291 if (err_num < 0)
2292 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2293 errorExplain(err_num),
2294 _("sh_forward_prep_send_int: blockEncrypt"));
2295 memcpy(q, outBlock, B_SIZ);
2296 p += B_SIZ;
2297 q += B_SIZ;
2298 }
2299 if (rem > 0)
2300 {
2301 /* incomplete block at end
2302 */
2303 memset(inBlock, '\0', B_SIZ);
2304 memcpy(inBlock, p, rem);
2305 err_num = blockEncrypt(&cipherInst, &(conn->client_entry->keyInstE),
2306 inBlock, 128 * BNUM, outBlock);
2307 if (err_num < 0)
2308 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2309 errorExplain(err_num),
2310 _("sh_forward_prep_send_int: blockEncrypt"));
2311 memcpy(q, outBlock, B_SIZ);
2312 q += B_SIZ;
2313 }
2314
2315 TPT((0, FIL__, __LINE__, _("msg=<encryption done>\n") ));
2316 }
2317 else
2318 {
2319 conn->buf = SH_ALLOC(length2 + 1);
2320
2321 for (i = 0; i < length2; ++i)
2322 conn->buf[i] = msg[i];
2323 conn->buf[length2] = '\0';
2324 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2325 }
2326#else
2327 conn->buf = SH_ALLOC(length2 + 1);
2328
2329 for (i = 0; i < length; ++i)
2330 conn->buf[i] = msg[i];
2331 conn->buf[length2] = '\0';
2332 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2333#endif
2334
2335 conn->state = CONN_SENDING;
2336 SL_RET0(_("sh_forward_prep_send_int"));
2337}
2338
2339/* -- Send/Receive. --
2340 */
2341void sh_forward_prep_send (sh_conn_t * conn,
2342 char * msg, unsigned long length,
2343 char * u, char protocol)
2344{
2345 SL_ENTER(_("sh_forward_prep_send"));
2346 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_FALSE);
2347 SL_RET0(_("sh_forward_prep_send"));
2348}
2349
2350void sh_forward_prep_send_crypt (sh_conn_t * conn,
2351 char * msg, unsigned long length,
2352 char * u, char protocol)
2353{
2354 SL_ENTER(_("sh_forward_prep_send_crypt"));
2355 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_TRUE);
2356 SL_RET0(_("sh_forward_prep_send_crypt"));
2357}
2358
2359/* #include <sys/times.h> */
2360
2361#if defined(WITH_EXTERNAL)
2362#include "sh_extern.h"
2363#endif
2364
2365/* -- Update the client status. --
2366 *
2367 * Update the status array for the client,
2368 * and eventually call external program.
2369 */
2370static void status_update (client_t * conn, int status)
2371{
2372#if defined(WITH_EXTERNAL)
2373 char msg[2 * SH_MINIBUF + TIM_MAX + 3];
2374#endif
2375
2376 SL_ENTER(_("status_update"));
2377
2378 if (conn == NULL ||
2379 status < 0 || status >= CLT_MAX)
2380 SL_RET0(_("status_update"));
2381
2382 conn->status_now = status;
2383 conn->status_arr[status] = status;
2384 sl_strlcpy(conn->timestamp[status],
2385 sh_unix_time(0),
2386 TIM_MAX);
2387
2388#if defined(WITH_EXTERNAL)
2389 sl_snprintf(msg, sizeof(msg), _("%s %s %s"),
2390 conn->hostname, conn->timestamp[status], _(clt_stat[status]));
2391 sh_ext_execute('s', 'r', 'v', msg, 0);
2392#endif
2393
2394 SL_RET0(_("status_update"));
2395}
2396
2397static time_t time_client_limit = 86400;
2398
2399int sh_forward_set_time_limit (const char * c)
2400{
2401 long val;
2402
2403 SL_ENTER(_("sh_forward_set_time_limit"));
2404
2405 val = strtol (c, (char **)NULL, 10);
2406 if (val <= 0)
2407 SL_RETURN( (-1), _("sh_forward_set_time_limit"));
2408
2409 val = (val < 0 ? 0 : val);
2410
2411 time_client_limit = (time_t) val;
2412 SL_RETURN( (0), _("sh_forward_set_time_limit"));
2413}
2414
2415
2416/* -- Check for time limit exceeded. --
2417 */
2418static int client_time_check()
2419{
2420 zAVLCursor avlcursor;
2421 client_t * item;
2422
2423 SL_ENTER(_("client_time_check"));
2424
2425 if (time_client_limit == (time_t) 0)
2426 SL_RETURN( 0, _("client_time_check"));
2427
2428 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2429 item = (client_t *) zAVLNext(&avlcursor))
2430 {
2431 if (item->exit_flag == 0 && item->last_connect != (time_t) 0)
2432 {
2433 if ( (time(NULL) - item->last_connect) > time_client_limit)
2434 {
2435 if (item->status_now != CLT_TOOLONG)
2436 {
2437 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMEXC,
2438 item->hostname);
2439 status_update (item, CLT_TOOLONG);
2440 }
2441 }
2442 }
2443 }
2444 SL_RETURN( 0, _("client_time_check"));
2445}
2446
2447static int lookup_err = SH_ERR_SEVERE;
2448
2449int sh_forward_lookup_level (const char * c)
2450{
2451 int ci = sh_error_convert_level (c);
2452
2453 SL_ENTER(_("sh_forward_lookup_level"));
2454
2455 if (ci >= 0)
2456 {
2457 lookup_err = ci;
2458 SL_RETURN( 0, _("sh_forward_lookup_level"));
2459 }
2460 else
2461 SL_RETURN( (-1), _("sh_forward_lookup_level"));
2462}
2463
2464#ifndef MAXHOSTNAMELEN
2465#define MAXHOSTNAMELEN 127
2466#endif
2467
2468int check_addr (const char * claim, struct sockaddr_in addr_peer)
2469{
2470 char h_name[MAXHOSTNAMELEN + 1];
2471 char h_peer[MAXHOSTNAMELEN + 1];
2472 char h_peer_IP[16];
2473 char tmp_peer_IP[16];
2474 struct hostent * he;
2475 char ** p = NULL;
2476 int i;
2477 int flag = 0;
2478
2479 SL_ENTER(_("check_addr"));
2480
2481 if (claim == NULL)
2482 {
2483 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2484 _("NULL input"), _("check_addr"));
2485 SL_RETURN ((-1), _("check_addr"));
2486 }
2487
2488 /* Make sure we have the canonical name for the client
2489 */
2490 he = sh_gethostbyname (claim);
2491
2492 if (he != NULL && he->h_name != NULL)
2493 {
2494 if (NULL == strchr(he->h_name, '.') && he->h_addr_list != NULL)
2495 {
2496 he = sh_gethostbyaddr(he->h_addr_list[0],
2497 he->h_length,
2498 he->h_addrtype);
2499 }
2500 }
2501
2502 /* copy canonical name into h_name
2503 */
2504 if (he != NULL && he->h_name != NULL)
2505 sl_strlcpy(h_name, he->h_name, MAXHOSTNAMELEN + 1);
2506 else
2507 {
2508 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESCLT,
2509 claim);
2510 SL_RETURN ((0), _("check_addr"));
2511 }
2512
2513
2514 /* get canonical name of socket peer
2515 */
2516 he = sh_gethostbyaddr ((char *) &(addr_peer.sin_addr),
2517 sizeof(addr_peer.sin_addr),
2518 AF_INET);
2519
2520 if (he != NULL && he->h_name != NULL)
2521 {
2522 if (0 == sl_strcmp(he->h_name, _("localhost")))
2523 sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
2524 else
2525 sl_strlcpy(h_peer, he->h_name, MAXHOSTNAMELEN + 1);
2526 }
2527 else
2528 {
2529 sl_strlcpy(tmp_peer_IP,
2530 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2531 16);
2532 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
2533 claim, tmp_peer_IP);
2534 SL_RETURN ((0), _("check_addr"));
2535 }
2536
2537 sl_strlcpy(h_peer_IP,
2538 inet_ntoa (*(struct in_addr *) he->h_addr),
2539 16);
2540
2541#if 0
2542 if (S_FALSE == DoReverseLookup)
2543 {
2544 SL_RETURN ((0), _("check_addr"));
2545 }
2546#endif
2547
2548 /* reverse lookup
2549 */
2550 if (0 != sl_strncmp(_("127."),
2551 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2552 4))
2553 {
2554 he = sh_gethostbyname(h_peer);
2555
2556 if (he != NULL)
2557 {
2558 for (p = he->h_addr_list; *p; ++p)
2559 {
2560 if (0 == memcmp (*p, &(addr_peer.sin_addr),
2561 sizeof(addr_peer.sin_addr)))
2562 break;
2563 ++i;
2564 }
2565 }
2566 if (he == NULL || *p == NULL)
2567 {
2568 sl_strlcpy(tmp_peer_IP,
2569 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2570 16);
2571 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
2572 claim, h_peer, tmp_peer_IP);
2573 SL_RETURN ((0), _("check_addr"));
2574 }
2575 }
2576
2577
2578 if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
2579 {
2580 SL_RETURN ((0), _("check_addr"));
2581 }
2582 else
2583 {
2584 i = 0;
2585 while (he->h_aliases[i] != NULL)
2586 {
2587 if (0 == sl_strcmp(he->h_aliases[i], h_name))
2588 {
2589 flag = 1;
2590 break;
2591 }
2592 ++i;
2593 }
2594 if (flag == 0)
2595 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKUP,
2596 claim, h_peer);
2597 }
2598
2599 SL_RETURN ((0), _("check_addr"));
2600}
2601
2602static int UseSocketPeer = S_FALSE;
2603
2604int set_socket_peer (const char * c)
2605{
2606 return sh_util_flagval(c, &UseSocketPeer);
2607}
2608
2609
2610/* -- Search register. --
2611 */
2612client_t * search_register(sh_conn_t * conn, int pos)
2613{
2614 client_t * this_client;
2615 char peer_ip[16];
2616 char peer_name[MAXHOSTNAMELEN+1];
2617 char * search_string;
2618 struct sockaddr_in peer_addr;
2619 struct hostent * he;
2620 char ** p = NULL;
2621
2622 SL_ENTER(_("search_register"));
2623
2624 if (UseSocketPeer == S_TRUE)
2625 {
2626 peer_addr = conn->addr_peer;
2627 sl_strlcpy(peer_ip,
2628 inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
2629
2630 /* get canonical name of socket peer
2631 */
2632 he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr),
2633 sizeof(peer_addr.sin_addr),
2634 AF_INET);
2635
2636 if (he != NULL && he->h_name != NULL)
2637 {
2638 if (0 == sl_strcmp(he->h_name, _("localhost")))
2639 sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
2640 else
2641 sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
2642
2643 /* Reverse lookup
2644 */
2645 if (0 != sl_strncmp(peer_ip, _("127."), 4))
2646 {
2647 he = sh_gethostbyname(peer_name);
2648
2649 if (he != NULL)
2650 {
2651 for (p = he->h_addr_list; *p; ++p)
2652 {
2653 if (0 == memcmp (*p, &(peer_addr.sin_addr),
2654 sizeof(peer_addr.sin_addr)))
2655 break;
2656 }
2657 }
2658 if (he == NULL || *p == NULL)
2659 {
2660 /*
2661 sh_error_handle(lookup_err, FIL__, __LINE__, 0,
2662 MSG_TCP_LOOKERS,
2663 conn->buf[pos], peer_name, peer_ip);
2664 */
2665 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2666 }
2667 }
2668 }
2669 else
2670 {
2671 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2672 }
2673 search_string = peer_name;
2674 }
2675 else
2676 {
2677 search_string = &(conn->buf[pos]);
2678
2679 if (0 != check_addr (search_string, conn->addr_peer))
2680 {
2681 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2682 _("Reverse lookup failed"), search_string);
2683 sh_forward_do_free (conn);
2684 SL_RETURN( NULL, _("search_register"));
2685 }
2686 }
2687
2688 /* ---- search the register -----
2689 */
2690 this_client = zAVLSearch(all_clients, search_string);
2691
2692 if (this_client == NULL)
2693 {
2694 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2695 _("Not in client list"), search_string);
2696 sh_forward_do_free (conn);
2697 SL_RETURN( NULL, _("search_register"));
2698 }
2699 if (this_client->exit_flag == 1)
2700 {
2701 TPT((0, FIL__, __LINE__, _("msg=<this_client->exit_flag == 1>\n")));
2702 this_client->session_key_timer = (time_t) 0;
2703 this_client->session_key[0] = '\0';
2704 this_client->exit_flag = 0;
2705 }
2706 TPT((0, FIL__, __LINE__, _("msg=<search_register: client %s>\n"),
2707 this_client->hostname));
2708 TPT((0, FIL__, __LINE__, _("msg=<search_register: key %s>\n"),
2709 this_client->session_key));
2710 SL_RETURN( this_client, _("search_register"));
2711}
2712
2713
2714/************************************************************************
2715 *
2716 * Here we check the message received, and decide on the answer to send
2717 * (if any). The connection is in CONN_PAUSED state, thus we must:
2718 * (i) define the proper reaction
2719 * (ii) reset to CONN_READING or CONN_WRITING or CONN_FREE
2720 * (iii) eventually reset the connection entry
2721 *
2722 *************************************************************************/
2723static
2724void check_protocol(sh_conn_t * conn, int state)
2725{
2726 client_t * this_client;
2727
2728 char * cmd;
2729
2730 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
2731 char * buffer;
2732
2733 int clt_sev;
2734 char * ptok;
2735
2736 UINT32 ticks;
2737 size_t len;
2738 int i;
2739 char * test;
2740 char u[5] = "OOOO";
2741
2742 SL_TICKET sfd = -1;
2743 char * read_buf = 0;
2744 char * send_buf;
2745 int bytes;
2746
2747#ifdef SH_ENCRYPT
2748 int blkfac;
2749 int rem;
2750 int send_bytes;
2751 int err_num;
2752#endif
2753
2754
2755#ifdef USE_SRP_PROTOCOL
2756 char * foo_B;
2757 char * foo_Ss;
2758#endif
2759
2760 SL_ENTER(_("check_protocol"));
2761
2762 /* seed / re-seed the PRNG if required
2763 */
2764 (void) taus_seed();
2765
2766
2767 /* protocols:
2768 * -- (iii) file transfer
2769 * -- (ii) authenticated message transfer
2770 * -- (i) SRP key exchange
2771 */
2772
2773 /* --------- FILE TRANSFER -----------
2774 */
2775 if ( (conn->head[0] & SH_PROTO_SRP) == 0 &&
2776 (conn->head[0] & SH_PROTO_BIG) != 0 /* is set */ )
2777 {
2778
2779 if (state == SH_DO_READ) /* finished reading */
2780 {
2781 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
2782
2783 /* -- Client requests challenge. --
2784 */
2785 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
2786 {
2787
2788 TPT(( 0, FIL__, __LINE__,
2789 _("msg=<File transfer - HELO (1).>\n")));
2790
2791 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN)
2792 {
2793 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
2794 sh_forward_do_free (conn);
2795 SL_RET0(_("check_protocol"));
2796 }
2797
2798 /* ---- search the register -----
2799 */
2800
2801 this_client = search_register (conn, KEY_LEN);
2802 if (this_client == NULL)
2803 SL_RET0(_("check_protocol"));
2804
2805 /* ---- force authentication -----
2806 */
2807
2808 if (this_client->session_key[0] == '\0' ||
2809 (time(NULL) - this_client->session_key_timer)
2810 > (time_t) TIMEOUT_KEY )
2811 {
2812 /* fake an auth request and jump there
2813 */
2814 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
2815 conn->head[3] = 'S';
2816 conn->head[4] = 'A';
2817 conn->head[5] = 'L';
2818 conn->head[6] = 'T';
2819 if (flag_err_info == SL_TRUE)
2820 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
2821 &(conn->buf[KEY_LEN]));
2822 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
2823 /* &(conn->buf[KEY_LEN]) is hostname */
2824 /* may overlap, thus only memmove is correct */
2825 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
2826 this_client->session_key[0] = '\0';
2827 this_client->session_key_timer = (time_t) 1;
2828 goto servInit;
2829 }
2830
2831 /* --- check whether hostname is properly signed ---
2832 */
2833 if (conn->K != NULL)
2834 {
2835 SH_FREE(conn->K);
2836 conn->K = NULL;
2837 }
2838 len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
2839 conn->K = SH_ALLOC(len);
2840
2841 sl_strlcpy (conn->K,
2842 sh_util_siggen(this_client->session_key,
2843 &(conn->buf[KEY_LEN]),
2844 sl_strlen(&(conn->buf[KEY_LEN]))),
2845 KEY_LEN+1);
2846 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
2847 &(conn->buf[KEY_LEN])));
2848 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
2849 this_client->session_key));
2850 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
2851 sh_util_siggen(this_client->session_key,
2852 &(conn->buf[KEY_LEN]),
2853 sl_strlen(&(conn->buf[KEY_LEN])))));
2854
2855 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
2856 {
2857 TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf));
2858 TPT((0, FIL__, __LINE__, _("msg=<srv %s>\n"), conn->K));
2859 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2860 _("Signature mismatch"),
2861 &(conn->buf[KEY_LEN]));
2862
2863 this_client->session_key_timer =
2864 time(NULL) - (2*TIMEOUT_KEY);
2865
2866 sh_forward_do_free (conn);
2867 SL_RET0(_("check_protocol"));
2868 }
2869 SH_FREE(conn->K);
2870 conn->K = NULL;
2871
2872 /* --- create and send a nonce ---
2873 */
2874
2875 conn->client_entry = this_client;
2876 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
2877
2878 ticks = (UINT32) taus_get (&(skey->rng0[0]),
2879 &(skey->rng1[0]),
2880 &(skey->rng2[0]));
2881 if (conn->K != NULL)
2882 {
2883 SH_FREE(conn->K);
2884 conn->K = NULL;
2885 }
2886 conn->K = SH_ALLOC(KEY_LEN+1);
2887 sl_strlcpy (conn->K,
2888 sh_tiger_hash ((char *) &ticks,
2889 TIGER_DATA, sizeof(UINT32)),
2890 KEY_LEN+1);
2891
2892 TPT((0, FIL__, __LINE__, _("msg=<send nonce>\n")));
2893 sh_forward_prep_send (conn, conn->K, KEY_LEN+1, _("NSRV"),
2894 SH_PROTO_BIG);
2895 }
2896
2897 /* --- Client has send a message. Check state and message. ---
2898 */
2899 else if (0 == check_request_nerr((char *)&(conn->head[3]), _("NCLT")) &&
2900 conn->client_entry != NULL &&
2901 sl_strlen(conn->buf) > KEY_LEN &&
2902 conn->K != NULL)
2903 {
2904
2905 TPT(( 0, FIL__, __LINE__,
2906 _("msg=<File transfer - NCLT (3).>\n")));
2907
2908 /* --- get client nonce and compute hash ---
2909 */
2910 if (conn->A != NULL)
2911 {
2912 SH_FREE(conn->A);
2913 conn->A = NULL;
2914 }
2915 conn->A = SH_ALLOC(3*KEY_LEN+1);
2916 sl_strlcpy (conn->A, conn->K, KEY_LEN+1);
2917 sl_strlcat(conn->A, conn->buf, /* truncate */
2918 2*KEY_LEN+1);
2919 sl_strlcat(conn->A, conn->client_entry->session_key,
2920 3*KEY_LEN+1);
2921 sl_strlcpy (conn->K, sh_tiger_hash(conn->A,TIGER_DATA,3*KEY_LEN),
2922 KEY_LEN+1);
2923 SH_FREE(conn->A);
2924 conn->A = NULL;
2925
2926
2927#ifdef SH_ENCRYPT
2928 if ((conn->client_entry->encf_flag != 0) &&
2929 ((conn->head[0] & SH_PROTO_ENC) == 0))
2930 {
2931 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
2932 _("file download"),
2933#ifdef SH_ENCRYPT_2
2934 _("version2"),
2935#else
2936 _("version1"),
2937#endif
2938 _("none"));
2939 if (sl_strlen(conn->buf) > (KEY_LEN + 5)) {
2940 if (sh_tools_hash_vfy(conn->K, conn->buf, KEY_LEN+5)) {
2941 if (conn->buf[KEY_LEN+4] == conn->head[0]) {
2942 /* conn->client_entry->encf_flag = 0 */ ; /* FIXME */
2943 }
2944 }
2945 }
2946 }
2947 else if ((conn->client_entry->encf_flag != 0) &&
2948 ((conn->head[0] & SH_MASK_ENC) !=
2949 conn->client_entry->encf_flag))
2950 {
2951 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
2952 MSG_TCP_MISENC,
2953 _("file download"),
2954#ifdef SH_ENCRYPT_2
2955 _("version2"),
2956#else
2957 _("version1"),
2958#endif
2959 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1")
2960 );
2961 conn->client_entry->encf_flag =
2962 (conn->head[0] & SH_MASK_ENC);
2963 }
2964#else
2965 if ((conn->head[0] & SH_PROTO_ENC) != 0)
2966 {
2967 sh_error_handle((-1), FIL__, __LINE__, 0,
2968 MSG_TCP_MISENC,
2969 _("file download"),
2970 _("none"),
2971 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
2972 }
2973#endif
2974
2975
2976 /* ---- K = H(NSRV, NCLT, session_key) -------
2977 */
2978
2979 if (conn->FileName != NULL)
2980 {
2981 SH_FREE(conn->FileName);
2982 conn->FileName = NULL;
2983 }
2984
2985 if (0 == sl_strncmp (_("CONF"), &(conn->buf[KEY_LEN]), 4))
2986 {
2987 strcpy(conn->FileType, _("CONF")); /* known to fit */
2988 conn->FileName = get_client_conf_file(conn->peer,
2989 &(conn->FileLength));
2990 conn->FileSent = 0;
2991 }
2992 else if (0 == sl_strncmp (_("DATA"), &(conn->buf[KEY_LEN]), 4))
2993 {
2994 strcpy(conn->FileType, _("DATA")); /* known to fit */
2995 conn->FileName = get_client_data_file(conn->peer,
2996 &(conn->FileLength));
2997 conn->FileSent = 0;
2998 }
2999 else
3000 {
3001 ptok = sh_util_safe_name(&(conn->buf[KEY_LEN]));
3002 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FFILE,
3003 conn->peer,
3004 ptok);
3005 SH_FREE(ptok);
3006 status_update (conn->client_entry, CLT_FAILED);
3007 sh_forward_do_free (conn);
3008 }
3009
3010 bytes = -1;
3011
3012 if (conn != NULL && conn->FileName != NULL)
3013 {
3014 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3015 if (!SL_ISERROR(sfd))
3016 {
3017 read_buf = SH_ALLOC(TRANS_BYTES);
3018 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3019 sl_close(sfd);
3020 }
3021
3022 else
3023 {
3024 sh_error_handle((-1), FIL__, __LINE__, sfd,
3025 MSG_E_ACCESS,
3026 (long) geteuid(),
3027 conn->FileName);
3028 }
3029 if (bytes >= 0)
3030 {
3031#ifdef SH_ENCRYPT
3032 /* need to send N * B_SIZ bytes
3033 */
3034 blkfac = bytes / B_SIZ;
3035 rem = bytes - (blkfac * B_SIZ);
3036 if (rem != 0)
3037 {
3038 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3039 ++blkfac;
3040 send_bytes = blkfac * B_SIZ;
3041 }
3042 else
3043 send_bytes = bytes;
3044
3045 send_buf = hash_me(conn->K, read_buf,
3046 send_bytes);
3047
3048 sh_forward_prep_send_crypt (conn, send_buf,
3049 send_bytes+KEY_LEN,
3050 _("FILE"),
3051 SH_PROTO_BIG|conn->client_entry->encf_flag);
3052#else
3053 send_buf = hash_me(conn->K, read_buf, bytes);
3054 sh_forward_prep_send_crypt (conn, send_buf,
3055 bytes+KEY_LEN,
3056 _("FILE"), SH_PROTO_BIG);
3057#endif
3058 conn->FileSent += bytes;
3059 if (send_buf != NULL)
3060 {
3061 SH_FREE(send_buf);
3062 }
3063 SH_FREE(read_buf);
3064 }
3065 }
3066
3067 if (conn == NULL || conn->FileName == NULL ||
3068 SL_ISERROR(sfd) || bytes < 0)
3069 {
3070 sh_error_handle((-1), FIL__, __LINE__, sfd, MSG_TCP_NFILE,
3071 conn->peer,
3072 (conn->FileName == NULL) ?
3073 _("(NULL)") : conn->FileName);
3074 status_update (conn->client_entry, CLT_FAILED);
3075 sh_forward_do_free (conn);
3076 }
3077
3078 }
3079
3080 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3081 _("RECV")) &&
3082 conn->client_entry != NULL &&
3083 conn->K != NULL &&
3084 conn->FileName != NULL)
3085 {
3086
3087 TPT(( 0, FIL__, __LINE__,
3088 _("msg=<File transfer - RCVT (5+).>\n")));
3089
3090 if (conn->FileSent == conn->FileLength)
3091 {
3092 send_buf = hash_me(conn->K, conn->peer,
3093 sl_strlen(conn->peer));
3094#ifdef SH_ENCRYPT
3095 sh_forward_prep_send_crypt (conn, send_buf,
3096 sl_strlen(conn->peer)+KEY_LEN,
3097 _("EEOT"),
3098 SH_PROTO_BIG|conn->client_entry->encf_flag);
3099#else
3100 sh_forward_prep_send_crypt (conn, send_buf,
3101 sl_strlen(conn->peer)+KEY_LEN,
3102 _("EEOT"),
3103 SH_PROTO_BIG);
3104#endif
3105 SH_FREE(send_buf);
3106 }
3107 else
3108 {
3109 bytes = -1;
3110 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3111 if (!SL_ISERROR(sfd))
3112 {
3113 read_buf = SH_ALLOC(TRANS_BYTES);
3114 sl_seek (sfd, (off_t) conn->FileSent);
3115 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3116 sl_close(sfd);
3117 }
3118 else
3119 {
3120 sh_error_handle((-1), FIL__, __LINE__, sfd,
3121 MSG_E_ACCESS,
3122 (long) geteuid(),
3123 conn->FileName);
3124 }
3125 if (bytes >= 0)
3126 {
3127#ifdef SH_ENCRYPT
3128 /* need to send N * B_SIZ bytes
3129 */
3130 blkfac = bytes / B_SIZ;
3131 rem = bytes - (blkfac * B_SIZ);
3132 if (rem != 0)
3133 {
3134 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3135 ++blkfac;
3136 send_bytes = blkfac * B_SIZ;
3137 }
3138 else
3139 send_bytes = bytes;
3140
3141 send_buf = hash_me(conn->K, read_buf,
3142 send_bytes);
3143
3144 sh_forward_prep_send_crypt (conn, send_buf,
3145 send_bytes+KEY_LEN,
3146 _("FILE"),
3147 SH_PROTO_BIG|conn->client_entry->encf_flag);
3148#else
3149
3150 send_buf = hash_me(conn->K, read_buf, bytes);
3151 sh_forward_prep_send_crypt (conn, send_buf,
3152 bytes+KEY_LEN,
3153 _("FILE"),
3154 SH_PROTO_BIG);
3155#endif
3156
3157 conn->FileSent += bytes;
3158 SH_FREE(send_buf);
3159 SH_FREE(read_buf);
3160 }
3161 else
3162 {
3163 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NFILE,
3164 conn->peer,
3165 (conn->FileName == NULL) ?
3166 _("(NULL)") : conn->FileName);
3167 status_update (conn->client_entry, CLT_FAILED);
3168 sh_forward_do_free (conn);
3169 }
3170 }
3171 }
3172
3173
3174 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3175 _("EOTE")) &&
3176 conn->client_entry != NULL)
3177 {
3178
3179 TPT(( 0, FIL__, __LINE__,
3180 _("msg=<File transfer - EOTE (7).>\n")));
3181
3182 if (flag_err_info == SL_TRUE)
3183 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKFILE,
3184 conn->peer);
3185
3186 if ((conn->client_entry->status_now != CLT_SUSPEND) &&
3187 (conn->client_entry->status_now != CLT_TOOLONG))
3188 { status_update (conn->client_entry, CLT_FILE); }
3189 else
3190 { conn->client_entry->session_key[0] = '\0'; }
3191 conn->client_entry->last_connect = time (NULL);
3192 sh_forward_do_free (conn);
3193 }
3194
3195
3196 /* client does something unexpected
3197 */
3198 else /* ---- ??? ----- */
3199 {
3200 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3201 1, conn->pass, conn->peer,
3202 '\\', conn->head[3], '\\',conn->head[4],
3203 '\\', conn->head[5], '\\',conn->head[6]);
3204 status_update (conn->client_entry, CLT_FAILED);
3205 sh_forward_do_free (conn);
3206 }
3207 }
3208
3209 else if (state == SH_DO_WRITE) /* finished writing */
3210 {
3211 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - (wait).>\n")));
3212
3213 /* challenge is sent, now wait for message from client
3214 */
3215 conn->headcount = 0;
3216 conn->bytecount = 0;
3217 conn->bytes_to_send = 0;
3218 conn->bytes_to_get = 0;
3219 if (conn->buf != NULL)
3220 {
3221 SH_FREE(conn->buf);
3222 conn->buf = NULL;
3223 }
3224 conn->state = CONN_READING;
3225 }
3226 SL_RET0(_("check_protocol"));
3227 }
3228
3229 /* --------- message exchange -----------
3230 */
3231 if ((conn->head[0] & SH_PROTO_SRP) == 0 &&
3232 (conn->head[0] & SH_PROTO_MSG) != 0 /* is set */ )
3233 {
3234
3235 if (state == SH_DO_READ) /* finished reading */
3236 {
3237
3238 TPT(( 0, FIL__, __LINE__, _("msg=<Message transfer - entry.>\n")));
3239
3240 /* client requests challenge
3241 */
3242 if (0 == check_request_nerr ((char *)&(conn->head[3]), _("HELO")))
3243 {
3244
3245 TPT(( 0, FIL__, __LINE__,
3246 _("msg=<Message transfer - HELO (1).>\n")));
3247
3248 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN )
3249 {
3250 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3251 sh_forward_do_free (conn);
3252 SL_RET0(_("check_protocol"));
3253 }
3254
3255 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3256
3257 /* ---- search the register -----
3258 */
3259 this_client = search_register (conn, KEY_LEN);
3260 if (NULL == this_client)
3261 SL_RET0(_("check_protocol"));
3262
3263 /* ---- force authentication -----
3264 */
3265 if ( (this_client->session_key[0] == '\0') ||
3266 ((time(NULL)-this_client->session_key_timer)
3267 > (time_t) TIMEOUT_KEY)
3268 )
3269 {
3270
3271 /* fake an auth request and jump there
3272 */
3273 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
3274 conn->head[3] = 'S';
3275 conn->head[4] = 'A';
3276 conn->head[5] = 'L';
3277 conn->head[6] = 'T';
3278 if (flag_err_info == SL_TRUE)
3279 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
3280 &(conn->buf[KEY_LEN]));
3281 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
3282 /* &(conn->buf[KEY_LEN]) is hostname */
3283 /* may overlap, thus only memmove is correct */
3284 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
3285 this_client->session_key[0] = '\0';
3286 this_client->session_key_timer = (time_t) 1;
3287
3288 goto servInit;
3289 }
3290
3291 /* check whether hostname is properly signed
3292 */
3293 if (conn->K != NULL)
3294 {
3295 SH_FREE(conn->K);
3296 conn->K = NULL;
3297 }
3298 len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1;
3299 conn->K = SH_ALLOC(len);
3300
3301 sl_strlcpy (conn->K,
3302 sh_util_siggen(this_client->session_key,
3303 &(conn->buf[KEY_LEN]),
3304 sl_strlen(&(conn->buf[KEY_LEN]))),
3305 KEY_LEN+1);
3306 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
3307 &(conn->buf[KEY_LEN])));
3308 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
3309 this_client->session_key));
3310 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), conn->K));
3311
3312 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
3313 {
3314 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s>\n"), conn->buf));
3315 TPT(( 0, FIL__, __LINE__, _("msg=<Want %s>\n"), conn->K));
3316 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3317 _("Signature mismatch"),
3318 &(conn->buf[KEY_LEN]));
3319
3320 this_client->session_key_timer =
3321 time(NULL) - (2*TIMEOUT_KEY);
3322
3323 sh_forward_do_free (conn);
3324 SL_RET0(_("check_protocol"));
3325 }
3326 SH_FREE(conn->K);
3327 conn->K = NULL;
3328
3329 /* -- create a nonce and send it --
3330 */
3331
3332 conn->client_entry = this_client;
3333 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
3334
3335 ticks = (UINT32) taus_get (&(skey->rng0[0]),
3336 &(skey->rng1[0]),
3337 &(skey->rng2[0]));
3338 test = (char *) &ticks;
3339 sh_util_cpylong (conn->challenge, test, 4);
3340 conn->challenge[4] = '\0';
3341 for (i = 0; i < 4; ++i)
3342 if (conn->challenge[i] == '\0')
3343 conn->challenge[i] = 0x01;
3344
3345 sh_forward_prep_send (conn, conn->challenge, 5, _("TALK"),
3346 SH_PROTO_MSG);
3347 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s.>\n"),
3348 hu_trans(conn->challenge)));
3349 }
3350
3351 /* Client has send a message. Check whether we are in proper
3352 * state, and verify message.
3353 */
3354 else if (0 ==
3355 check_request_nerr((char *)&(conn->head[3]), _("MESG")) &&
3356 conn->client_entry != NULL &&
3357 conn->client_entry->session_key[0] != '\0' &&
3358 (len = sl_strlen(conn->buf) - KEY_LEN) > 0 &&
3359 sl_strlen(conn->challenge) == 4)
3360 {
3361 TPT(( 0, FIL__, __LINE__,
3362 _("msg=<Message transfer - MESG (3).>\n")));
3363
3364#ifdef SH_ENCRYPT
3365 if (conn->client_entry->encf_flag == 0) {
3366 conn->client_entry->ency_flag = 0;
3367 }
3368 if ((conn->client_entry->ency_flag != 0) &&
3369 ((conn->head[0] & SH_PROTO_ENC) == 0))
3370 {
3371 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3372 _("message transfer"),
3373#ifdef SH_ENCRYPT_2
3374 _("version2"),
3375#else
3376 _("version1"),
3377#endif
3378 _("none"));
3379 /* conn->client_entry->ency_flag = 0; */
3380 }
3381 else if ((conn->client_entry->ency_flag != 0) &&
3382 ((conn->head[0] & SH_MASK_ENC) !=
3383 conn->client_entry->ency_flag))
3384 {
3385 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3386 MSG_TCP_MISENC,
3387 _("message transfer"),
3388#ifdef SH_ENCRYPT_2
3389 _("version2"),
3390#else
3391 _("version1"),
3392#endif
3393 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3394 conn->client_entry->ency_flag =
3395 (conn->head[0] & SH_MASK_ENC);
3396 }
3397#else
3398 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3399 {
3400 sh_error_handle((-1), FIL__, __LINE__, 0,
3401 MSG_TCP_MISENC,
3402 _("message transfer"),
3403 _("none"),
3404 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3405 }
3406#endif
3407
3408 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3409 /* get hash from message end, truncate message
3410 */
3411 sl_strlcpy(hash, &(conn->buf[len]), KEY_LEN+1);
3412 conn->buf[len] = '\0';
3413
3414 /* verify hash
3415 */
3416 buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL);
3417 i = sl_strncmp(hash,
3418 sh_util_siggen(conn->client_entry->session_key,
3419 buffer,
3420 sl_strlen(buffer)),
3421 KEY_LEN);
3422 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3423 sh_util_siggen(conn->client_entry->session_key,
3424 buffer,
3425 sl_strlen(buffer))));
3426
3427
3428 if (0 != i)
3429 {
3430 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3431 status_update (conn->client_entry, CLT_FAILED);
3432 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3433 _("Msg signature mismatch"), conn->peer);
3434 conn->client_entry->session_key_timer =
3435 time(NULL) - (2*TIMEOUT_KEY);
3436 sh_forward_do_free (conn);
3437 SL_RET0(_("check_protocol"));
3438 }
3439 else
3440 {
3441 conn->client_entry->last_connect = time (NULL);
3442
3443 if (NULL != sl_strstr(conn->buf, _("EXIT")))
3444 {
3445 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3446 conn->client_entry->exit_flag = 1;
3447 status_update (conn->client_entry, CLT_EXITED);
3448 }
3449 else if (NULL != sl_strstr(conn->buf, _("PANIC")))
3450 {
3451 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3452 status_update (conn->client_entry, CLT_PANIC);
3453 }
3454 else if (NULL != sl_strstr(conn->buf, _("SUSPEND")))
3455 {
3456 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3457 status_update (conn->client_entry, CLT_SUSPEND);
3458 }
3459 else if (NULL != sl_strstr(conn->buf, _("POLICY")))
3460 {
3461 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3462 status_update (conn->client_entry, CLT_POLICY);
3463 }
3464 else if (NULL != sl_strstr(conn->buf,
3465 _("File check completed")))
3466 {
3467 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3468 status_update (conn->client_entry, CLT_CHECK);
3469 }
3470 else if (NULL != sl_strstr(conn->buf, _("START")))
3471 {
3472 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3473 sh_socket_add2reload (conn->client_entry->hostname);
3474 if (conn->client_entry->status_now == CLT_SUSPEND) {
3475 status_update (conn->client_entry, CLT_ILLEGAL);
3476 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3477 conn->peer);
3478 }
3479 else
3480 status_update (conn->client_entry, CLT_STARTED);
3481 }
3482 else
3483 {
3484 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3485 if (0 != sl_strcmp(conn->buf,
3486 _("Runtime configuration reloaded")))
3487 {
3488 sh_socket_add2reload (conn->client_entry->hostname);
3489 }
3490 status_update (conn->client_entry, CLT_MSG);
3491 }
3492
3493 TPT((0, FIL__, __LINE__, _("msg=<status updated>\n")));
3494 clt_sev = atoi(conn->buf);
3495 clt_class = (-1);
3496 ptok = strchr(conn->buf, '?');
3497 if (ptok != NULL)
3498 {
3499 ++ptok;
3500 if (ptok != NULL && sh.flag.client_class == S_TRUE)
3501 clt_class = atoi(ptok); /* is a global */
3502 ptok = strchr(ptok, '?');
3503 if (ptok != NULL)
3504 ++ptok;
3505 }
3506 if (sh.flag.client_severity == S_FALSE)
3507 clt_sev = (-1);
3508
3509 /* here we expect an xml formatted message, thus we don't
3510 escape xml special chars (flag == 0) */
3511 ptok =
3512 sh_tools_safe_name ((ptok!=NULL) ? ptok : conn->buf, 0);
3513
3514 /* push client name to error routine
3515 */
3516 sh_error_set_peer(sh_strip_domain (conn->peer));
3517 sh_error_handle(clt_sev, FIL__, __LINE__, 0, MSG_TCP_MSG,
3518 sh_strip_domain (conn->peer),
3519 ptok);
3520 sh_error_set_peer(NULL);
3521
3522 TPT((0, FIL__, __LINE__, _("msg=<%s>\n"), ptok));
3523 SH_FREE(ptok);
3524 clt_class = (-1);
3525 }
3526 memset(buffer, '\0', sl_strlen(buffer));
3527 SH_FREE(buffer);
3528
3529 /* SERVER CONF SEND
3530 */
3531 buffer = sh_util_strconcat(conn->buf,
3532 conn->challenge,
3533 NULL);
3534 sl_strlcpy(hash,
3535 sh_util_siggen ( conn->client_entry->session_key,
3536 buffer,
3537 sl_strlen(buffer)),
3538 KEY_LEN+1);
3539
3540 /* --- SERVER CMD --- */
3541 cmd = sh_socket_check (conn->peer);
3542
3543 if (cmd != NULL)
3544 {
3545 /* max cmd size is SH_MAXMSGLEN bytes
3546 */
3547 sl_strlcpy(&hash[KEY_LEN], cmd, SH_MAXMSGLEN);
3548 sl_strlcat(&hash[KEY_LEN],
3549 sh_util_siggen ( conn->client_entry->session_key,
3550 &hash[KEY_LEN],
3551 sl_strlen(&hash[KEY_LEN])),
3552 SH_MAXMSGLEN+KEY_LEN+1);
3553
3554 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <%s>\n"),
3555 &hash[KEY_LEN]));
3556
3557 } else {
3558
3559 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <[NULL]>\n")));
3560
3561 }
3562 /* --- SERVER CMD END --- */
3563
3564 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3565 sh_util_siggen(conn->client_entry->session_key,
3566 buffer,
3567 sl_strlen(buffer))));
3568
3569#ifdef SH_ENCRYPT
3570 sh_forward_prep_send_crypt (conn, hash,
3571 sl_strlen(hash) /* KEY_LEN */,
3572 _("CONF"),
3573 SH_PROTO_MSG|SH_PROTO_END|conn->client_entry->ency_flag);
3574#else
3575 sh_forward_prep_send_crypt (conn, hash,
3576 sl_strlen(hash) /* KEY_LEN */,
3577 _("CONF"),
3578 SH_PROTO_MSG|SH_PROTO_END);
3579#endif
3580
3581 memset(buffer, '\0', sl_strlen(buffer));
3582 SH_FREE(buffer);
3583
3584 /* sh_forward_do_free (conn); */
3585 }
3586
3587 /* client does something unexpected
3588 */
3589 else /* ---- ??? ----- */
3590 {
3591 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3592 2, conn->pass, conn->peer,
3593 '\\', conn->head[3], '\\',conn->head[4],
3594 '\\', conn->head[5], '\\',conn->head[6]);
3595 status_update (conn->client_entry, CLT_FAILED);
3596 conn->client_entry->session_key_timer =
3597 time(NULL) - (2*TIMEOUT_KEY);
3598 sh_forward_do_free (conn);
3599 }
3600 }
3601 else if (state == SH_DO_WRITE) /* finished writing */
3602 {
3603 if (0 != (conn->head[0] & SH_PROTO_END))
3604 {
3605 if (flag_err_debug == SL_TRUE)
3606 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKMSG,
3607 sh_strip_domain (conn->peer));
3608 sh_forward_do_free (conn);
3609 SL_RET0(_("check_protocol"));
3610 }
3611
3612 TPT(( 0, FIL__, __LINE__, _("msg=<Msg transfer - (wait).>\n")));
3613
3614 /* challenge is sent, now wait for message from client
3615 */
3616 conn->headcount = 0;
3617 conn->bytecount = 0;
3618 conn->bytes_to_send = 0;
3619 conn->bytes_to_get = 0;
3620 if (conn->buf != NULL)
3621 {
3622 SH_FREE(conn->buf);
3623 conn->buf = NULL;
3624 }
3625 conn->state = CONN_READING;
3626 }
3627 TPT((0, FIL__, __LINE__, _("msg=<return>\n") ));
3628 SL_RET0(_("check_protocol"));
3629 }
3630
3631 /* --------- authentication -----------
3632 */
3633
3634 /* entry point for jump from message forward if session key must
3635 * be re-initialized
3636 */
3637 servInit:
3638
3639 if ( (conn->head[0] & SH_PROTO_SRP) != 0 /* is set */ )
3640 {
3641
3642#ifndef USE_SRP_PROTOCOL
3643
3644 if (state == SH_DO_READ) /* finished reading */
3645 {
3646 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3647
3648 /* first pass -- client request salt
3649 */
3650 if (conn->pass == 1)
3651 {
3652
3653 TPT((0, FIL__, __LINE__,
3654 _("msg=<Authentication - SALT (1).>\n")));
3655
3656 if (conn->buf == NULL || sl_strlen(conn->buf) == 0)
3657 {
3658 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3659 sh_forward_do_free (conn);
3660 SL_RET0(_("check_protocol"));
3661 }
3662
3663
3664 /* search the register
3665 */
3666
3667 this_client = search_register (conn, 0);
3668 if (NULL == this_client)
3669 SL_RET0(_("check_protocol"));
3670
3671
3672 conn->client_entry = this_client;
3673 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3674
3675 if (0 != check_request_s((char *)&(conn->head[3]),
3676 _("SALT"),conn->peer))
3677 {
3678 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3679 _("No salt requested"), conn->peer);
3680 status_update (conn->client_entry, CLT_FAILED);
3681 conn->client_entry->session_key_timer =
3682 time(NULL) - (2*TIMEOUT_KEY);
3683 sh_forward_do_free (conn);
3684 SL_RET0(_("check_protocol"));
3685 }
3686
3687
3688 /* -- create server nounce v --
3689 */
3690 ticks = (UINT32) taus_get (&(skey->rng0[0]),
3691 &(skey->rng1[0]),
3692 &(skey->rng2[0]));
3693
3694 if (conn->A != NULL)
3695 {
3696 SH_FREE(conn->A);
3697 conn->A = NULL;
3698 }
3699 conn->A = SH_ALLOC(KEY_LEN+1);
3700
3701 sl_strlcpy(conn->A,
3702 sh_tiger_hash((char *) &ticks,
3703 TIGER_DATA, sizeof(UINT32)),
3704 KEY_LEN+1);
3705 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3706
3707 if (conn->M1 != NULL)
3708 {
3709 SH_FREE(conn->M1);
3710 conn->M1 = NULL;
3711 }
3712 conn->M1 = SH_ALLOC(2*KEY_LEN+1);
3713
3714 /* compute hash key H(v(server), P)v(server)
3715 */
3716 sh_passwd (conn->A, conn->client_entry->verifier,
3717 NULL, conn->M1);
3718
3719 sl_strlcat(conn->M1, conn->A, 2*KEY_LEN+1);
3720
3721
3722 /* --- send H(v(server), P)v(server) ----
3723 */
3724 sh_forward_prep_send (conn,
3725 conn->M1,
3726 sl_strlen(conn->M1),
3727 u,
3728 (conn->head[0]|SH_PROTO_SRP));
3729
3730 SH_FREE(conn->M1);
3731 conn->M1 = NULL;
3732 }
3733
3734 /* client -- third pass
3735 * Message is H(H(u,v),P)u
3736 *
3737 * A := v, verifier := H(password),
3738 */
3739 else if (conn->pass == 3 &&
3740 conn->client_entry != NULL)
3741 {
3742
3743 TPT((0, FIL__, __LINE__,
3744 _("msg=<Authentication - PASS (3).>\n")));
3745
3746 if (0 != check_request_s((char *) &(conn->head[3]), _("PASS"),
3747 conn->peer) ||
3748 sl_strlen(conn->buf) <= KEY_LEN ||
3749 conn->A == NULL)
3750 {
3751 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3752 _("Invalid client request"), conn->peer);
3753 status_update (conn->client_entry, CLT_FAILED);
3754 conn->client_entry->session_key_timer =
3755 time(NULL) - (2*TIMEOUT_KEY);
3756 sh_forward_do_free (conn);
3757 SL_RET0(_("check_protocol"));
3758 }
3759
3760 /* store random nonce u from client
3761 */
3762 if (conn->K != NULL)
3763 {
3764 SH_FREE(conn->K);
3765 conn->K = NULL;
3766 }
3767 conn->K = SH_ALLOC(KEY_LEN+1);
3768 sl_strlcpy(conn->K, &(conn->buf[KEY_LEN]), KEY_LEN+1);
3769
3770 /* verify random nonce u from client
3771 */
3772 if (conn->M1 != NULL)
3773 {
3774 SH_FREE(conn->M1);
3775 conn->M1 = NULL;
3776 }
3777 conn->M1 = sh_util_strconcat(conn->K, conn->A, NULL);
3778
3779 TPT((0, FIL__, __LINE__, _("msg=<c/r: K = %s>\n"), conn->K));
3780 TPT((0, FIL__, __LINE__, _("msg=<c/r: A = %s>\n"), conn->A));
3781 TPT((0, FIL__, __LINE__, _("msg=<c/r: M = %s>\n"), conn->M1));
3782
3783 sl_strlcpy(hash, sh_tiger_hash (conn->M1,
3784 TIGER_DATA,
3785 sl_strlen(conn->M1)), KEY_LEN+1);
3786 sh_passwd (hash, conn->client_entry->verifier, NULL, conn->M1);
3787
3788 TPT((0, FIL__, __LINE__, _("msg=<c/r: H = %s>\n"), hash));
3789 TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1));
3790
3791 if ( 0 != sl_strncmp(conn->M1, conn->buf, KEY_LEN))
3792 {
3793 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3794 _("Session key mismatch"), conn->peer);
3795 status_update (conn->client_entry, CLT_FAILED);
3796 conn->client_entry->session_key_timer =
3797 time(NULL) - (2*TIMEOUT_KEY);
3798 sh_forward_do_free (conn);
3799 SL_RET0(_("check_protocol"));
3800 }
3801
3802
3803 /* ---- compute hash key H(v, P, u) ----
3804 */
3805
3806 sh_passwd (conn->A, conn->client_entry->verifier, conn->K,
3807 conn->M1);
3808
3809 sl_strlcpy(conn->client_entry->session_key,
3810 conn->M1, KEY_LEN+1);
3811 TPT((0, FIL__, __LINE__, _("msg=<c/r: Key = %s>\n"),
3812 conn->client_entry->session_key));
3813
3814#ifdef SH_ENCRYPT
3815 err_num = makeKey(&(conn->client_entry->keyInstE),
3816 DIR_ENCRYPT, 192,
3817 conn->client_entry->session_key);
3818 if (err_num < 0)
3819 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3820 errorExplain(err_num),
3821 _("check_protocol: makeKey"));
3822 err_num = makeKey(&(conn->client_entry->keyInstD),
3823 DIR_DECRYPT, 192,
3824 conn->client_entry->session_key);
3825 if (err_num < 0)
3826 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3827 errorExplain(err_num),
3828 _("check_protocol: makeKey"));
3829#endif
3830
3831 if (conn->K != NULL) SH_FREE (conn->K);
3832 conn->K = NULL;
3833 if (conn->A != NULL) SH_FREE (conn->A);
3834 conn->A = NULL;
3835 if (conn->M1 != NULL) SH_FREE (conn->M1);
3836 conn->M1 = NULL;
3837
3838 /* if (conn->client_entry->status_now == CLT_STARTED */
3839 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
3840 (conn->client_entry->status_now != CLT_EXITED) &&
3841 (conn->client_entry->status_now != CLT_SUSPEND))
3842 && conn->client_entry->session_key_timer > (time_t) 1)
3843 {
3844 status_update (conn->client_entry, CLT_ILLEGAL);
3845 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3846 conn->peer);
3847 }
3848 else if (conn->client_entry->session_key_timer == (time_t) 0)
3849 {
3850 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NEW,
3851 conn->peer);
3852 if (conn->client_entry->status_now != CLT_SUSPEND)
3853 status_update (conn->client_entry, CLT_STARTED);
3854 }
3855
3856 conn->client_entry->session_key_timer = time (NULL);
3857 conn->client_entry->last_connect = time (NULL);
3858
3859 /* put in read state
3860 */
3861 sh_forward_prep_send (conn,
3862 _("AUTH"),
3863 5,
3864 _("AUTH"),
3865 (conn->head[0]|SH_PROTO_SRP));
3866
3867 }
3868 else
3869 {
3870 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3871 3, conn->pass, conn->peer,
3872 '\\', conn->head[3], '\\', conn->head[4],
3873 '\\', conn->head[5], '\\', conn->head[6]);
3874 sh_forward_do_free (conn);
3875 }
3876 }
3877
3878#else
3879 /* use SRP */
3880
3881
3882 if (state == SH_DO_READ) /* finished reading */
3883 {
3884
3885 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3886
3887 /* first pass -- client request salt
3888 */
3889 if (conn->pass == 1)
3890 {
3891 TPT((0, FIL__, __LINE__,
3892 _("msg=<Authentication - SALT (1).>\n")));
3893
3894 if (conn->buf == NULL)
3895 {
3896 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3897 sh_forward_do_free (conn);
3898 SL_RET0(_("check_protocol"));
3899 }
3900
3901 /* search the register
3902 */
3903 this_client = search_register(conn, 0);
3904 if (NULL == this_client)
3905 SL_RET0(_("check_protocol"));
3906
3907 conn->client_entry = this_client;
3908 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3909
3910 if (0 != check_request_s((char *)&(conn->head[3]), _("SALT"),
3911 conn->peer))
3912 {
3913 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3914 _("No salt requested"), conn->peer);
3915 status_update (conn->client_entry, CLT_FAILED);
3916 conn->client_entry->session_key_timer =
3917 time(NULL) - (2*TIMEOUT_KEY);
3918 sh_forward_do_free (conn);
3919 SL_RET0(_("check_protocol"));
3920 }
3921
3922
3923 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3924
3925 sh_forward_prep_send (conn,
3926 conn->client_entry->salt,
3927 sl_strlen(conn->client_entry->salt),
3928 u,
3929 (conn->head[0]|SH_PROTO_SRP));
3930 }
3931
3932 /* client has sent A -- third pass
3933 */
3934 else if (conn->pass == 3 &&
3935 conn->client_entry != NULL)
3936 {
3937
3938 TPT((0, FIL__, __LINE__,
3939 _("msg=<Authentication - PC01 (3).>\n")));
3940
3941 if (0 != check_request_s((char *)&(conn->head[3]),_("PC01"),conn->peer)||
3942 conn->buf == NULL
3943 )
3944 {
3945 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3946 _("Invalid client request"), conn->peer);
3947 status_update (conn->client_entry, CLT_FAILED);
3948 conn->client_entry->session_key_timer =
3949 time(NULL) - (2*TIMEOUT_KEY);
3950 sh_forward_do_free (conn);
3951 SL_RET0(_("check_protocol"));
3952 }
3953
3954 if (0 != sh_srp_init())
3955 {
3956 status_update (conn->client_entry, CLT_FAILED);
3957 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
3958 MSG_TCP_EBGN);
3959 sh_forward_do_free (conn);
3960 SL_RET0(_("check_protocol"));
3961 }
3962
3963
3964 /* check A, only send B if correct
3965 */
3966 if ( sl_strlen(conn->buf) < SH_BUFSIZE &&
3967 0 == sh_srp_check_zero (conn->buf) )
3968 {
3969 len = sl_strlen(conn->buf)+1;
3970
3971 if (conn->A != NULL)
3972 {
3973 SH_FREE(conn->A);
3974 conn->A = NULL;
3975 }
3976 conn->A = SH_ALLOC(len);
3977 sl_strlcpy (conn->A, conn->buf, len);
3978
3979 /*
3980 * compute B
3981 */
3982 if (0 != sh_srp_make_a ()) /* b random number */
3983 {
3984 status_update (conn->client_entry, CLT_FAILED);
3985
3986 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
3987 MSG_TCP_EBGN);
3988 sh_srp_exit();
3989 sh_forward_do_free (conn);
3990 SL_RET0(_("check_protocol"));
3991 }
3992
3993 foo_B = sh_srp_B /* B = v + g^b */
3994 (conn->client_entry->verifier);
3995
3996 if (foo_B == NULL)
3997 {
3998 status_update (conn->client_entry, CLT_FAILED);
3999
4000 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4001 MSG_TCP_EBGN);
4002 sh_srp_exit();
4003 sh_forward_do_free (conn);
4004 SL_RET0(_("check_protocol"));
4005 }
4006
4007 TPT((0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), conn->A));
4008 TPT((0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), foo_B));
4009
4010 /*
4011 * create nonce u
4012 */
4013 ticks = (UINT32) taus_get (&(skey->rng0[0]),
4014 &(skey->rng1[0]),
4015 &(skey->rng2[0]));
4016 test = (char *) &ticks;
4017 sh_util_cpylong (u, test, 4); /* u nounce */
4018 u[4] = '\0';
4019 sl_strlcpy(conn->challenge,
4020 sh_tiger_hash(u, TIGER_DATA, 4),
4021 SH_CHALLENGE_SIZE);
4022
4023 TPT((0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), u[0], u[1], u[2], u[3]));
4024 TPT((0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
4025 conn->challenge));
4026
4027 /*
4028 * compute the session key K and M1 = Hash(A,B,K)
4029 */
4030 foo_Ss = sh_srp_S_s (conn->challenge,
4031 conn->A,
4032 conn->client_entry->verifier);
4033 if (foo_Ss == NULL)
4034 {
4035 status_update (conn->client_entry, CLT_FAILED);
4036
4037 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4038 MSG_TCP_EBGN);
4039 sh_srp_exit();
4040 sh_forward_do_free (conn);
4041 SL_RET0(_("check_protocol"));
4042 }
4043
4044 if (conn->K != NULL)
4045 {
4046 SH_FREE(conn->K);
4047 conn->K = NULL;
4048 }
4049 conn->K = SH_ALLOC(KEY_LEN+1);
4050 sl_strlcpy(conn->K,
4051 sh_tiger_hash(foo_Ss, TIGER_DATA,
4052 sl_strlen(foo_Ss)),
4053 KEY_LEN+1);
4054
4055 if (conn->M1 != NULL)
4056 {
4057 SH_FREE(conn->M1);
4058 conn->M1 = NULL;
4059 }
4060 conn->M1 = SH_ALLOC(KEY_LEN+1);
4061 sl_strlcpy(conn->M1,
4062 sh_srp_M (conn->A, foo_B, conn->K),
4063 KEY_LEN+1);
4064
4065 TPT((0, FIL__, __LINE__, _("msg=<srp:Ss = %s>\n"), foo_Ss));
4066 TPT((0, FIL__, __LINE__, _("msg=<srp: K = %s>\n"), conn->K));
4067 TPT((0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),conn->M1));
4068
4069 /*
4070 * send B
4071 */
4072 sh_forward_prep_send (conn,
4073 foo_B,
4074 sl_strlen(foo_B)+1,
4075 u,
4076 (conn->head[0]|SH_PROTO_SRP));
4077 if (foo_Ss != NULL)
4078 {
4079 SH_FREE(foo_Ss);
4080 foo_Ss = NULL;
4081 }
4082 if (foo_B != NULL)
4083 {
4084 SH_FREE(foo_B);
4085 foo_B = NULL;
4086 }
4087 }
4088 else
4089 {
4090 status_update (conn->client_entry, CLT_FAILED);
4091
4092 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4093 MSG_TCP_EZERO);
4094 sh_forward_do_free (conn);
4095 }
4096
4097 sh_srp_exit();
4098 }
4099
4100 /* client has sent M1 -- fifth pass
4101 */
4102 else if (conn->pass == 5 &&
4103 conn->client_entry != NULL)
4104 {
4105 TPT((0, FIL__, __LINE__,
4106 _("msg=<Authentication - PC02 (5).>\n")));
4107
4108 /* check that the state is valid
4109 */
4110 if (0 != check_request_s((char *)&(conn->head[3]), _("PC02"),
4111 conn->peer) ||
4112 conn->A == NULL || conn->K == NULL || conn->M1 == NULL)
4113 {
4114 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4115 _("Invalid client request"), conn->peer);
4116 status_update (conn->client_entry, CLT_FAILED);
4117 conn->client_entry->session_key_timer =
4118 time(NULL) - (2*TIMEOUT_KEY);
4119 sh_forward_do_free (conn);
4120 SL_RET0(_("check_protocol"));
4121 }
4122
4123 /* ------ verify M1 = H(A, B, K) -------
4124 * ----- send M2 = H(A, M1, K) -------
4125 */
4126 if (conn->buf != NULL &&
4127 sl_strncmp(conn->buf, conn->M1, KEY_LEN) == 0)
4128 {
4129 /*
4130 * send M2
4131 */
4132 sh_forward_prep_send (conn,
4133 sh_srp_M (conn->A, conn->M1, conn->K),
4134 KEY_LEN+1,
4135 _("PARP"),
4136 (conn->head[0]|SH_PROTO_SRP));
4137
4138 if (conn->A != NULL) SH_FREE(conn->A); conn->A = NULL;
4139 if (conn->M1 != NULL) SH_FREE(conn->M1); conn->M1 = NULL;
4140 sl_strlcpy(conn->client_entry->session_key,
4141 conn->K, KEY_LEN+1);
4142 TPT((0, FIL__, __LINE__, _("msg=<key %s>\n"),
4143 conn->client_entry->session_key));
4144
4145#ifdef SH_ENCRYPT
4146 err_num = makeKey(&(conn->client_entry->keyInstE),
4147 DIR_ENCRYPT, 192,
4148 conn->client_entry->session_key);
4149 if (err_num < 0)
4150 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4151 errorExplain(err_num),
4152 _("sh_forward_prep_send_int: makeKey"));
4153 err_num = makeKey(&(conn->client_entry->keyInstD),
4154 DIR_DECRYPT, 192,
4155 conn->client_entry->session_key);
4156 if (err_num < 0)
4157 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4158 errorExplain(err_num),
4159 _("sh_forward_prep_send_int: makeKey"));
4160#endif
4161
4162 if (conn->K != NULL) SH_FREE(conn->K); conn->K = NULL;
4163
4164 conn->client_entry->last_connect = time (NULL);
4165
4166 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
4167 (conn->client_entry->status_now != CLT_EXITED) &&
4168 (conn->client_entry->status_now != CLT_SUSPEND))
4169 && conn->client_entry->session_key_timer > (time_t) 1)
4170 {
4171 status_update (conn->client_entry, CLT_ILLEGAL);
4172
4173 sh_error_handle((-1), FIL__, __LINE__, 0,
4174 MSG_TCP_ILL,
4175 conn->peer);
4176 }
4177 else if (conn->client_entry->session_key_timer == (time_t) 0)
4178 {
4179 sh_error_handle((-1), FIL__, __LINE__, 0,
4180 MSG_TCP_NEW,
4181 conn->peer);
4182 if (conn->client_entry->status_now != CLT_SUSPEND)
4183 status_update (conn->client_entry, CLT_STARTED);
4184 }
4185 conn->client_entry->session_key_timer = time (NULL);
4186
4187 }
4188 else
4189 {
4190 status_update (conn->client_entry, CLT_FAILED);
4191 conn->client_entry->session_key_timer =
4192 time(NULL) - (2*TIMEOUT_KEY);
4193
4194 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4195 _("Session key mismatch"), conn->peer);
4196 sh_forward_do_free (conn);
4197 }
4198 }
4199
4200 else
4201 {
4202 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
4203 4, conn->pass, conn->peer,
4204 '\\', conn->head[3], '\\', conn->head[4],
4205 '\\', conn->head[5], '\\', conn->head[6]);
4206 sh_forward_do_free (conn);
4207 }
4208 }
4209
4210#endif
4211
4212 else if (state == SH_DO_WRITE) /* finished writing */
4213 {
4214 TPT((0, FIL__, __LINE__, _("msg=<Authentication -- (wait).>\n")));
4215
4216 conn->headcount = 0;
4217 conn->bytecount = 0;
4218 conn->bytes_to_send = 0;
4219 conn->bytes_to_get = 0;
4220 if (conn->buf != NULL)
4221 {
4222 SH_FREE(conn->buf);
4223 conn->buf = NULL;
4224 }
4225 conn->state = CONN_READING;
4226 }
4227 }
4228 SL_RET0(_("check_protocol"));
4229}
4230
4231
4232/***********************************************************
4233 *
4234 * SERVER RECEIVE FUNCTION
4235 *
4236 ***********************************************************
4237 */
4238int sh_forward_do_read (sh_conn_t * conn)
4239{
4240 unsigned long byteread; /* bytes read */
4241
4242#ifdef SH_ENCRYPT
4243
4244 unsigned long blkfac = 0;
4245 /* unsigned long length2; */
4246 char * p = NULL, * q = NULL;
4247 RIJ_BYTE inBlock[B_SIZ];
4248 RIJ_BYTE outBlock[B_SIZ];
4249 unsigned int j;
4250 cipherInstance cipherInst;
4251 int err_num;
4252#endif
4253
4254 SL_ENTER(_("sh_forward_do_read"));
4255
4256 if (conn->state == CONN_SENDING)
4257 {
4258 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4259 conn->peer);
4260 SL_RETURN( (-1), _("sh_forward_do_read"));
4261 }
4262
4263 if (conn->headcount < SH_HEADER_SIZE)
4264 {
4265 conn->bytes_to_get = SH_HEADER_SIZE - conn->headcount;
4266 byteread = read (conn->fd, &(conn->head[conn->headcount]),
4267 conn->bytes_to_get);
4268 if (byteread > 0 || errno == EINTR)
4269 {
4270 if (byteread > 0)
4271 conn->headcount += byteread;
4272 if (conn->headcount == SH_HEADER_SIZE)
4273 {
4274 conn->bytes_to_get =
4275 (256 * (unsigned int)conn->head[1] +
4276 (unsigned int)conn->head[2]);
4277 SH_SHOWPROT(conn->head, '<');
4278 conn->bytecount = 0;
4279 }
4280 }
4281 else
4282 {
4283 goto conn_reset;
4284 }
4285 SL_RETURN( (0), _("sh_forward_do_read"));
4286 }
4287
4288
4289 /* limit message size
4290 */
4291 /*
4292 conn->bytes_to_get =
4293 (conn->bytes_to_get > (16*SH_BUFSIZE - 1)) ?
4294 (16*SH_BUFSIZE - 1) : conn->bytes_to_get;
4295 */
4296 conn->bytes_to_get = (conn->bytes_to_get > TRANS_BYTES) ?
4297 TRANS_BYTES : conn->bytes_to_get;
4298
4299 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get > 0)
4300 {
4301 if ((conn->bytecount > 0) && (conn->bytes_to_get > conn->bytecount))
4302 {
4303 /* do nothing */;
4304 }
4305 else
4306 {
4307 if (conn->buf != NULL)
4308 SH_FREE (conn->buf);
4309 conn->buf = SH_ALLOC (conn->bytes_to_get + 1);
4310 conn->bytecount = 0;
4311 }
4312
4313 byteread = read (conn->fd, &(conn->buf[conn->bytecount]),
4314 conn->bytes_to_get - conn->bytecount);
4315 if (byteread > 0 || errno == EINTR)
4316 {
4317 if (byteread > 0)
4318 conn->bytecount += byteread;
4319 if (conn->bytecount == conn->bytes_to_get)
4320 {
4321 ++conn->pass;
4322 /* always terminate with NULL - we might use sl_strcmp()
4323 */
4324 conn->buf[conn->bytecount] = '\0';
4325 conn->state = CONN_PAUSE;
4326
4327#ifdef SH_ENCRYPT
4328 if ((conn->head[0] & SH_PROTO_EN2) != 0) /* if encrypted */
4329 {
4330 conn->buf =
4331 sh_tools_revertPack (conn->head, conn->buf,
4332 &(conn->client_entry->keyInstD),
4333 conn->bytecount);
4334 }
4335 else if ((conn->head[0] & SH_PROTO_ENC) != 0) /* if encrypted */
4336 {
4337 /* Decrypt only complete blocks.
4338 * If there is an incomplete block,
4339 * something is wrong anyway.
4340 * Decrypt in place.
4341 */
4342 blkfac = conn->bytecount / B_SIZ;
4343 /* length2 = (B_SIZ * blkfac); */
4344 p = conn->buf;
4345 q = conn->buf;
4346
4347 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
4348 if (err_num < 0)
4349 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4350 errorExplain(err_num),
4351 _("sh_forward_do_read: cipherInit"));
4352
4353 for (j = 0; j < blkfac; ++j)
4354 {
4355 memcpy(inBlock, p, B_SIZ);
4356 err_num = blockDecrypt(&cipherInst,
4357 &(conn->client_entry->keyInstD),
4358 inBlock, 128 * BNUM, outBlock);
4359 if (err_num < 0)
4360 sh_error_handle((-1), FIL__, __LINE__, -1,
4361 MSG_E_SUBGEN,
4362 errorExplain(err_num),
4363 _("sh_forward_do_read: blockDecrypt"));
4364 memcpy(q, outBlock, B_SIZ);
4365 p += 16;
4366 q += 16;
4367 }
4368 }
4369#endif
4370
4371 /* ------ HERE CALL check_protocol(conn) ------- */
4372 check_protocol(conn, SH_DO_READ);
4373 }
4374 }
4375 else
4376 {
4377 goto conn_reset;
4378 }
4379 }
4380
4381 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get == 0)
4382 {
4383 if (conn->buf != NULL)
4384 SH_FREE (conn->buf);
4385 conn->buf = NULL;
4386 conn->bytecount = 0;
4387 ++conn->pass;
4388 conn->state = CONN_PAUSE;
4389 /* fprintf(stderr, "\n**** FIXME null read ****\n\n"); */
4390 /* ------ HERE CALL check_protocol(conn) ------- */
4391 check_protocol(conn, SH_DO_READ);
4392 }
4393
4394 SL_RETURN( (0), _("sh_forward_do_read"));
4395
4396 conn_reset:
4397 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4398 conn->peer);
4399 sh_forward_do_free ( conn );
4400 SL_RETURN( (-1), _("sh_forward_do_read"));
4401}
4402
4403#if !defined(O_NONBLOCK)
4404#if defined(O_NDELAY)
4405#define O_NONBLOCK O_NDELAY
4406#else
4407#define O_NONBLOCK 0
4408#endif
4409#endif
4410
4411/* send to the client
4412 */
4413int sh_forward_do_write (sh_conn_t * conn)
4414{
4415 int flags;
4416 long arg = 0;
4417 long bytesent; /* bytes read */
4418
4419 SL_ENTER(_("sh_forward_do_write"));
4420
4421 /* ---- consistency check ------
4422 */
4423 if (conn->state == CONN_READING)
4424 {
4425 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4426 conn->peer);
4427 SL_RETURN( (-1), _("sh_forward_do_write"));
4428 }
4429
4430
4431 flags = retry_fcntl (FIL__, __LINE__, conn->fd, F_GETFL, arg);
4432 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags|O_NONBLOCK);
4433
4434 /* ---- send the header ------
4435 */
4436 if (conn->headcount < SH_HEADER_SIZE)
4437 {
4438 conn->bytes_to_send = SH_HEADER_SIZE - conn->headcount;
4439 bytesent = write (conn->fd,
4440 &(conn->head[conn->headcount]),
4441 conn->bytes_to_send);
4442 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4443 {
4444 if (bytesent > 0)
4445 conn->headcount += bytesent;
4446 if (conn->headcount == SH_HEADER_SIZE)
4447 {
4448 conn->bytes_to_send =
4449 (256 * (int)conn->head[1] + (int)conn->head[2]);
4450 }
4451 }
4452 else
4453 {
4454 goto conn_reset_w;
4455 }
4456 if (conn->fd >= 0)
4457 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4458 SL_RETURN( (0), _("sh_forward_do_write"));
4459 }
4460
4461
4462 /* ---- send the body ------
4463 */
4464
4465 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send > 0 &&
4466 conn->buf != NULL)
4467 {
4468 bytesent = write (conn->fd, &(conn->buf[conn->bytecount]),
4469 conn->bytes_to_send - conn->bytecount);
4470 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4471 {
4472 if (bytesent > 0)
4473 conn->bytecount += bytesent;
4474 if (conn->bytecount == conn->bytes_to_send)
4475 {
4476 ++conn->pass;
4477 conn->state = CONN_PAUSE;
4478 /* ------ HERE CALL check_protocol(conn) ------- */
4479 check_protocol(conn, SH_DO_WRITE);
4480 }
4481 }
4482 else
4483 {
4484 goto conn_reset_w;
4485 }
4486 }
4487
4488 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send == 0)
4489 {
4490 ++conn->pass;
4491 conn->state = CONN_PAUSE;
4492 /* fprintf(stderr, "\n**** FIXME null write ****\n\n"); */
4493 /* ------ HERE CALL check_protocol(conn) ------- */
4494 check_protocol(conn, SH_DO_WRITE);
4495 }
4496
4497 if (conn->fd >= 0)
4498 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4499 SL_RETURN( (0), _("sh_forward_do_write"));
4500
4501 conn_reset_w:
4502 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4503 conn->peer);
4504 sh_forward_do_free ( conn );
4505 SL_RETURN( (-1), _("sh_forward_do_write"));
4506}
4507
4508/* accept a connection from a client
4509 */
4510#include <syslog.h>
4511#ifdef SH_USE_LIBWRAP
4512#include <tcpd.h>
4513
4514#ifndef ALLOW_SEVERITY
4515#define ALLOW_SEVERITY LOG_INFO
4516#define DENY_SEVERITY LOG_WARNING
4517#endif
4518
4519int allow_severity;
4520int deny_severity;
4521#endif
4522
4523int sh_forward_accept (int sock, sh_conn_t * newconn)
4524{
4525 int errflag;
4526 int rc;
4527 struct sockaddr_in addr;
4528#ifdef SH_USE_LIBWRAP
4529 struct request_info request;
4530 char errbuf[128];
4531 char daemon[128];
4532#endif
4533
4534 /* handle AIX (size_t addrlen) in wrapper
4535 */
4536 int addrlen = sizeof(addr);
4537
4538 SL_ENTER(_("sh_forward_accept"));
4539
4540 rc = retry_accept(FIL__, __LINE__, sock,
4541 (struct sockaddr *) &addr, &addrlen);
4542
4543 if (rc >= 0)
4544 {
4545
4546 if (addrlen == 0)
4547 {
4548 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4549 _("Connecting entity unknown"), _("accept"));
4550 newconn->fd = -1;
4551 newconn->state = CONN_FREE;
4552 close(rc);
4553 SL_RETURN( (-1), _("sh_forward_accept"));
4554 }
4555
4556#ifdef SH_USE_LIBWRAP
4557 sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
4558 request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
4559 fromhost(&request);
4560 if (!hosts_access(&request))
4561 {
4562 sl_strlcpy(errbuf, _("Refused connection from "), 128);
4563 sl_strlcat(errbuf, eval_client(&request), 128);
4564
4565 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4566 errbuf, _("libwrap"));
4567 newconn->fd = -1;
4568 newconn->state = CONN_FREE;
4569 close(rc);
4570 SL_RETURN( (-1), _("sh_forward_accept"));
4571 }
4572#endif
4573
4574 memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
4575
4576 /* prepare for usage of connection
4577 */
4578 (void) retry_fcntl( FIL__, __LINE__, rc, F_SETFD, 1 );
4579 newconn->fd = rc;
4580 newconn->state = CONN_READING;
4581 newconn->timer = (unsigned long) time (NULL);
4582
4583 if (flag_err_info == SL_TRUE)
4584 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CNEW, newconn->fd);
4585
4586 SL_RETURN( (0), _("sh_forward_accept"));
4587 }
4588 else
4589 {
4590 errflag = errno;
4591 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4592 sh_error_message(errflag), _("accept"));
4593 newconn->fd = -1;
4594 newconn->state = CONN_FREE;
4595 SL_RETURN( (-1), _("sh_forward_accept"));
4596 }
4597}
4598
4599extern char sh_sig_msg[64]; /* defined in sh_unix.c */
4600
4601/* ------------ port and interface -------
4602 */
4603static unsigned int server_port = SH_DEFAULT_PORT;
4604
4605int sh_forward_set_port (const char * str)
4606{
4607 int retval = 0;
4608 unsigned long i;
4609 char * endptr;
4610
4611 SL_ENTER(_("sh_forward_set_port"));
4612 i = strtoul (str, &endptr, 0);
4613 if (endptr == str) {
4614 retval = -1;
4615 } else if (i > 65535) {
4616 retval = -1;
4617 } else {
4618 server_port = i;
4619 }
4620 SL_RETURN( (retval), _("sh_forward_set_port"));
4621}
4622
4623static struct in_addr server_interface;
4624static int use_server_interface = 0;
4625
4626int sh_forward_set_interface (const char * str)
4627{
4628 if (0 == strcmp(str, _("INADDR_ANY")))
4629 {
4630 use_server_interface = 0;
4631 return 0;
4632 }
4633 if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/)
4634 {
4635 use_server_interface = 0;
4636 return -1;
4637 }
4638 use_server_interface = 1;
4639 return 0;
4640}
4641
4642/* ------------ print error --------------
4643 */
4644struct sock_err_st {
4645 char msg[128];
4646 int errnum;
4647 int port;
4648 int line;
4649 int euid;
4650};
4651
4652static struct sock_err_st sock_err[2];
4653
4654void sh_forward_printerr(char * str, int errnum, unsigned int port, int line)
4655{
4656 int slot = 0;
4657
4658 if (port != server_port)
4659 slot = 1;
4660 if (str == NULL)
4661 sock_err[slot].msg[0] = '\0';
4662 else
4663 sl_strlcpy(sock_err[slot].msg, str, 128);
4664 sock_err[slot].errnum = errnum;
4665 sock_err[slot].port = port;
4666 sock_err[slot].line = line;
4667 sock_err[slot].euid = (int) geteuid();
4668}
4669
4670int sh_forward_printerr_final(int slot)
4671{
4672 SL_ENTER(_("sh_forward_printerr_final"));
4673 if (sock_err[slot].msg[0] != '\0')
4674 {
4675 dlog(1, FIL__, __LINE__,
4676 _("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"),
4677 sh_error_message(sock_err[slot].errnum), sock_err[slot].euid,
4678 sock_err[slot].port);
4679 sh_error_handle((-1), FIL__, sock_err[slot].line,
4680 sock_err[slot].errnum, MSG_EXIT_ABORTS,
4681 sh_error_message(sock_err[slot].errnum),
4682 sh.prg_name,
4683 sock_err[slot].msg);
4684 SL_RETURN((-1), _("sh_forward_printerr_final"));
4685 }
4686 SL_RETURN(0, _("sh_forward_printerr_final"));
4687}
4688
4689static sh_conn_t * conns = NULL;
4690#define TIME_OUT_DEF 300
4691static int maxconn = 0; /* maximum number of simultaneous connections */
4692
4693
4694#ifdef INET_SYSLOG
4695#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
4696#define SH_MINSOCK 3
4697int create_syslog_socket (int flag);
4698static int recv_syslog_socket (int fd);
4699static int syslog_sock = -1;
4700#else
4701#define SH_MINSOCK 2
4702#endif
4703
4704extern int pf_unix_fd;
4705
4706/* the tcp socket, and the function to establish it
4707 */
4708static int sh_tcp_sock = -1;
4709
4710int sh_create_tcp_socket ()
4711{
4712 struct sockaddr_in addr;
4713 int addrlen = sizeof(addr);
4714
4715 int sock = -1;
4716 int errnum = 0;
4717 int flag = 1; /* non-zero to enable an option */
4718
4719 SL_ENTER(_("sh_create_tcp_socket"));
4720
4721 sh_forward_printerr (NULL, 0, server_port, __LINE__);
4722
4723 /* create the socket, bind() it and listen()
4724 */
4725 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
4726 {
4727 errnum = errno;
4728 sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
4729 SL_RETURN((-1), _("sl_create_tcp_socket"));
4730 }
4731 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
4732
4733 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
4734 (void *) &flag, sizeof(flag)) < 0 )
4735 {
4736 errnum = errno;
4737 sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
4738 SL_RETURN((-1), _("sl_create_tcp_socket"));
4739 }
4740
4741 addr.sin_family = AF_INET;
4742 addr.sin_port = htons(server_port);
4743 if (use_server_interface == 0)
4744 addr.sin_addr.s_addr = INADDR_ANY;
4745 else
4746 memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
4747
4748 if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0)
4749 {
4750 errnum = errno;
4751 sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
4752 SL_RETURN((-1), _("sl_create_tcp_socket"));
4753 }
4754
4755 if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
4756 {
4757 errnum = errno;
4758 sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
4759 SL_RETURN((-1), _("sl_create_tcp_socket"));
4760 }
4761
4762 if ( listen(sock, 5) < 0)
4763 {
4764 errnum = errno;
4765 sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
4766 SL_RETURN((-1), _("sl_create_tcp_socket"));
4767 }
4768
4769 sh_tcp_sock = sock;
4770
4771 SL_RETURN((sock), _("sl_create_tcp_socket"));
4772}
4773
4774/*****************************************
4775 *
4776 * This is the server main loop.
4777 *
4778 * The server is set up for listening, and
4779 * and starts a select() loop.
4780 *
4781 *****************************************/
4782
4783void sh_receive()
4784{
4785#ifdef SH_USE_XML
4786 extern int sh_log_file (char * message, char * inet_peer);
4787#endif
4788
4789 int sock = -1;
4790 sh_conn_t * cx;
4791 fd_set readset;
4792 fd_set writeset;
4793 struct timeval tv;
4794 int num_sel;
4795 int errnum;
4796 int nowconn;
4797 int status;
4798 int high_fd;
4799 register int i;
4800 long dummy = 0;
4801 unsigned long time_now;
4802 unsigned long time_last = 0;
4803 unsigned long time_out = TIME_OUT_DEF;
4804
4805 time_t told;
4806 time_t tcurrent;
4807
4808 unsigned long tchkold;
4809
4810 struct sigaction new_act;
4811 struct sigaction old_act;
4812
4813 SL_ENTER(_("sh_receive"));
4814
4815 /* ignore SIGPIPE (instead get EPIPE if connection is closed)
4816 * --- we have called sh_unix_init() already ---
4817 */
4818 new_act.sa_handler = SIG_IGN;
4819 sigemptyset( &new_act.sa_mask ); /* set an empty mask */
4820 new_act.sa_flags = 0; /* init sa_flags */
4821 retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
4822
4823 if ( sh_forward_printerr_final(0) < 0)
4824 {
4825 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4826 }
4827 sock = sh_tcp_sock;
4828
4829 /* ****************************************************************
4830 *
4831 * This is a non-forking server. We use select() on the listen()
4832 * socket to watch for new connections. For new connections, accept()
4833 * will return a new socket that is put in the read/write filesets.
4834 * Data about active connections are kept in the 'conns' table.
4835 *
4836 ******************************************************************/
4837
4838 /* The table to hold info on sockets.
4839 * We reserve 6 file descriptors for misc. use.
4840 * The POSIX lower limit on open files seems to be eight.
4841 */
4842 maxconn = get_open_max() - 6;
4843 maxconn = (((int)FD_SETSIZE) < maxconn) ? FD_SETSIZE : maxconn;
4844
4845 conns = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
4846
4847 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
4848 (maxconn-1), sock);
4849
4850 /* timer
4851 */
4852 tcurrent = (unsigned long) time (NULL);
4853 told = tcurrent;
4854
4855 tchkold = tcurrent;
4856
4857 for (i = SH_MINSOCK; i < maxconn; ++i)
4858 {
4859 conns[i].buf = NULL;
4860 conns[i].K = NULL;
4861 conns[i].A = NULL;
4862 conns[i].M1 = NULL;
4863 conns[i].FileName = NULL;
4864 conns[i].fd = -1;
4865 sh_forward_do_free ( &conns[i]);
4866 }
4867
4868 /* status init
4869 */
4870 server_status.conn_open = 0;
4871 server_status.conn_total = 0;
4872 server_status.conn_max = maxconn-1;
4873 server_status.start = time (NULL);
4874 server_status.last = (time_t) 0;
4875
4876 nowconn = 1;
4877 tv.tv_sec = 5;
4878 tv.tv_usec = 0;
4879
4880 /* conns[0] is the listen() socket. Always in read mode.
4881 */
4882 conns[0].fd = sock;
4883 conns[0].state = CONN_READING;
4884 high_fd = sock;
4885
4886 conns[1].fd = pf_unix_fd;
4887 conns[1].state = CONN_READING;
4888 high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
4889
4890#ifdef INET_SYSLOG
4891 conns[2].fd = -1;
4892 if ( sh_forward_printerr_final(1) < 0)
4893 {
4894 SH_FREE(conns);
4895 conns = NULL;
4896 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4897 }
4898 sock = syslog_sock;
4899
4900 if (sock >= 0)
4901 {
4902 conns[2].fd = sock;
4903 conns[2].state = CONN_READING;
4904 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
4905 }
4906#endif
4907
4908 sh_html_write(all_clients);
4909
4910 /* This is the select() loop.
4911 */
4912 while (1 == 1)
4913 {
4914
4915 if (sig_raised > 0)
4916 {
4917 TPT((0, FIL__, __LINE__, _("msg=<Process a signal.>\n")))
4918
4919 if (sig_termfast == 1) /* SIGTERM */
4920 {
4921 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
4922 strncpy (sh_sig_msg, _("SIGTERM"), 20);
4923 --sig_raised; --sig_urgent;
4924 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
4925 }
4926
4927 if (sig_config_read_again == 1)
4928 {
4929 TPT((0, FIL__, __LINE__, _("msg=<Re-read configuration.>\n")));
4930 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
4931
4932
4933 /* -- Delete the name server cache. --
4934 */
4935
4936 delete_cache();
4937#if defined(WITH_EXTERNAL)
4938 /* -- Delete list of external tasks. --
4939 */
4940 (void) sh_ext_cleanup();
4941#endif
4942 /* - mark all clients dead
4943 * - read configuration file
4944 * - remove clients still dead
4945 */
4946 sh_forward_mark_dead ();
4947
4948#if defined(SH_WITH_MAIL)
4949 reset_count_dev_mail();
4950#endif
4951 reset_count_dev_console();
4952 reset_count_dev_time();
4953 sl_trust_purge_user();
4954
4955 (void) sh_readconf_read ();
4956 for (i = SH_MINSOCK; i < maxconn; ++i)
4957 if (conns[i].state != CONN_FREE &&
4958 conns[i].client_entry != NULL &&
4959 conns[i].client_entry->dead_flag == 1)
4960 sh_forward_do_free ( &conns[i]);
4961 sh_forward_clean_tree ();
4962
4963 sig_config_read_again = 0;
4964 --sig_raised;
4965 }
4966
4967 if (sig_fresh_trail == 1) /* SIGIOT */
4968 {
4969 /* Logfile access
4970 */
4971#ifdef SH_USE_XML
4972 sh_log_file (NULL, NULL);
4973#endif
4974 TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
4975 sh_error_only_stderr (S_TRUE);
4976 sh_unix_rm_lock_file(sh.srvlog.name);
4977 retry_msleep(3, 0);
4978 sh.flag.log_start = S_TRUE;
4979 sh_error_only_stderr (S_FALSE);
4980 sig_fresh_trail = 0;
4981 --sig_raised;
4982 }
4983
4984
4985 if (sig_terminate == 1 && nowconn < 2) /* SIGQUIT */
4986 {
4987 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
4988 strncpy (sh_sig_msg, _("SIGQUIT"), 20);
4989 --sig_raised; --sig_urgent;
4990 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
4991 }
4992
4993
4994 if (sig_debug_switch == 1) /* SIGUSR1 */
4995 {
4996 TPT((0, FIL__, __LINE__, _("msg=<Debug switch.>\n")));
4997 sh_error_dbg_switch();
4998 sig_debug_switch = 0;
4999 --sig_raised;
5000 }
5001
5002 if (sig_suspend_switch > 0) /* SIGUSR2 */
5003 {
5004 TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
5005 if (sh_global_suspend_flag == 1) {
5006 sh_global_suspend_flag = 0;
5007 } else {
5008 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND,
5009 sh.prg_name);
5010 sh_global_suspend_flag = 1;
5011 }
5012 --sig_suspend_switch;
5013 --sig_raised; --sig_urgent;
5014 }
5015
5016 sig_raised = (sig_raised < 0) ? 0 : sig_raised;
5017 sig_urgent = (sig_urgent < 0) ? 0 : sig_urgent;
5018 TPT((0, FIL__, __LINE__, _("msg=<End signal processing.>\n")));
5019 }
5020
5021 if (sh_global_suspend_flag == 1)
5022 {
5023 (void) retry_msleep (1, 0);
5024 continue;
5025 }
5026
5027 /* Recompute the descriptor set. select() modifies it,
5028 * thus we update it using the info from the connection table.
5029 * Also recompute the number of open connections.
5030 */
5031 FD_ZERO( &readset );
5032 FD_ZERO( &writeset );
5033 FD_SET(conns[0].fd, &readset );
5034 high_fd = conns[0].fd;
5035
5036 if (conns[1].fd > -1)
5037 {
5038 FD_SET(conns[1].fd, &readset );
5039 high_fd = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
5040 }
5041
5042#ifdef INET_SYSLOG
5043 if (conns[2].fd > -1)
5044 {
5045 FD_SET(conns[2].fd, &readset );
5046 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5047 }
5048#endif
5049
5050 time_now = (unsigned long) time (NULL);
5051 nowconn = 1;
5052
5053 for (i = SH_MINSOCK; i < maxconn; ++i)
5054 {
5055 /* eliminate timed out connections
5056 */
5057 if (conns[i].state != CONN_FREE)
5058 {
5059 if (time_now-conns[i].timer > time_out)
5060 {
5061 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMOUT,
5062 conns[i].peer);
5063 sh_forward_do_free ( &conns[i]);
5064 }
5065 else
5066 ++nowconn;
5067 }
5068
5069
5070 if (conns[i].state == CONN_READING)
5071 {
5072 FD_SET(conns[i].fd, &readset);
5073 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5074 }
5075 else if (conns[i].state == CONN_SENDING)
5076 {
5077 FD_SET(conns[i].fd, &writeset);
5078 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5079 }
5080 }
5081
5082 /* -- Exponentially reduce timeout limit if more than 1/2 full. --
5083 */
5084 if (nowconn > (maxconn/2))
5085 time_out = ( (time_out/2) > 1) ? (time_out/2) : 1;
5086 else
5087 time_out = TIME_OUT_DEF;
5088
5089
5090
5091 /* -- Do the select(). --
5092 */
5093 num_sel = select(high_fd+1, &readset, &writeset, NULL, &tv);
5094 errnum = errno;
5095
5096 /* reset timeout - modified by select() on some systems
5097 */
5098 tv.tv_sec = 5;
5099 tv.tv_usec = 0;
5100
5101
5102 if ( (time_now - time_last) > 2L)
5103 {
5104 time_last = time_now;
5105 if (sh_html_write(all_clients) < 0)
5106 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5107 }
5108
5109
5110 /* Error handling.
5111 */
5112 if ( num_sel < 0 ) /* some error */
5113 {
5114 if (sig_raised == 1)
5115 {
5116 sig_raised = 2;
5117 continue;
5118 }
5119
5120 if ( errnum == EINTR)
5121 continue; /* try again */
5122
5123 if ( errnum == EBADF)
5124 {
5125 /* seek and destroy the bad fd
5126 */
5127 for (i = SH_MINSOCK; i < high_fd; ++i)
5128 {
5129 if ((conns[i].state == CONN_READING) ||
5130 (conns[i].state == CONN_SENDING))
5131 {
5132 if (-1 == retry_fcntl(FIL__, __LINE__,
5133 conns[i].fd, F_GETFL, dummy))
5134 sh_forward_do_free ( &conns[i]);
5135 }
5136 }
5137 continue;
5138 }
5139
5140 sh_error_handle((-1), FIL__, __LINE__, errnum, MSG_EXIT_ABORTS,
5141 sh_error_message(errnum),
5142 sh.prg_name,
5143 _("select"));
5144 aud_exit(FIL__, __LINE__, EXIT_FAILURE );
5145 }
5146
5147
5148 /* log the timestamp
5149 */
5150 if ((tcurrent - told) > sh.looptime )
5151 {
5152 told = tcurrent;
5153#ifdef MEM_DEBUG
5154 sh_mem_check();
5155 sh_unix_count_mlock();
5156#else
5157 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_STAMP);
5158#endif
5159 }
5160
5161#if defined(SH_WITH_MAIL)
5162 /*
5163 * flush the mail queue
5164 */
5165 if (tcurrent - sh.mailTime.alarm_last > sh.mailTime.alarm_interval)
5166 {
5167 TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
5168 (void) sh_mail_msg (NULL);
5169 sh.mailTime.alarm_last = tcurrent;
5170 }
5171#endif
5172#ifdef MEM_DEBUG
5173 sh_mem_dump();
5174#endif
5175
5176 tcurrent = (unsigned long) time (NULL);
5177
5178 /* check for time limit exceeded
5179 */
5180 if ((tcurrent - tchkold) > (unsigned int) 3 )
5181 {
5182 tchkold = tcurrent;
5183 client_time_check(/* all_clients */);
5184 }
5185
5186 /* seed / re-seed the PRNG if required
5187 */
5188 (void) taus_seed();
5189
5190 /* select() timeout handling.
5191 */
5192 if ( num_sel == 0 ) /* timeout - no connection */
5193 {
5194 if (sh_html_write(all_clients) < 0)
5195 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5196 continue;
5197 }
5198
5199 /* New connection.
5200 */
5201 if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection */
5202 {
5203 --num_sel;
5204 status = 0;
5205 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
5206 {
5207 i = SH_MINSOCK;
5208 while (i < maxconn)
5209 {
5210 if (conns[i].state == CONN_FREE)
5211 {
5212 status = sh_forward_accept (conns[0].fd, &conns[i]);
5213 if (status == 0)
5214 {
5215 high_fd =
5216 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
5217 ++server_status.conn_open;
5218 ++server_status.conn_total;
5219 server_status.last = time (NULL);
5220 }
5221 break;
5222 }
5223 ++i;
5224 }
5225 }
5226 if (status == 0)
5227 continue;
5228 }
5229
5230 /* check for commands on the socket
5231 */
5232 if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
5233 {
5234 sh_socket_poll();
5235 }
5236
5237#ifdef INET_SYSLOG
5238 if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
5239 {
5240 recv_syslog_socket (conns[2].fd);
5241 }
5242#endif
5243
5244 /* Check for pending read/write on the rest of the sockets.
5245 */
5246 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
5247 {
5248 if (sig_termfast == 1)
5249 break;
5250
5251 cx = &conns[i];
5252 if ( cx->state == CONN_READING &&
5253 FD_ISSET( cx->fd, &readset ) )
5254 {
5255 --num_sel;
5256 sh_forward_do_read ( cx );
5257 }
5258 else if ( cx->state == CONN_SENDING &&
5259 FD_ISSET( cx->fd, &writeset ) )
5260 {
5261 --num_sel;
5262 sh_forward_do_write ( cx );
5263 }
5264 }
5265 /* continue */
5266 }
5267 /* notreached */
5268}
5269
5270void free_client_tree ()
5271{
5272 SL_ENTER(_("free_client_tree"));
5273 zAVLFreeTree (all_clients, free_client);
5274 SL_RET0(_("free_client_tree"));
5275}
5276
5277void sh_forward_free_all ()
5278{
5279 register int i;
5280
5281 SL_ENTER(_("sh_forward_free_all"));
5282
5283 if (conns != NULL)
5284 for (i = SH_MINSOCK; i < maxconn; ++i)
5285 {
5286 sh_forward_do_free ( &conns[i]);
5287 }
5288
5289
5290 free_client_tree ();
5291
5292 if (conns != NULL)
5293 SH_FREE (conns);
5294
5295 SL_RET0(_("sh_forward_free_all"));
5296}
5297
5298#ifdef INET_SYSLOG
5299
5300#ifdef HAVE_INET_ATON
5301static char * my_inet_ntoa(struct in_addr in)
5302{
5303 return inet_ntoa(in);
5304}
5305#else
5306static char * my_inet_ntoa(struct in_addr in)
5307{
5308 unsigned char a, b, c, d;
5309 static char foo[16];
5310 char bar[4];
5311 memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
5312 memcpy (&a, &bar[0], 1);
5313 memcpy (&b, &bar[1], 1);
5314 memcpy (&c, &bar[2], 1);
5315 memcpy (&d, &bar[3], 1);
5316 sprintf(foo, "%d.%d.%d.%d", /* known to fit */
5317 (int) a, (int) b, (int) c, (int) d);
5318 return foo;
5319}
5320#endif
5321
5322
5323/* Unlike Linux / FreeBSD, most systems don't define the stuff below
5324 * in syslog.h
5325 */
5326
5327#ifndef LOG_FAC
5328#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
5329#endif
5330
5331#ifndef LOG_PRI
5332#define LOG_PRI(p) ((p) & LOG_PRIMASK)
5333#endif
5334
5335typedef struct sh_code {
5336 char *c_name;
5337 int c_val;
5338} SH_CODE;
5339
5340SH_CODE sh_facilitynames[] =
5341{
5342#ifdef LOG_AUTH
5343 { N_("auth"), LOG_AUTH },
5344#endif
5345#ifdef LOG_AUTHPRIV
5346 { N_("authpriv"), LOG_AUTHPRIV },
5347#endif
5348#ifdef LOG_CRON
5349 { N_("cron"), LOG_CRON },
5350#endif
5351#ifdef LOG_DAEMON
5352 { N_("daemon"), LOG_DAEMON },
5353#endif
5354#ifdef LOG_FTP
5355 { N_("ftp"), LOG_FTP },
5356#endif
5357#ifdef LOG_KERN
5358 { N_("kern"), LOG_KERN },
5359#endif
5360#ifdef LOG_LPR
5361 { N_("lpr"), LOG_LPR },
5362#endif
5363#ifdef LOG_MAIL
5364 { N_("mail"), LOG_MAIL },
5365#endif
5366#ifdef INTERNAL_MARK
5367 { N_("mark"), INTERNAL_MARK }, /* INTERNAL */
5368#endif
5369#ifdef LOG_NEWS
5370 { N_("news"), LOG_NEWS },
5371#endif
5372#ifdef LOG_AUTH
5373 { N_("security"), LOG_AUTH }, /* DEPRECATED */
5374#endif
5375#ifdef LOG_SYSLOG
5376 { N_("syslog"), LOG_SYSLOG },
5377#endif
5378#ifdef LOG_USER
5379 { N_("user"), LOG_USER },
5380#endif
5381#ifdef LOG_UUCP
5382 { N_("uucp"), LOG_UUCP },
5383#endif
5384#ifdef LOG_LOCAL0
5385 { N_("local0"), LOG_LOCAL0 },
5386#endif
5387#ifdef LOG_LOCAL1
5388 { N_("local1"), LOG_LOCAL1 },
5389#endif
5390#ifdef LOG_LOCAL2
5391 { N_("local2"), LOG_LOCAL2 },
5392#endif
5393#ifdef LOG_LOCAL3
5394 { N_("local3"), LOG_LOCAL3 },
5395#endif
5396#ifdef LOG_LOCAL4
5397 { N_("local4"), LOG_LOCAL4 },
5398#endif
5399#ifdef LOG_LOCAL5
5400 { N_("local5"), LOG_LOCAL5 },
5401#endif
5402#ifdef LOG_LOCAL6
5403 { N_("local6"), LOG_LOCAL6 },
5404#endif
5405#ifdef LOG_LOCAL7
5406 { N_("local7"), LOG_LOCAL7 },
5407#endif
5408 { NULL, -1 }
5409};
5410
5411
5412SH_CODE sh_prioritynames[] =
5413{
5414#ifdef LOG_ALERT
5415 { N_("alert"), LOG_ALERT },
5416#endif
5417#ifdef LOG_CRIT
5418 { N_("crit"), LOG_CRIT },
5419#endif
5420#ifdef LOG_DEBUG
5421 { N_("debug"), LOG_DEBUG },
5422#endif
5423#ifdef LOG_EMERG
5424 { N_("emerg"), LOG_EMERG },
5425#endif
5426#ifdef LOG_ERR
5427 { N_("err"), LOG_ERR },
5428#endif
5429#ifdef LOG_ERR
5430 { N_("error"), LOG_ERR }, /* DEPRECATED */
5431#endif
5432#ifdef LOG_INFO
5433 { N_("info"), LOG_INFO },
5434#endif
5435#ifdef INTERNAL_NOPRI
5436 { N_("none"), INTERNAL_NOPRI }, /* INTERNAL */
5437#endif
5438#ifdef LOG_NOTICE
5439 { N_("notice"), LOG_NOTICE },
5440#endif
5441#ifdef LOG_EMERG
5442 { N_("panic"), LOG_EMERG }, /* DEPRECATED */
5443#endif
5444#ifdef LOG_WARNING
5445 { N_("warn"), LOG_WARNING }, /* DEPRECATED */
5446#endif
5447#ifdef LOG_WARNING
5448 { N_("warning"), LOG_WARNING },
5449#endif
5450 { NULL, -1 }
5451};
5452
5453static int enable_syslog_socket = S_FALSE;
5454
5455static int recv_syslog_socket (int fd)
5456{
5457 static time_t return_next = 0;
5458 int priority = 0;
5459 int fac, pri;
5460 int i;
5461 char * cfac = NULL;
5462 char * cpri = NULL;
5463 int res;
5464 char * tmp;
5465 char * bptr;
5466 char * ptr = NULL;
5467 char buf[1048];
5468 struct sockaddr_in from;
5469
5470 /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
5471 * but *int everywhere else. Because socklen_t is unsigned int, there
5472 * should be no problem as long as sizeof(struct sockaddr_in) < INT_MAX ...
5473 */
5474 int fromlen = sizeof(from);
5475
5476 if (enable_syslog_socket == S_FALSE)
5477 return 0;
5478
5479 SL_ENTER(_("recv_syslog_socket"));
5480
5481 if (return_next > 0)
5482 {
5483 if ( (time(NULL) - return_next) < 2)
5484 SL_RETURN( 0, _("recv_syslog_socket"));
5485 else
5486 return_next = 0;
5487 }
5488
5489 res = recvfrom(fd, buf, 1047, 0, (struct sockaddr *) &from, &fromlen);
5490
5491 if (res > 0)
5492 {
5493 res = (res < 1047) ? res : 1047;
5494 buf[res] = '\0';
5495 if (res > 1 && buf[res-1] == '\n')
5496 buf[res-1] = '\0';
5497
5498 /* here we expect an xml formatted message, thus we don't
5499 escape xml special chars (flag == 0) */
5500 /* commented out to not escape twice */
5501 /* bptr = sh_tools_safe_name(buf, 0); */
5502 bptr = buf;
5503
5504 if (!bptr || !(*bptr))
5505 {
5506 res = errno;
5507 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5508 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5509 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5510 SL_RETURN( (-1), _("recv_syslog_socket"));
5511 }
5512
5513 TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
5514 my_inet_ntoa(from.sin_addr)));
5515 ptr = bptr;
5516 i = 0;
5517 if (*ptr == '<')
5518 {
5519 ++ptr; ++i;
5520 while (i < res &&
5521 (unsigned char) *ptr > 47 && (unsigned char) *ptr < 58)
5522 {
5523 priority = 10 * priority + (*ptr - '0');
5524 ++ptr;
5525 ++i;
5526 }
5527 if (*ptr == '>')
5528 ++ptr;
5529 }
5530 fac = LOG_FAC(priority);
5531 i = 0;
5532 while (sh_facilitynames[i].c_name != NULL)
5533 {
5534 if (sh_facilitynames[i].c_val == (fac<<3))
5535 { cfac = sh_util_strdup(_(sh_facilitynames[i].c_name)); break; }
5536 ++i;
5537 }
5538 pri = LOG_PRI(priority);
5539 i = 0;
5540 while (sh_prioritynames[i].c_name != NULL)
5541 {
5542 if (sh_prioritynames[i].c_val == pri)
5543 { cpri = sh_util_strdup(_(sh_prioritynames[i].c_name)); break; }
5544 ++i;
5545 }
5546
5547 /* here we do not expect an xml formatted message, thus we escape
5548 xml special chars (flag == 1) */
5549 tmp = sh_tools_safe_name (ptr, 1);
5550 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_INET_SYSLOG,
5551 my_inet_ntoa(from.sin_addr),
5552 (cfac == NULL) ? _("none") : cfac,
5553 (cpri == NULL) ? _("none") : cpri,
5554 (ptr == NULL) ? _("none") : ptr);
5555 if (cfac != NULL)
5556 SH_FREE(cfac);
5557 if (cpri != NULL)
5558 SH_FREE(cpri);
5559 SH_FREE(tmp);
5560 /* SH_FREE(bptr); */
5561 }
5562
5563 else if (res < 0 && errno != EINTR)
5564 {
5565 res = errno;
5566 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5567 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5568 sh_error_message(res), my_inet_ntoa(from.sin_addr));
5569
5570 /* don't accept anything the next 2 seconds
5571 */
5572 return_next = time(NULL);
5573 SL_RETURN( (-1), _("recv_syslog_socket"));
5574 }
5575 SL_RETURN( (0), _("recv_syslog_socket"));
5576}
5577
5578int set_syslog_active(const char * c)
5579{
5580 return sh_util_flagval(c, &enable_syslog_socket);
5581}
5582
5583/* callerFlag == S_TRUE means override the enable_syslog_socket flag
5584 */
5585int create_syslog_socket (int callerFlag)
5586{
5587 int flag = 1; /* non-zero to enable an option */
5588 int sock;
5589 int errnum;
5590 int res;
5591 struct sockaddr_in addr;
5592 int addrlen = sizeof(addr);
5593
5594 SL_ENTER(_("create_syslog_socket"));
5595
5596 if (callerFlag == S_FALSE)
5597 {
5598 if (enable_syslog_socket == S_FALSE && syslog_sock >= 0)
5599 {
5600 /* user does not wish to use this facility
5601 */
5602 TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
5603 close(syslog_sock);
5604 syslog_sock = -1;
5605 }
5606 SL_RETURN((-1), _("create_syslog_socket"));
5607 }
5608
5609 sh_forward_printerr (NULL, 0, 514, __LINE__);
5610
5611 /* create the socket, bind() it and listen()
5612 */
5613 sock = socket(AF_INET, SOCK_DGRAM, 0);
5614
5615 if (sock < 0)
5616 {
5617 errnum = errno;
5618 sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
5619 SL_RETURN((-1), _("create_syslog_socket"));
5620 }
5621 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
5622
5623 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5624 (void *) &flag, sizeof(flag)) < 0 )
5625 {
5626 errnum = errno;
5627 sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
5628 errnum, 514, __LINE__);
5629 SL_RETURN((-1), _("create_syslog_socket"));
5630 }
5631
5632#if defined(SO_BSDCOMPAT)
5633 if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
5634 (void *) &flag, sizeof(flag)) < 0 )
5635 {
5636 errnum = errno;
5637 sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
5638 errnum, 514, __LINE__);
5639 SL_RETURN((-1), _("create_syslog_socket"));
5640 }
5641#endif
5642
5643 memset(&addr, 0, sizeof(addr));
5644 addr.sin_family = AF_INET;
5645 addr.sin_port = htons(514);
5646
5647 res = bind(sock, (struct sockaddr *) &addr, addrlen);
5648
5649 if ( res < 0)
5650 {
5651 errnum = errno;
5652 sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
5653 close(sock);
5654 SL_RETURN((-1), _("create_syslog_socket"));
5655 }
5656
5657 syslog_sock = sock;
5658
5659 SL_RETURN((sock), _("create_syslog_socket"));
5660}
5661/* #ifdef INET_SYSLOG */
5662#endif
5663
5664
5665
5666/* #ifdef SH_WITH_SERVER */
5667#endif
5668
5669
5670
5671
5672
5673
Note: See TracBrowser for help on using the repository browser.