source: trunk/src/sh_forward.c@ 300

Last change on this file since 300 was 295, checked in by katerina, 14 years ago

Support for IPv6 (ticket #222).

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