source: trunk/src/sh_forward.c@ 29

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

Support for server-to-server relay and more user policies

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