source: trunk/src/sh_forward.c@ 289

Last change on this file since 289 was 283, checked in by katerina, 14 years ago

Patch for ticket #207 (server logs client reports to prelude).

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