source: trunk/src/sh_forward.c@ 4

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

More fixes for update function, released 2.1.1 version.

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