source: trunk/src/sh_forward.c@ 11

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

Minor optimisations for server

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