source: trunk/src/sh_forward.c@ 1

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

Initial import

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