source: trunk/src/sh_forward.c@ 127

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

Code cleanup and minor fixes

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