source: trunk/src/sh_forward.c@ 254

Last change on this file since 254 was 252, checked in by katerina, 15 years ago

Add code to check for stale file records on close() and fclose(), fix sl_close() to handle open stream (ticket #163).

File size: 146.0 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <string.h>
23#include <stdio.h>
24#include <stdlib.h>
25
26
27/* Must be early on FreeBSD
28 */
29#include <sys/types.h>
30
31/* must be .le. than (1020 * 64)
32 * (see sh_tools.c -- put_header)
33 *
34 * also: must be (N * 16), otherwise
35 * binary files cannot be transferred encrypted
36 *
37 * 65280 = (1020*64)
38 * #define TRANS_BYTES 8000 V0.8
39 */
40#ifdef SH_ENCRYPT_2
41#define TRANS_BYTES 65120
42#else
43#define TRANS_BYTES 65280
44#endif
45
46/* timeout for session key
47 */
48#define TIMEOUT_KEY 7200
49
50/* max time between connection attempts
51 */
52#define TIMEOUT_CON 2048
53
54/* #undef SRP_DEBUG */
55/* #define SRP_DEBUG */
56
57#ifdef HAVE_MEMORY_H
58#include <memory.h>
59#endif
60
61#if TIME_WITH_SYS_TIME
62#include <sys/time.h>
63#include <time.h>
64#else
65#if HAVE_SYS_TIME_H
66#include <sys/time.h>
67#else
68#include <time.h>
69#endif
70#endif
71
72/*
73#ifdef TM_IN_SYS_TIME
74#include <sys/time.h>
75#else
76#include <time.h>
77#endif
78*/
79
80#ifdef HAVE_SYS_SELECT_H
81#include <sys/select.h>
82#endif
83
84#ifdef HAVE_UNISTD_H
85#include <errno.h>
86#include <signal.h>
87#include <setjmp.h>
88#include <pwd.h>
89#include <grp.h>
90#include <sys/stat.h>
91#include <sys/resource.h>
92#include <fcntl.h>
93#include <sys/wait.h>
94#include <unistd.h>
95#endif
96
97#ifndef FD_SET
98#define NFDBITS 32
99#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
100#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
101#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
102#endif /* !FD_SET */
103#ifndef FD_SETSIZE
104#define FD_SETSIZE 32
105#endif
106#ifndef FD_ZERO
107#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p)))
108#endif
109
110#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
111#include <sys/mman.h>
112#endif
113
114
115#include <netdb.h>
116#include <sys/types.h>
117#include <netinet/in.h>
118#include <sys/socket.h>
119#ifndef S_SPLINT_S
120#include <arpa/inet.h>
121#endif
122
123#include "samhain.h"
124#include "sh_tiger.h"
125#include "sh_utils.h"
126#include "sh_unix.h"
127#include "sh_forward.h"
128#include "sh_srp.h"
129#include "sh_fifo.h"
130#include "sh_tools.h"
131#include "sh_entropy.h"
132#include "sh_html.h"
133#include "sh_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
1992/* Function to return the key for indexing
1993 * the argument
1994 */
1995zAVLKey sh_avl_key (void const * arg)
1996{
1997 const client_t * sa = (const client_t *) arg;
1998 return (zAVLKey) sa->hostname;
1999}
2000
2001zAVLTree * all_clients = NULL;
2002
2003void sh_forward_html_write()
2004{
2005 SL_ENTER(_("sh_forward_html_write"));
2006 sh_html_write(all_clients);
2007 SL_RET0(_("sh_forward_html_write"));
2008}
2009
2010
2011int sh_forward_use_clt_class (const char * c)
2012{
2013 int i;
2014 SL_ENTER(_("sh_forward_use_clt_class"));
2015 i = sh_util_flagval(c, &(sh.flag.client_class));
2016 SL_RETURN(i, _("sh_forward_use_clt_class"));
2017}
2018
2019int sh_forward_use_clt_sev (const char * c)
2020{
2021 int i;
2022 SL_ENTER(_("sh_forward_use_clt_sev"));
2023 i = sh_util_flagval(c, &(sh.flag.client_severity));
2024 SL_RETURN(i, _("sh_forward_use_clt_sev"));
2025}
2026
2027
2028/* the destructor
2029 */
2030void free_client(void * inptr)
2031{
2032 client_t * here;
2033
2034 SL_ENTER(_("free_client"));
2035 if (inptr == NULL)
2036 SL_RET0(_("free_client"));
2037 else
2038 here = (client_t *) inptr;
2039
2040 if (here->hostname != NULL)
2041 SH_FREE(here->hostname);
2042 if (here->salt != NULL)
2043 SH_FREE(here->salt);
2044 if (here->verifier != NULL)
2045 SH_FREE(here->verifier);
2046 SH_FREE(here);
2047 SL_RET0(_("free_client"));
2048}
2049
2050
2051int sh_forward_register_client (const char * str)
2052{
2053 client_t * newclt;
2054 client_t * testclt;
2055
2056 const char * ptr;
2057 int sepnum = 0;
2058 int sep[2];
2059 register int i = 0;
2060 int siz_str = 0;
2061
2062 SL_ENTER(_("sh_forward_register_client"));
2063
2064 ptr = str;
2065 while (*ptr) {
2066 if (*ptr == '@' && sepnum < 2 )
2067 {
2068 sep[sepnum] = i;
2069 ++sepnum;
2070 }
2071 ++ptr; ++i;
2072 }
2073
2074 if (all_clients == NULL)
2075 {
2076 all_clients = zAVLAllocTree (sh_avl_key);
2077 if (all_clients == NULL)
2078 {
2079 (void) safe_logger (0, 0, NULL);
2080 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
2081 }
2082 }
2083
2084 if ((sepnum == 2) && (sep[0] > 0) && (sep[1] > sep[0]))
2085 {
2086 newclt = SH_ALLOC (sizeof(client_t));
2087 newclt->hostname = SH_ALLOC (sep[0]+1);
2088 newclt->salt = SH_ALLOC (sep[1]-sep[0]);
2089 newclt->verifier = SH_ALLOC (sl_strlen(str)-sep[1]+1);
2090 newclt->exit_flag = 0;
2091 newclt->dead_flag = 0;
2092#ifdef SH_ENCRYPT
2093#ifdef SH_ENCRYPT_2
2094 newclt->encf_flag = SH_PROTO_ENC|SH_PROTO_EN2;
2095 newclt->ency_flag = SH_PROTO_ENC|SH_PROTO_EN2;
2096#else
2097 newclt->encf_flag = SH_PROTO_ENC;
2098 newclt->ency_flag = SH_PROTO_ENC;
2099#endif
2100#else
2101 newclt->encf_flag = 0;
2102 newclt->ency_flag = 0;
2103#endif
2104 newclt->session_key[0] = '\0';
2105 newclt->last_connect = (time_t) 0;
2106 newclt->session_key_timer = (time_t) 0;
2107 newclt->status_now = CLT_INACTIVE;
2108 for (i = 0; i < CLT_MAX; ++i)
2109 newclt->status_arr[i] = CLT_INACTIVE;
2110 (void) sh_unix_time(0, newclt->timestamp[CLT_INACTIVE], TIM_MAX);
2111 /* truncate */
2112 sl_strlcpy(newclt->hostname, &str[0], sep[0]+1);
2113 /* truncate */
2114 sl_strlcpy(newclt->salt, &str[sep[0]+1], sep[1]-sep[0]);
2115 sl_strlcpy(newclt->verifier, &str[sep[1]+1], sl_strlen(str)-sep[1]+1);
2116
2117 testclt = (client_t *) zAVLSearch (all_clients, newclt->hostname);
2118
2119 if (testclt != NULL)
2120 {
2121 SH_FREE(testclt->verifier);
2122 siz_str = strlen (newclt->verifier) + 1;
2123 testclt->verifier = SH_ALLOC (siz_str);
2124 sl_strlcpy(testclt->verifier, newclt->verifier, siz_str);
2125
2126 SH_FREE(testclt->salt);
2127 siz_str = strlen (newclt->salt) + 1;
2128 testclt->salt = SH_ALLOC (siz_str);
2129 sl_strlcpy(testclt->salt, newclt->salt, siz_str);
2130
2131 testclt->dead_flag = 0;
2132
2133 free_client(newclt);
2134 SL_RETURN( 0, _("sh_forward_register_client"));
2135 }
2136 else
2137 {
2138 if (0 == zAVLInsert (all_clients, newclt))
2139 {
2140 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CREG,
2141 newclt->hostname,
2142 newclt->salt, newclt->verifier);
2143 SL_RETURN( 0, _("sh_forward_register_client"));
2144 }
2145 }
2146 }
2147 SL_RETURN (-1, _("sh_forward_register_client"));
2148}
2149
2150typedef struct {
2151 int state;
2152 int fd;
2153 char * buf;
2154 unsigned char head[SH_HEADER_SIZE];
2155 char challenge[SH_CHALLENGE_SIZE];
2156 char peer[SH_MINIBUF+1];
2157 client_t * client_entry;
2158 char * K;
2159 char * M1;
2160 char * A;
2161 int headcount;
2162 unsigned long bytecount;
2163 unsigned long bytes_to_send;
2164 unsigned long bytes_to_get;
2165 int pass;
2166 unsigned long timer;
2167
2168 char * FileName;
2169 unsigned long FileLength;
2170 unsigned long FileSent;
2171 char FileType[5];
2172
2173 struct sockaddr_in addr_peer;
2174} sh_conn_t;
2175
2176
2177static char zap_challenge[SH_CHALLENGE_SIZE] = { 0 };
2178
2179void sh_forward_do_free (sh_conn_t * conn)
2180{
2181 SL_ENTER(_("sh_forward_do_free"));
2182
2183 if (conn->K != NULL)
2184 {
2185 SH_FREE(conn->K);
2186 conn->K = NULL;
2187 }
2188 if (conn->A != NULL)
2189 {
2190 SH_FREE(conn->A);
2191 conn->A = NULL;
2192 }
2193 if (conn->M1 != NULL)
2194 {
2195 SH_FREE(conn->M1);
2196 conn->M1 = NULL;
2197 }
2198 if (conn->buf != NULL)
2199 {
2200 SH_FREE(conn->buf);
2201 conn->buf = NULL;
2202 }
2203 if (conn->fd != (-1))
2204 {
2205 sl_close_fd (FIL__, __LINE__, conn->fd);
2206 conn->fd = -1;
2207 }
2208 memcpy(conn->challenge, zap_challenge, SH_CHALLENGE_SIZE);
2209 conn->state = CONN_FREE;
2210 conn->headcount = 0;
2211 conn->bytecount = 0;
2212 conn->bytes_to_send = 0;
2213 conn->bytes_to_get = 0;
2214 conn->pass = 0;
2215 conn->timer = 0;
2216 conn->client_entry = NULL;
2217
2218 if (conn->FileName != NULL)
2219 {
2220 SH_FREE(conn->FileName);
2221 conn->FileName = NULL;
2222 }
2223 conn->FileLength = 0;
2224 conn->FileSent = 0;
2225 conn->FileType[0] = '\0';
2226 conn->FileType[1] = '\0';
2227 conn->FileType[2] = '\0';
2228 conn->FileType[3] = '\0';
2229 conn->FileType[4] = '\0';
2230
2231 --server_status.conn_open;
2232
2233 SL_RET0(_("sh_forward_do_free"));
2234}
2235
2236/****************************************
2237 *
2238 * -- Reconfiguration. --
2239 *
2240 * (1) Mark all clients as 'dead'.
2241 * (2) Reload configuration - clients
2242 * in config are non-dead now.
2243 * (3) Remove all clients still
2244 * marked as 'dead'.
2245 */
2246
2247/* -- Mark all clients as dead.
2248 */
2249void sh_forward_mark_dead (void)
2250{
2251 zAVLCursor avlcursor;
2252 client_t * item;
2253
2254 SL_ENTER(_("sh_forward_mark_dead"));
2255
2256 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2257 item = (client_t *) zAVLNext(&avlcursor))
2258 {
2259 item->dead_flag = 1;
2260 }
2261 SL_RET0(_("sh_forward_mark_dead"));
2262}
2263
2264
2265/* -- Clean tree from dead clients.
2266 */
2267void sh_forward_clean_tree (void)
2268{
2269 zAVLCursor avlcursor;
2270 client_t * item;
2271
2272 SL_ENTER(_("sh_forward_clean_tree"));
2273
2274 repeat_search:
2275
2276 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2277 item = (client_t *) zAVLNext(&avlcursor))
2278 {
2279 if (item->dead_flag == 1)
2280 {
2281 zAVLDelete (all_clients, item->hostname);
2282 free_client (item);
2283 goto repeat_search;
2284 }
2285 }
2286 SL_RET0(_("sh_forward_clean_tree"));
2287}
2288
2289/*
2290 *
2291 **********************************************/
2292
2293
2294
2295/* -- SERVER SEND FUNKTION. --
2296 */
2297void sh_forward_prep_send_int (sh_conn_t * conn,
2298 char * msg, unsigned long length,
2299 char * u, char protocol,
2300 int docrypt)
2301{
2302 /* register unsigned long i; */
2303 unsigned long length2;
2304
2305#ifdef SH_ENCRYPT
2306 unsigned long blkfac = 0;
2307 int rem = 0;
2308 char * p, * q;
2309 RIJ_BYTE inBlock[B_SIZ];
2310 RIJ_BYTE outBlock[B_SIZ];
2311 unsigned int j;
2312 cipherInstance cipherInst;
2313 int err_num;
2314 char expbuf[SH_ERRBUF_SIZE];
2315#else
2316 (void) docrypt;
2317#endif
2318
2319 SL_ENTER(_("sh_forward_prep_send_int"));
2320
2321 TPT((0, FIL__, __LINE__, _("msg=<%s>, docrypt=<%d>\n"), msg, docrypt ));
2322
2323#ifdef SH_ENCRYPT
2324 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0) )
2325 {
2326 length2 = length;
2327 }
2328 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0) )
2329 {
2330 blkfac = length/B_SIZ;
2331 rem = length - (B_SIZ * blkfac);
2332 length2 = (B_SIZ * blkfac);
2333 if (rem > 0 && (length2 + B_SIZ) > length2)
2334 length2 += B_SIZ;
2335 else
2336 rem = 0;
2337 }
2338 else
2339 {
2340 length2 = length;
2341 }
2342#else
2343 length2 = length;
2344#endif
2345
2346 conn->headcount = 0;
2347 conn->bytecount = 0;
2348 conn->bytes_to_send = 0;
2349 conn->bytes_to_get = 0;
2350
2351 if (conn->buf != NULL)
2352 {
2353 SH_FREE(conn->buf);
2354 conn->buf = NULL;
2355 }
2356
2357
2358 put_header (conn->head, protocol, &length2, u);
2359 SH_SHOWPROT(conn->head,'>');
2360
2361 TPT((0, FIL__, __LINE__, _("msg=<put_header done>\n") ));
2362
2363 if (msg == NULL)
2364 length2 = 0;
2365
2366#ifdef SH_ENCRYPT
2367 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != 0))
2368 {
2369 TPT((0, FIL__, __LINE__, _("encrypting (version 2)\n")));
2370
2371 conn->buf = sh_tools_makePack (conn->head, msg, length2,
2372 &(conn->client_entry->keyInstE));
2373 }
2374 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0) &&
2375 ((length2 + 1) > length2))
2376 {
2377 conn->buf = SH_ALLOC(length2 + 1);
2378
2379 p = msg;
2380 q = conn->buf;
2381
2382 TPT((0, FIL__, __LINE__, _("encrypting (version 1)\n")));
2383
2384 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
2385 if (err_num < 0)
2386 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2387 errorExplain(err_num, expbuf, sizeof(expbuf)),
2388 _("sh_forward_prep_send_int: cipherInit"));
2389
2390 for (j = 0; j < blkfac; ++j)
2391 {
2392 memcpy(inBlock, p, B_SIZ);
2393 err_num = blockEncrypt(&cipherInst, &(conn->client_entry->keyInstE),
2394 inBlock, 128 * BNUM, outBlock);
2395 if (err_num < 0)
2396 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2397 errorExplain(err_num, expbuf, sizeof(expbuf)),
2398 _("sh_forward_prep_send_int: blockEncrypt"));
2399 memcpy(q, outBlock, B_SIZ);
2400 p += B_SIZ;
2401 q += B_SIZ;
2402 }
2403 if (rem > 0)
2404 {
2405 /* incomplete block at end
2406 */
2407 memset(inBlock, '\0', B_SIZ);
2408 memcpy(inBlock, p, rem);
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 q += B_SIZ;
2417 }
2418
2419 TPT((0, FIL__, __LINE__, _("msg=<encryption done>\n") ));
2420 }
2421 else
2422 {
2423 if ((length2 + 1) < length2) --length2;
2424 conn->buf = SH_ALLOC(length2 + 1);
2425
2426 memcpy(conn->buf, msg, length2);
2427 /*
2428 for (i = 0; i < length2; ++i)
2429 conn->buf[i] = msg[i];
2430 */
2431 conn->buf[length2] = '\0';
2432 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2433 }
2434#else
2435 if ((length2 + 1) < length2) --length2;
2436 conn->buf = SH_ALLOC(length2 + 1);
2437
2438 memcpy(conn->buf, msg, length2);
2439 /*
2440 for (i = 0; i < length; ++i)
2441 conn->buf[i] = msg[i];
2442 */
2443 conn->buf[length2] = '\0';
2444 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
2445#endif
2446
2447 conn->state = CONN_SENDING;
2448 SL_RET0(_("sh_forward_prep_send_int"));
2449}
2450
2451/* -- Send/Receive. --
2452 */
2453void sh_forward_prep_send (sh_conn_t * conn,
2454 char * msg, unsigned long length,
2455 char * u, char protocol)
2456{
2457 SL_ENTER(_("sh_forward_prep_send"));
2458 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_FALSE);
2459 SL_RET0(_("sh_forward_prep_send"));
2460}
2461
2462void sh_forward_prep_send_crypt (sh_conn_t * conn,
2463 char * msg, unsigned long length,
2464 char * u, char protocol)
2465{
2466 SL_ENTER(_("sh_forward_prep_send_crypt"));
2467 sh_forward_prep_send_int (conn, msg, length, u, protocol, S_TRUE);
2468 SL_RET0(_("sh_forward_prep_send_crypt"));
2469}
2470
2471/* #include <sys/times.h> */
2472
2473#if defined(WITH_EXTERNAL)
2474#include "sh_extern.h"
2475#endif
2476
2477/* -- Update the client status. --
2478 *
2479 * Update the status array for the client,
2480 * and eventually call external program.
2481 */
2482static void status_update (client_t * conn, int status)
2483{
2484#if defined(WITH_EXTERNAL)
2485 char msg[2 * SH_MINIBUF + TIM_MAX + 3];
2486#endif
2487
2488 SL_ENTER(_("status_update"));
2489
2490 if (conn == NULL ||
2491 status < 0 || status >= CLT_MAX)
2492 SL_RET0(_("status_update"));
2493
2494 conn->status_now = status;
2495 conn->status_arr[status] = status;
2496 (void) sh_unix_time(0, conn->timestamp[status], TIM_MAX);
2497
2498#if defined(WITH_EXTERNAL)
2499 sl_snprintf(msg, sizeof(msg), _("%s %s %s"),
2500 conn->hostname, conn->timestamp[status], _(clt_stat[status]));
2501 sh_ext_execute('s', 'r', 'v', msg, 0);
2502#endif
2503
2504 SL_RET0(_("status_update"));
2505}
2506
2507static time_t time_client_limit = 86400;
2508
2509int sh_forward_set_time_limit (const char * c)
2510{
2511 long val;
2512
2513 SL_ENTER(_("sh_forward_set_time_limit"));
2514
2515 val = strtol (c, (char **)NULL, 10);
2516 if (val <= 0)
2517 SL_RETURN( (-1), _("sh_forward_set_time_limit"));
2518
2519 val = (val < 0 ? 0 : val);
2520
2521 time_client_limit = (time_t) val;
2522 SL_RETURN( (0), _("sh_forward_set_time_limit"));
2523}
2524
2525
2526/* -- Check for time limit exceeded. --
2527 */
2528static int client_time_check(void)
2529{
2530 zAVLCursor avlcursor;
2531 client_t * item;
2532
2533 SL_ENTER(_("client_time_check"));
2534
2535 if (time_client_limit == (time_t) 0)
2536 SL_RETURN( 0, _("client_time_check"));
2537
2538 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
2539 item = (client_t *) zAVLNext(&avlcursor))
2540 {
2541 if (item->exit_flag == 0 && item->last_connect != (time_t) 0)
2542 {
2543 if ( (time(NULL) - item->last_connect) > time_client_limit)
2544 {
2545 if (item->status_now != CLT_TOOLONG)
2546 {
2547 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMEXC,
2548 item->hostname);
2549 status_update (item, CLT_TOOLONG);
2550 }
2551 }
2552 }
2553 }
2554 SL_RETURN( 0, _("client_time_check"));
2555}
2556
2557static int lookup_err = SH_ERR_SEVERE;
2558
2559int sh_forward_lookup_level (const char * c)
2560{
2561 int ci = sh_error_convert_level (c);
2562
2563 SL_ENTER(_("sh_forward_lookup_level"));
2564
2565 if (ci >= 0)
2566 {
2567 lookup_err = ci;
2568 SL_RETURN( 0, _("sh_forward_lookup_level"));
2569 }
2570 else
2571 SL_RETURN( (-1), _("sh_forward_lookup_level"));
2572}
2573
2574#ifndef MAXHOSTNAMELEN
2575#define MAXHOSTNAMELEN 127
2576#endif
2577
2578int check_addr (const char * claim, struct sockaddr_in addr_peer)
2579{
2580 char h_name[MAXHOSTNAMELEN + 1];
2581 char h_peer[MAXHOSTNAMELEN + 1];
2582 char h_peer_IP[16];
2583 char tmp_peer_IP[16];
2584 struct hostent * he;
2585 char ** p = NULL;
2586 int i;
2587 int flag = 0;
2588
2589 SL_ENTER(_("check_addr"));
2590
2591 if (claim == NULL)
2592 {
2593 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2594 _("NULL input"), _("check_addr"));
2595 SL_RETURN ((-1), _("check_addr"));
2596 }
2597
2598 /* Make sure we have the canonical name for the client
2599 */
2600 he = sh_gethostbyname (claim);
2601
2602 if (he != NULL && he->h_name != NULL)
2603 {
2604 if (NULL == strchr(he->h_name, '.') && he->h_addr_list != NULL)
2605 {
2606 he = sh_gethostbyaddr(he->h_addr_list[0],
2607 he->h_length,
2608 he->h_addrtype);
2609 }
2610 }
2611
2612 /* copy canonical name into h_name
2613 */
2614 if (he != NULL && he->h_name != NULL)
2615 sl_strlcpy(h_name, he->h_name, MAXHOSTNAMELEN + 1);
2616 else
2617 {
2618 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESCLT,
2619 claim);
2620 SL_RETURN ((0), _("check_addr"));
2621 }
2622
2623
2624 /* get canonical name of socket peer
2625 */
2626 he = sh_gethostbyaddr ((char *) &(addr_peer.sin_addr),
2627 sizeof(addr_peer.sin_addr),
2628 AF_INET);
2629
2630 if (he != NULL && he->h_name != NULL)
2631 {
2632 if (0 == sl_strcmp(he->h_name, _("localhost")))
2633 sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
2634 else
2635 sl_strlcpy(h_peer, he->h_name, MAXHOSTNAMELEN + 1);
2636 }
2637 else
2638 {
2639 sl_strlcpy(tmp_peer_IP,
2640 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2641 16);
2642 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
2643 claim, tmp_peer_IP);
2644 SL_RETURN ((0), _("check_addr"));
2645 }
2646
2647 sl_strlcpy(h_peer_IP,
2648 inet_ntoa (*(struct in_addr *) he->h_addr),
2649 16);
2650
2651#if 0
2652 if (S_FALSE == DoReverseLookup)
2653 {
2654 SL_RETURN ((0), _("check_addr"));
2655 }
2656#endif
2657
2658 /* reverse lookup
2659 */
2660 if (0 != sl_strncmp(_("127."),
2661 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2662 4))
2663 {
2664 he = sh_gethostbyname(h_peer);
2665
2666 if (he != NULL)
2667 {
2668 for (p = he->h_addr_list; *p; ++p)
2669 {
2670 if (0 == memcmp (*p, &(addr_peer.sin_addr),
2671 sizeof(addr_peer.sin_addr)))
2672 break;
2673 }
2674 }
2675 if (he == NULL || *p == NULL)
2676 {
2677 sl_strlcpy(tmp_peer_IP,
2678 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2679 16);
2680 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
2681 claim, h_peer, tmp_peer_IP);
2682 SL_RETURN ((0), _("check_addr"));
2683 }
2684 }
2685
2686
2687 if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
2688 {
2689 SL_RETURN ((0), _("check_addr"));
2690 }
2691 else
2692 {
2693 i = 0;
2694 while (he->h_aliases[i] != NULL)
2695 {
2696 if (0 == sl_strcmp(he->h_aliases[i], h_name))
2697 {
2698 flag = 1;
2699 break;
2700 }
2701 ++i;
2702 }
2703 if (flag == 0)
2704 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKUP,
2705 claim, h_peer);
2706 }
2707
2708 SL_RETURN ((0), _("check_addr"));
2709}
2710
2711static int UseSocketPeer = S_FALSE;
2712
2713int set_socket_peer (const char * c)
2714{
2715 return sh_util_flagval(c, &UseSocketPeer);
2716}
2717
2718
2719/* -- Search register. --
2720 */
2721client_t * search_register(sh_conn_t * conn, int pos)
2722{
2723 client_t * this_client;
2724 char peer_ip[16];
2725 char peer_name[MAXHOSTNAMELEN+1];
2726 char * search_string;
2727 struct sockaddr_in peer_addr;
2728 struct hostent * he;
2729 char ** p = NULL;
2730
2731 SL_ENTER(_("search_register"));
2732
2733 if (UseSocketPeer == S_TRUE)
2734 {
2735 peer_addr = conn->addr_peer;
2736 sl_strlcpy(peer_ip,
2737 inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
2738
2739 /* get canonical name of socket peer
2740 */
2741 he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr),
2742 sizeof(peer_addr.sin_addr),
2743 AF_INET);
2744
2745 if (he != NULL && he->h_name != NULL)
2746 {
2747 if (0 == sl_strcmp(he->h_name, _("localhost")))
2748 sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
2749 else
2750 sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
2751
2752 /* Reverse lookup
2753 */
2754 if (0 != sl_strncmp(peer_ip, _("127."), 4))
2755 {
2756 he = sh_gethostbyname(peer_name);
2757
2758 if (he != NULL)
2759 {
2760 for (p = he->h_addr_list; *p; ++p)
2761 {
2762 if (0 == memcmp (*p, &(peer_addr.sin_addr),
2763 sizeof(peer_addr.sin_addr)))
2764 break;
2765 }
2766 }
2767 if (he == NULL || *p == NULL)
2768 {
2769 /*
2770 sh_error_handle(lookup_err, FIL__, __LINE__, 0,
2771 MSG_TCP_LOOKERS,
2772 conn->buf[pos], peer_name, peer_ip);
2773 */
2774 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2775 }
2776 }
2777 }
2778 else
2779 {
2780 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2781 }
2782 search_string = peer_name;
2783 }
2784 else
2785 {
2786 search_string = &(conn->buf[pos]);
2787
2788 if (0 != check_addr (search_string, conn->addr_peer))
2789 {
2790 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2791 _("Reverse lookup failed"), search_string);
2792 sh_forward_do_free (conn);
2793 SL_RETURN( NULL, _("search_register"));
2794 }
2795 }
2796
2797 /* ---- search the register -----
2798 */
2799 this_client = zAVLSearch(all_clients, search_string);
2800
2801 if (this_client == NULL)
2802 {
2803 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2804 _("Not in client list"), search_string);
2805 sh_forward_do_free (conn);
2806 SL_RETURN( NULL, _("search_register"));
2807 }
2808 if (this_client->exit_flag == 1)
2809 {
2810 TPT((0, FIL__, __LINE__, _("msg=<this_client->exit_flag == 1>\n")));
2811 this_client->session_key_timer = (time_t) 0;
2812 this_client->session_key[0] = '\0';
2813 this_client->exit_flag = 0;
2814 }
2815 TPT((0, FIL__, __LINE__, _("msg=<search_register: client %s>\n"),
2816 this_client->hostname));
2817 TPT((0, FIL__, __LINE__, _("msg=<search_register: key %s>\n"),
2818 this_client->session_key));
2819 SL_RETURN( this_client, _("search_register"));
2820}
2821
2822
2823/************************************************************************
2824 *
2825 * Here we check the message received, and decide on the answer to send
2826 * (if any). The connection is in CONN_PAUSED state, thus we must:
2827 * (i) define the proper reaction
2828 * (ii) reset to CONN_READING or CONN_WRITING or CONN_FREE
2829 * (iii) eventually reset the connection entry
2830 *
2831 *************************************************************************/
2832static
2833void check_protocol(sh_conn_t * conn, int state)
2834{
2835 client_t * this_client;
2836
2837 char * cmd;
2838
2839 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
2840 char * buffer;
2841
2842 int clt_sev;
2843 char * ptok;
2844
2845 UINT32 ticks;
2846 size_t len;
2847 int i;
2848 char * test;
2849 char u[5] = "OOOO";
2850
2851 SL_TICKET sfd = -1;
2852 char * read_buf = 0;
2853 char * send_buf;
2854 int bytes;
2855
2856#ifdef SH_ENCRYPT
2857 int blkfac;
2858 int rem;
2859 int send_bytes;
2860 int err_num;
2861 char expbuf[SH_ERRBUF_SIZE];
2862#endif
2863
2864
2865#ifdef USE_SRP_PROTOCOL
2866 char * foo_B;
2867 char * foo_Ss;
2868#endif
2869 char hashbuf[KEYBUF_SIZE];
2870 char sigbuf[KEYBUF_SIZE];
2871
2872 SL_ENTER(_("check_protocol"));
2873
2874 /* seed / re-seed the PRNG if required
2875 */
2876 (void) taus_seed();
2877
2878
2879 /* protocols:
2880 * -- (iii) file transfer
2881 * -- (ii) authenticated message transfer
2882 * -- (i) SRP key exchange
2883 */
2884
2885 /* --------- FILE TRANSFER -----------
2886 */
2887 if ( (conn->head[0] & SH_PROTO_SRP) == 0 &&
2888 (conn->head[0] & SH_PROTO_BIG) != 0 /* is set */ )
2889 {
2890
2891 if (state == SH_DO_READ) /* finished reading */
2892 {
2893 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
2894
2895 /* -- Client requests challenge. --
2896 */
2897 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
2898 {
2899
2900 TPT(( 0, FIL__, __LINE__,
2901 _("msg=<File transfer - HELO (1).>\n")));
2902
2903 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN)
2904 {
2905 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
2906 sh_forward_do_free (conn);
2907 SL_RET0(_("check_protocol"));
2908 }
2909
2910 /* ---- search the register -----
2911 */
2912
2913 this_client = search_register (conn, KEY_LEN);
2914 if (this_client == NULL)
2915 SL_RET0(_("check_protocol"));
2916
2917 /* ---- force authentication -----
2918 */
2919
2920 if (this_client->session_key[0] == '\0' ||
2921 (time(NULL) - this_client->session_key_timer)
2922 > (time_t) TIMEOUT_KEY )
2923 {
2924 /* fake an auth request and jump there
2925 */
2926 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
2927 conn->head[3] = 'S';
2928 conn->head[4] = 'A';
2929 conn->head[5] = 'L';
2930 conn->head[6] = 'T';
2931 if (flag_err_info == SL_TRUE)
2932 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
2933 &(conn->buf[KEY_LEN]));
2934 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
2935 /* &(conn->buf[KEY_LEN]) is hostname */
2936 /* may overlap, thus only memmove is correct */
2937 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
2938 this_client->session_key[0] = '\0';
2939 this_client->session_key_timer = (time_t) 1;
2940 goto servInit;
2941 }
2942
2943 /* --- check whether hostname is properly signed ---
2944 */
2945 if (conn->K != NULL)
2946 {
2947 SH_FREE(conn->K);
2948 conn->K = NULL;
2949 }
2950
2951 /* FIXME
2952 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
2953 if (sl_ok_adds(len, KEY_LEN))
2954 len += KEY_LEN;
2955 len = (len < (KEY_LEN+1)) ? (KEY_LEN+1) : len;
2956 */
2957 conn->K = SH_ALLOC(KEY_LEN+1);
2958
2959 sl_strlcpy (conn->K,
2960 sh_util_siggen(this_client->session_key,
2961 &(conn->buf[KEY_LEN]),
2962 sl_strlen(&(conn->buf[KEY_LEN])),
2963 sigbuf, sizeof(sigbuf)),
2964 KEY_LEN+1);
2965 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
2966 &(conn->buf[KEY_LEN])));
2967 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
2968 this_client->session_key));
2969 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
2970 sh_util_siggen(this_client->session_key,
2971 &(conn->buf[KEY_LEN]),
2972 sl_strlen(&(conn->buf[KEY_LEN])),
2973 sigbuf, sizeof(sigbuf))));
2974
2975 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
2976 {
2977 TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf));
2978 TPT((0, FIL__, __LINE__, _("msg=<srv %s>\n"), conn->K));
2979 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2980 _("Signature mismatch"),
2981 &(conn->buf[KEY_LEN]));
2982
2983 this_client->session_key_timer =
2984 time(NULL) - (2*TIMEOUT_KEY);
2985
2986 sh_forward_do_free (conn);
2987 SL_RET0(_("check_protocol"));
2988 }
2989 SH_FREE(conn->K);
2990 conn->K = NULL;
2991
2992 /* --- create and send a nonce ---
2993 */
2994
2995 conn->client_entry = this_client;
2996 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
2997
2998 ticks = (UINT32) taus_get ();
2999
3000 if (conn->K != NULL)
3001 {
3002 SH_FREE(conn->K);
3003 conn->K = NULL;
3004 }
3005 conn->K = SH_ALLOC(KEY_LEN+1);
3006 sl_strlcpy (conn->K,
3007 sh_tiger_hash ((char *) &ticks,
3008 TIGER_DATA, sizeof(UINT32),
3009 hashbuf, sizeof(hashbuf)),
3010 KEY_LEN+1);
3011
3012 TPT((0, FIL__, __LINE__, _("msg=<send nonce>\n")));
3013 sh_forward_prep_send (conn, conn->K, KEY_LEN+1, _("NSRV"),
3014 SH_PROTO_BIG);
3015 }
3016
3017 /* --- Client has send a message. Check state and message. ---
3018 */
3019 else if (0 == check_request_nerr((char *)&(conn->head[3]), _("NCLT")) &&
3020 conn->client_entry != NULL &&
3021 sl_strlen(conn->buf) > KEY_LEN &&
3022 conn->K != NULL)
3023 {
3024
3025 TPT(( 0, FIL__, __LINE__,
3026 _("msg=<File transfer - NCLT (3).>\n")));
3027
3028 /* --- get client nonce and compute hash ---
3029 */
3030 if (conn->A != NULL)
3031 {
3032 SH_FREE(conn->A);
3033 conn->A = NULL;
3034 }
3035 conn->A = SH_ALLOC(3*KEY_LEN+1);
3036 sl_strlcpy (conn->A, conn->K, KEY_LEN+1);
3037 sl_strlcat(conn->A, conn->buf, /* truncate */
3038 2*KEY_LEN+1);
3039 sl_strlcat(conn->A, conn->client_entry->session_key,
3040 3*KEY_LEN+1);
3041 sl_strlcpy (conn->K, sh_tiger_hash(conn->A,TIGER_DATA,3*KEY_LEN,
3042 hashbuf, sizeof(hashbuf)),
3043 KEY_LEN+1);
3044 SH_FREE(conn->A);
3045 conn->A = NULL;
3046
3047
3048#ifdef SH_ENCRYPT
3049 if ((conn->client_entry->encf_flag != 0) &&
3050 ((conn->head[0] & SH_PROTO_ENC) == 0))
3051 {
3052 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3053 _("file download"),
3054#ifdef SH_ENCRYPT_2
3055 _("version2"),
3056#else
3057 _("version1"),
3058#endif
3059 _("none"));
3060 if (sl_strlen(conn->buf) > (KEY_LEN + 5)) {
3061 if (sh_tools_hash_vfy(conn->K, conn->buf, KEY_LEN+5)) {
3062 if (conn->buf[KEY_LEN+4] == conn->head[0]) {
3063 /* conn->client_entry->encf_flag = 0 */ ; /* FIXME */
3064 }
3065 }
3066 }
3067 }
3068 else if ((conn->client_entry->encf_flag != 0) &&
3069 ((conn->head[0] & SH_MASK_ENC) !=
3070 conn->client_entry->encf_flag))
3071 {
3072 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3073 MSG_TCP_MISENC,
3074 _("file download"),
3075#ifdef SH_ENCRYPT_2
3076 _("version2"),
3077#else
3078 _("version1"),
3079#endif
3080 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1")
3081 );
3082 conn->client_entry->encf_flag =
3083 (conn->head[0] & SH_MASK_ENC);
3084 }
3085#else
3086 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3087 {
3088 sh_error_handle((-1), FIL__, __LINE__, 0,
3089 MSG_TCP_MISENC,
3090 _("file download"),
3091 _("none"),
3092 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3093 }
3094#endif
3095
3096
3097 /* ---- K = H(NSRV, NCLT, session_key) -------
3098 */
3099
3100 if (conn->FileName != NULL)
3101 {
3102 SH_FREE(conn->FileName);
3103 conn->FileName = NULL;
3104 }
3105
3106 if (0 == sl_strncmp (_("CONF"), &(conn->buf[KEY_LEN]), 4))
3107 {
3108 strcpy(conn->FileType, _("CONF")); /* known to fit */
3109 conn->FileName = get_client_conf_file(conn->peer,
3110 &(conn->FileLength));
3111 conn->FileSent = 0;
3112 }
3113 else if (0 == sl_strncmp (_("DATA"), &(conn->buf[KEY_LEN]), 4))
3114 {
3115 strcpy(conn->FileType, _("DATA")); /* known to fit */
3116 conn->FileName = get_client_data_file(conn->peer,
3117 &(conn->FileLength));
3118 conn->FileSent = 0;
3119 }
3120 else
3121 {
3122 ptok = sh_util_safe_name(&(conn->buf[KEY_LEN]));
3123 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FFILE,
3124 conn->peer,
3125 ptok);
3126 SH_FREE(ptok);
3127 status_update (conn->client_entry, CLT_FAILED);
3128 sh_forward_do_free (conn);
3129 }
3130
3131 bytes = -1;
3132
3133 if (conn != NULL && conn->FileName != NULL)
3134 {
3135 sfd = sl_open_read(FIL__, __LINE__,
3136 conn->FileName, SL_YESPRIV);
3137 if (!SL_ISERROR(sfd))
3138 {
3139 read_buf = SH_ALLOC(TRANS_BYTES);
3140 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3141 sl_close(sfd);
3142 }
3143
3144 else
3145 {
3146 sh_error_handle((-1), FIL__, __LINE__, sfd,
3147 MSG_E_ACCESS,
3148 (long) geteuid(),
3149 conn->FileName);
3150 }
3151 if (bytes >= 0)
3152 {
3153#ifdef SH_ENCRYPT
3154 /* need to send N * B_SIZ bytes
3155 */
3156 blkfac = bytes / B_SIZ;
3157 rem = bytes - (blkfac * B_SIZ);
3158 if (rem != 0)
3159 {
3160 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3161 ++blkfac;
3162 send_bytes = blkfac * B_SIZ;
3163 }
3164 else
3165 send_bytes = bytes;
3166
3167 send_buf = hash_me(conn->K, read_buf,
3168 send_bytes);
3169
3170 sh_forward_prep_send_crypt (conn, send_buf,
3171 send_bytes+KEY_LEN,
3172 _("FILE"),
3173 SH_PROTO_BIG|conn->client_entry->encf_flag);
3174#else
3175 send_buf = hash_me(conn->K, read_buf, bytes);
3176 sh_forward_prep_send_crypt (conn, send_buf,
3177 bytes+KEY_LEN,
3178 _("FILE"), SH_PROTO_BIG);
3179#endif
3180 conn->FileSent += bytes;
3181 if (send_buf != NULL)
3182 {
3183 SH_FREE(send_buf);
3184 }
3185 SH_FREE(read_buf);
3186 }
3187 }
3188
3189 if (conn == NULL || conn->FileName == NULL ||
3190 SL_ISERROR(sfd) || bytes < 0)
3191 {
3192 sh_error_handle((-1), FIL__, __LINE__, sfd, MSG_TCP_NFILE,
3193 conn->peer,
3194 (conn->FileName == NULL) ?
3195 _("(NULL)") : conn->FileName);
3196 status_update (conn->client_entry, CLT_FAILED);
3197 sh_forward_do_free (conn);
3198 }
3199
3200 }
3201
3202 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3203 _("RECV")) &&
3204 conn->client_entry != NULL &&
3205 conn->K != NULL &&
3206 conn->FileName != NULL)
3207 {
3208
3209 TPT(( 0, FIL__, __LINE__,
3210 _("msg=<File transfer - RCVT (5+).>\n")));
3211
3212 if (conn->FileSent == conn->FileLength)
3213 {
3214 send_buf = hash_me(conn->K, conn->peer,
3215 sl_strlen(conn->peer));
3216#ifdef SH_ENCRYPT
3217 sh_forward_prep_send_crypt (conn, send_buf,
3218 sl_strlen(conn->peer)+KEY_LEN,
3219 _("EEOT"),
3220 SH_PROTO_BIG|conn->client_entry->encf_flag);
3221#else
3222 sh_forward_prep_send_crypt (conn, send_buf,
3223 sl_strlen(conn->peer)+KEY_LEN,
3224 _("EEOT"),
3225 SH_PROTO_BIG);
3226#endif
3227 SH_FREE(send_buf);
3228 }
3229 else
3230 {
3231 bytes = -1;
3232 sfd = sl_open_read(FIL__, __LINE__,
3233 conn->FileName, SL_YESPRIV);
3234 if (!SL_ISERROR(sfd))
3235 {
3236 read_buf = SH_ALLOC(TRANS_BYTES);
3237 sl_seek (sfd, (off_t) conn->FileSent);
3238 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3239 sl_close(sfd);
3240 }
3241 else
3242 {
3243 sh_error_handle((-1), FIL__, __LINE__, sfd,
3244 MSG_E_ACCESS,
3245 (long) geteuid(),
3246 conn->FileName);
3247 }
3248 if (bytes >= 0)
3249 {
3250#ifdef SH_ENCRYPT
3251 /* need to send N * B_SIZ bytes
3252 */
3253 blkfac = bytes / B_SIZ;
3254 rem = bytes - (blkfac * B_SIZ);
3255 if (rem != 0)
3256 {
3257 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3258 ++blkfac;
3259 send_bytes = blkfac * B_SIZ;
3260 }
3261 else
3262 send_bytes = bytes;
3263
3264 send_buf = hash_me(conn->K, read_buf,
3265 send_bytes);
3266
3267 sh_forward_prep_send_crypt (conn, send_buf,
3268 send_bytes+KEY_LEN,
3269 _("FILE"),
3270 SH_PROTO_BIG|conn->client_entry->encf_flag);
3271#else
3272
3273 send_buf = hash_me(conn->K, read_buf, bytes);
3274 sh_forward_prep_send_crypt (conn, send_buf,
3275 bytes+KEY_LEN,
3276 _("FILE"),
3277 SH_PROTO_BIG);
3278#endif
3279
3280 conn->FileSent += bytes;
3281 SH_FREE(send_buf);
3282 SH_FREE(read_buf);
3283 }
3284 else
3285 {
3286 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NFILE,
3287 conn->peer,
3288 (conn->FileName == NULL) ?
3289 _("(NULL)") : conn->FileName);
3290 status_update (conn->client_entry, CLT_FAILED);
3291 sh_forward_do_free (conn);
3292 }
3293 }
3294 }
3295
3296
3297 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3298 _("EOTE")) &&
3299 conn->client_entry != NULL)
3300 {
3301
3302 TPT(( 0, FIL__, __LINE__,
3303 _("msg=<File transfer - EOTE (7).>\n")));
3304
3305 if (flag_err_info == SL_TRUE)
3306 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKFILE,
3307 conn->peer);
3308
3309 if ((conn->client_entry->status_now != CLT_SUSPEND) &&
3310 (conn->client_entry->status_now != CLT_TOOLONG))
3311 { status_update (conn->client_entry, CLT_FILE); }
3312 else
3313 { conn->client_entry->session_key[0] = '\0'; }
3314 conn->client_entry->last_connect = time (NULL);
3315 sh_forward_do_free (conn);
3316 }
3317
3318
3319 /* client does something unexpected
3320 */
3321 else /* ---- ??? ----- */
3322 {
3323 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3324 1, conn->pass, conn->peer,
3325 '\\', conn->head[3], '\\',conn->head[4],
3326 '\\', conn->head[5], '\\',conn->head[6]);
3327 status_update (conn->client_entry, CLT_FAILED);
3328 sh_forward_do_free (conn);
3329 }
3330 }
3331
3332 else if (state == SH_DO_WRITE) /* finished writing */
3333 {
3334 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - (wait).>\n")));
3335
3336 /* challenge is sent, now wait for message from client
3337 */
3338 conn->headcount = 0;
3339 conn->bytecount = 0;
3340 conn->bytes_to_send = 0;
3341 conn->bytes_to_get = 0;
3342 if (conn->buf != NULL)
3343 {
3344 SH_FREE(conn->buf);
3345 conn->buf = NULL;
3346 }
3347 conn->state = CONN_READING;
3348 }
3349 SL_RET0(_("check_protocol"));
3350 }
3351
3352 /* --------- message exchange -----------
3353 */
3354 if ((conn->head[0] & SH_PROTO_SRP) == 0 &&
3355 (conn->head[0] & SH_PROTO_MSG) != 0 /* is set */ )
3356 {
3357
3358 if (state == SH_DO_READ) /* finished reading */
3359 {
3360
3361 TPT(( 0, FIL__, __LINE__, _("msg=<Message transfer - entry.>\n")));
3362
3363 /* client requests challenge
3364 */
3365 if (0 == check_request_nerr ((char *)&(conn->head[3]), _("HELO")))
3366 {
3367
3368 TPT(( 0, FIL__, __LINE__,
3369 _("msg=<Message transfer - HELO (1).>\n")));
3370
3371 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN )
3372 {
3373 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3374 sh_forward_do_free (conn);
3375 SL_RET0(_("check_protocol"));
3376 }
3377
3378 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3379
3380 /* ---- search the register -----
3381 */
3382 this_client = search_register (conn, KEY_LEN);
3383 if (NULL == this_client)
3384 SL_RET0(_("check_protocol"));
3385
3386 /* ---- force authentication -----
3387 */
3388 if ( (this_client->session_key[0] == '\0') ||
3389 ((time(NULL)-this_client->session_key_timer)
3390 > (time_t) TIMEOUT_KEY)
3391 )
3392 {
3393
3394 /* fake an auth request and jump there
3395 */
3396 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
3397 conn->head[3] = 'S';
3398 conn->head[4] = 'A';
3399 conn->head[5] = 'L';
3400 conn->head[6] = 'T';
3401 if (flag_err_info == SL_TRUE)
3402 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
3403 &(conn->buf[KEY_LEN]));
3404 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
3405 /* &(conn->buf[KEY_LEN]) is hostname */
3406 /* may overlap, thus only memmove is correct */
3407 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
3408 this_client->session_key[0] = '\0';
3409 this_client->session_key_timer = (time_t) 1;
3410
3411 goto servInit;
3412 }
3413
3414 /* check whether hostname is properly signed
3415 */
3416 if (conn->K != NULL)
3417 {
3418 SH_FREE(conn->K);
3419 conn->K = NULL;
3420 }
3421 /* FIXME len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1; */
3422 conn->K = SH_ALLOC(KEY_LEN + 1);
3423
3424 sl_strlcpy (conn->K,
3425 sh_util_siggen(this_client->session_key,
3426 &(conn->buf[KEY_LEN]),
3427 sl_strlen(&(conn->buf[KEY_LEN])),
3428 sigbuf, sizeof(sigbuf)),
3429 KEY_LEN+1);
3430 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
3431 &(conn->buf[KEY_LEN])));
3432 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
3433 this_client->session_key));
3434 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), conn->K));
3435
3436 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
3437 {
3438 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s>\n"), conn->buf));
3439 TPT(( 0, FIL__, __LINE__, _("msg=<Want %s>\n"), conn->K));
3440 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3441 _("Signature mismatch"),
3442 &(conn->buf[KEY_LEN]));
3443
3444 this_client->session_key_timer =
3445 time(NULL) - (2*TIMEOUT_KEY);
3446
3447 sh_forward_do_free (conn);
3448 SL_RET0(_("check_protocol"));
3449 }
3450 SH_FREE(conn->K);
3451 conn->K = NULL;
3452
3453 /* -- create a nonce and send it --
3454 */
3455
3456 conn->client_entry = this_client;
3457 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
3458
3459 ticks = (UINT32) taus_get ();
3460
3461 test = (char *) &ticks;
3462 sh_util_cpylong (conn->challenge, test, 4);
3463 conn->challenge[4] = '\0';
3464 for (i = 0; i < 4; ++i)
3465 if (conn->challenge[i] == '\0')
3466 conn->challenge[i] = 0x01;
3467
3468 sh_forward_prep_send (conn, conn->challenge, 5, _("TALK"),
3469 SH_PROTO_MSG);
3470 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s.>\n"),
3471 hu_trans(conn->challenge)));
3472 }
3473
3474 /* Client has send a message. Check whether we are in proper
3475 * state, and verify message.
3476 */
3477 else if (0 ==
3478 check_request_nerr((char *)&(conn->head[3]), _("MESG")) &&
3479 conn->client_entry != NULL &&
3480 conn->client_entry->session_key[0] != '\0' &&
3481 (len = sl_strlen(conn->buf) - KEY_LEN) > 0 &&
3482 sl_strlen(conn->challenge) == 4)
3483 {
3484 TPT(( 0, FIL__, __LINE__,
3485 _("msg=<Message transfer - MESG (3).>\n")));
3486
3487#ifdef SH_ENCRYPT
3488 if (conn->client_entry->encf_flag == 0) {
3489 conn->client_entry->ency_flag = 0;
3490 }
3491 if ((conn->client_entry->ency_flag != 0) &&
3492 ((conn->head[0] & SH_PROTO_ENC) == 0))
3493 {
3494 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3495 _("message transfer"),
3496#ifdef SH_ENCRYPT_2
3497 _("version2"),
3498#else
3499 _("version1"),
3500#endif
3501 _("none"));
3502 /* conn->client_entry->ency_flag = 0; */
3503 }
3504 else if ((conn->client_entry->ency_flag != 0) &&
3505 ((conn->head[0] & SH_MASK_ENC) !=
3506 conn->client_entry->ency_flag))
3507 {
3508 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3509 MSG_TCP_MISENC,
3510 _("message transfer"),
3511#ifdef SH_ENCRYPT_2
3512 _("version2"),
3513#else
3514 _("version1"),
3515#endif
3516 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3517 conn->client_entry->ency_flag =
3518 (conn->head[0] & SH_MASK_ENC);
3519 }
3520#else
3521 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3522 {
3523 sh_error_handle((-1), FIL__, __LINE__, 0,
3524 MSG_TCP_MISENC,
3525 _("message transfer"),
3526 _("none"),
3527 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3528 }
3529#endif
3530
3531 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3532 /* get hash from message end, truncate message
3533 */
3534 sl_strlcpy(hash, &(conn->buf[len]), KEY_LEN+1);
3535 conn->buf[len] = '\0';
3536
3537 /* verify hash
3538 */
3539 buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL);
3540 i = sl_strncmp(hash,
3541 sh_util_siggen(conn->client_entry->session_key,
3542 buffer,
3543 sl_strlen(buffer),
3544 sigbuf, sizeof(sigbuf)),
3545 KEY_LEN);
3546 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3547 sh_util_siggen(conn->client_entry->session_key,
3548 buffer,
3549 sl_strlen(buffer),
3550 sigbuf, sizeof(sigbuf))));
3551
3552
3553 if (0 != i)
3554 {
3555 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3556 status_update (conn->client_entry, CLT_FAILED);
3557 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3558 _("Msg signature mismatch"), conn->peer);
3559 conn->client_entry->session_key_timer =
3560 time(NULL) - (2*TIMEOUT_KEY);
3561 sh_forward_do_free (conn);
3562 SL_RET0(_("check_protocol"));
3563 }
3564 else
3565 {
3566 conn->client_entry->last_connect = time (NULL);
3567
3568 if (NULL != sl_strstr(conn->buf, _("EXIT")))
3569 {
3570 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3571 conn->client_entry->exit_flag = 1;
3572 status_update (conn->client_entry, CLT_EXITED);
3573 }
3574 else if (NULL != sl_strstr(conn->buf, _("PANIC")))
3575 {
3576 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3577 status_update (conn->client_entry, CLT_PANIC);
3578 }
3579 else if (NULL != sl_strstr(conn->buf, _("SUSPEND")))
3580 {
3581 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3582 status_update (conn->client_entry, CLT_SUSPEND);
3583 }
3584 else if (NULL != sl_strstr(conn->buf, _("POLICY")))
3585 {
3586 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3587 status_update (conn->client_entry, CLT_POLICY);
3588 }
3589 else if (NULL != sl_strstr(conn->buf,
3590 _("File check completed")))
3591 {
3592 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3593 status_update (conn->client_entry, CLT_CHECK);
3594 }
3595 else if (NULL != sl_strstr(conn->buf, _("START")))
3596 {
3597 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3598 sh_socket_add2reload (conn->client_entry->hostname);
3599 if (conn->client_entry->status_now == CLT_SUSPEND) {
3600 status_update (conn->client_entry, CLT_ILLEGAL);
3601 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3602 conn->peer);
3603 }
3604 else
3605 status_update (conn->client_entry, CLT_STARTED);
3606 }
3607 else
3608 {
3609 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3610 if (0 != sl_strcmp(conn->buf,
3611 _("Runtime configuration reloaded")))
3612 {
3613 sh_socket_add2reload (conn->client_entry->hostname);
3614 }
3615 status_update (conn->client_entry, CLT_MSG);
3616 }
3617
3618 TPT((0, FIL__, __LINE__, _("msg=<status updated>\n")));
3619 clt_sev = atoi(conn->buf);
3620 clt_class = (-1);
3621 ptok = strchr(conn->buf, '?');
3622 if (ptok != NULL)
3623 {
3624 ++ptok;
3625 if (ptok != NULL && sh.flag.client_class == S_TRUE)
3626 clt_class = atoi(ptok); /* is a global */
3627 ptok = strchr(ptok, '?');
3628 if (ptok != NULL)
3629 ++ptok;
3630 }
3631 if (sh.flag.client_severity == S_FALSE)
3632 clt_sev = (-1);
3633
3634 /* here we expect an xml formatted message, thus we don't
3635 escape xml special chars (flag == 0) */
3636 ptok =
3637 sh_tools_safe_name ((ptok!=NULL) ? ptok : conn->buf, 0);
3638
3639 /* push client name to error routine
3640 */
3641 sh_error_set_peer(sh_strip_domain (conn->peer));
3642 sh_error_handle(clt_sev, FIL__, __LINE__, 0, MSG_TCP_MSG,
3643 sh_strip_domain (conn->peer),
3644 ptok);
3645 sh_error_set_peer(NULL);
3646
3647 TPT((0, FIL__, __LINE__, _("msg=<%s>\n"), ptok));
3648 SH_FREE(ptok);
3649 clt_class = (-1);
3650 }
3651 memset(buffer, '\0', sl_strlen(buffer));
3652 SH_FREE(buffer);
3653
3654 /* SERVER CONF SEND
3655 */
3656 buffer = sh_util_strconcat(conn->buf,
3657 conn->challenge,
3658 NULL);
3659 sl_strlcpy(hash,
3660 sh_util_siggen ( conn->client_entry->session_key,
3661 buffer,
3662 sl_strlen(buffer),
3663 sigbuf, sizeof(sigbuf)),
3664 KEY_LEN+1);
3665
3666 /* --- SERVER CMD --- */
3667 cmd = sh_socket_check (conn->peer);
3668
3669 if (cmd != NULL)
3670 {
3671 /* max cmd size is SH_MAXMSGLEN bytes
3672 */
3673 sl_strlcpy(&hash[KEY_LEN], cmd, SH_MAXMSGLEN);
3674 sl_strlcat(&hash[KEY_LEN],
3675 sh_util_siggen ( conn->client_entry->session_key,
3676 &hash[KEY_LEN],
3677 sl_strlen(&hash[KEY_LEN]),
3678 sigbuf, sizeof(sigbuf)),
3679 SH_MAXMSGLEN+KEY_LEN+1);
3680
3681 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <%s>\n"),
3682 &hash[KEY_LEN]));
3683
3684 } else {
3685
3686 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <[NULL]>\n")));
3687
3688 }
3689 /* --- SERVER CMD END --- */
3690
3691 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3692 sh_util_siggen(conn->client_entry->session_key,
3693 buffer,
3694 sl_strlen(buffer),
3695 sigbuf, sizeof(sigbuf))));
3696
3697#ifdef SH_ENCRYPT
3698 sh_forward_prep_send_crypt (conn, hash,
3699 sl_strlen(hash) /* KEY_LEN */,
3700 _("CONF"),
3701 SH_PROTO_MSG|SH_PROTO_END|conn->client_entry->ency_flag);
3702#else
3703 sh_forward_prep_send_crypt (conn, hash,
3704 sl_strlen(hash) /* KEY_LEN */,
3705 _("CONF"),
3706 SH_PROTO_MSG|SH_PROTO_END);
3707#endif
3708
3709 memset(buffer, '\0', sl_strlen(buffer));
3710 SH_FREE(buffer);
3711
3712 /* sh_forward_do_free (conn); */
3713 }
3714
3715 /* client does something unexpected
3716 */
3717 else /* ---- ??? ----- */
3718 {
3719 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3720 2, conn->pass, conn->peer,
3721 '\\', conn->head[3], '\\',conn->head[4],
3722 '\\', conn->head[5], '\\',conn->head[6]);
3723 status_update (conn->client_entry, CLT_FAILED);
3724 conn->client_entry->session_key_timer =
3725 time(NULL) - (2*TIMEOUT_KEY);
3726 sh_forward_do_free (conn);
3727 }
3728 }
3729 else if (state == SH_DO_WRITE) /* finished writing */
3730 {
3731 if (0 != (conn->head[0] & SH_PROTO_END))
3732 {
3733 if (flag_err_debug == SL_TRUE)
3734 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKMSG,
3735 sh_strip_domain (conn->peer));
3736 sh_forward_do_free (conn);
3737 SL_RET0(_("check_protocol"));
3738 }
3739
3740 TPT(( 0, FIL__, __LINE__, _("msg=<Msg transfer - (wait).>\n")));
3741
3742 /* challenge is sent, now wait for message from client
3743 */
3744 conn->headcount = 0;
3745 conn->bytecount = 0;
3746 conn->bytes_to_send = 0;
3747 conn->bytes_to_get = 0;
3748 if (conn->buf != NULL)
3749 {
3750 SH_FREE(conn->buf);
3751 conn->buf = NULL;
3752 }
3753 conn->state = CONN_READING;
3754 }
3755 TPT((0, FIL__, __LINE__, _("msg=<return>\n") ));
3756 SL_RET0(_("check_protocol"));
3757 }
3758
3759 /* --------- authentication -----------
3760 */
3761
3762 /* entry point for jump from message forward if session key must
3763 * be re-initialized
3764 */
3765 servInit:
3766
3767 if ( (conn->head[0] & SH_PROTO_SRP) != 0 /* is set */ )
3768 {
3769
3770#ifndef USE_SRP_PROTOCOL
3771
3772 if (state == SH_DO_READ) /* finished reading */
3773 {
3774 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3775
3776 /* first pass -- client request salt
3777 */
3778 if (conn->pass == 1)
3779 {
3780
3781 TPT((0, FIL__, __LINE__,
3782 _("msg=<Authentication - SALT (1).>\n")));
3783
3784 if (conn->buf == NULL || sl_strlen(conn->buf) == 0)
3785 {
3786 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3787 sh_forward_do_free (conn);
3788 SL_RET0(_("check_protocol"));
3789 }
3790
3791
3792 /* search the register
3793 */
3794
3795 this_client = search_register (conn, 0);
3796 if (NULL == this_client)
3797 SL_RET0(_("check_protocol"));
3798
3799
3800 conn->client_entry = this_client;
3801 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3802
3803 if (0 != check_request_s((char *)&(conn->head[3]),
3804 _("SALT"),conn->peer))
3805 {
3806 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3807 _("No salt requested"), conn->peer);
3808 status_update (conn->client_entry, CLT_FAILED);
3809 conn->client_entry->session_key_timer =
3810 time(NULL) - (2*TIMEOUT_KEY);
3811 sh_forward_do_free (conn);
3812 SL_RET0(_("check_protocol"));
3813 }
3814
3815
3816 /* -- create server nounce v --
3817 */
3818 ticks = (UINT32) taus_get ();
3819
3820 if (conn->A != NULL)
3821 {
3822 SH_FREE(conn->A);
3823 conn->A = NULL;
3824 }
3825 conn->A = SH_ALLOC(KEY_LEN+1);
3826
3827 sl_strlcpy(conn->A,
3828 sh_tiger_hash((char *) &ticks,
3829 TIGER_DATA, sizeof(UINT32),
3830 hashbuf, sizeof(hashbuf)),
3831 KEY_LEN+1);
3832 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3833
3834 if (conn->M1 != NULL)
3835 {
3836 SH_FREE(conn->M1);
3837 conn->M1 = NULL;
3838 }
3839 conn->M1 = SH_ALLOC(2*KEY_LEN+1);
3840
3841 /* compute hash key H(v(server), P)v(server)
3842 */
3843 sh_passwd (conn->A, conn->client_entry->verifier,
3844 NULL, conn->M1);
3845
3846 sl_strlcat(conn->M1, conn->A, 2*KEY_LEN+1);
3847
3848
3849 /* --- send H(v(server), P)v(server) ----
3850 */
3851 sh_forward_prep_send (conn,
3852 conn->M1,
3853 sl_strlen(conn->M1),
3854 u,
3855 (conn->head[0]|SH_PROTO_SRP));
3856
3857 SH_FREE(conn->M1);
3858 conn->M1 = NULL;
3859 }
3860
3861 /* client -- third pass
3862 * Message is H(H(u,v),P)u
3863 *
3864 * A := v, verifier := H(password),
3865 */
3866 else if (conn->pass == 3 &&
3867 conn->client_entry != NULL)
3868 {
3869
3870 TPT((0, FIL__, __LINE__,
3871 _("msg=<Authentication - PASS (3).>\n")));
3872
3873 if (0 != check_request_s((char *) &(conn->head[3]), _("PASS"),
3874 conn->peer) ||
3875 sl_strlen(conn->buf) <= KEY_LEN ||
3876 conn->A == NULL)
3877 {
3878 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3879 _("Invalid client request"), conn->peer);
3880 status_update (conn->client_entry, CLT_FAILED);
3881 conn->client_entry->session_key_timer =
3882 time(NULL) - (2*TIMEOUT_KEY);
3883 sh_forward_do_free (conn);
3884 SL_RET0(_("check_protocol"));
3885 }
3886
3887 /* store random nonce u from client
3888 */
3889 if (conn->K != NULL)
3890 {
3891 SH_FREE(conn->K);
3892 conn->K = NULL;
3893 }
3894 conn->K = SH_ALLOC(KEY_LEN+1);
3895 sl_strlcpy(conn->K, &(conn->buf[KEY_LEN]), KEY_LEN+1);
3896
3897 /* verify random nonce u from client
3898 */
3899 if (conn->M1 != NULL)
3900 {
3901 SH_FREE(conn->M1);
3902 conn->M1 = NULL;
3903 }
3904 conn->M1 = sh_util_strconcat(conn->K, conn->A, NULL);
3905
3906 TPT((0, FIL__, __LINE__, _("msg=<c/r: K = %s>\n"), conn->K));
3907 TPT((0, FIL__, __LINE__, _("msg=<c/r: A = %s>\n"), conn->A));
3908 TPT((0, FIL__, __LINE__, _("msg=<c/r: M = %s>\n"), conn->M1));
3909
3910 sl_strlcpy(hash, sh_tiger_hash (conn->M1,
3911 TIGER_DATA,
3912 sl_strlen(conn->M1),
3913 hashbuf, sizeof(hashbuf)),
3914 KEY_LEN+1);
3915 sh_passwd (hash, conn->client_entry->verifier, NULL, conn->M1);
3916
3917 TPT((0, FIL__, __LINE__, _("msg=<c/r: H = %s>\n"), hash));
3918 TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1));
3919
3920 if ( 0 != sl_strncmp(conn->M1, conn->buf, KEY_LEN))
3921 {
3922 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3923 _("Session key mismatch"), conn->peer);
3924 status_update (conn->client_entry, CLT_FAILED);
3925 conn->client_entry->session_key_timer =
3926 time(NULL) - (2*TIMEOUT_KEY);
3927 sh_forward_do_free (conn);
3928 SL_RET0(_("check_protocol"));
3929 }
3930
3931
3932 /* ---- compute hash key H(v, P, u) ----
3933 */
3934
3935 sh_passwd (conn->A, conn->client_entry->verifier, conn->K,
3936 conn->M1);
3937
3938 sl_strlcpy(conn->client_entry->session_key,
3939 conn->M1, KEY_LEN+1);
3940 TPT((0, FIL__, __LINE__, _("msg=<c/r: Key = %s>\n"),
3941 conn->client_entry->session_key));
3942
3943#ifdef SH_ENCRYPT
3944 err_num = makeKey(&(conn->client_entry->keyInstE),
3945 DIR_ENCRYPT, 192,
3946 conn->client_entry->session_key);
3947 if (err_num < 0)
3948 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3949 errorExplain(err_num, expbuf, sizeof(expbuf)),
3950 _("check_protocol: makeKey"));
3951 err_num = makeKey(&(conn->client_entry->keyInstD),
3952 DIR_DECRYPT, 192,
3953 conn->client_entry->session_key);
3954 if (err_num < 0)
3955 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
3956 errorExplain(err_num, expbuf, sizeof(expbuf)),
3957 _("check_protocol: makeKey"));
3958#endif
3959
3960 if (conn->K != NULL) SH_FREE (conn->K);
3961 conn->K = NULL;
3962 if (conn->A != NULL) SH_FREE (conn->A);
3963 conn->A = NULL;
3964 if (conn->M1 != NULL) SH_FREE (conn->M1);
3965 conn->M1 = NULL;
3966
3967 /* if (conn->client_entry->status_now == CLT_STARTED */
3968 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
3969 (conn->client_entry->status_now != CLT_EXITED) &&
3970 (conn->client_entry->status_now != CLT_SUSPEND))
3971 && conn->client_entry->session_key_timer > (time_t) 1)
3972 {
3973 status_update (conn->client_entry, CLT_ILLEGAL);
3974 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3975 conn->peer);
3976 }
3977 else if (conn->client_entry->session_key_timer == (time_t) 0)
3978 {
3979 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NEW,
3980 conn->peer);
3981 if (conn->client_entry->status_now != CLT_SUSPEND)
3982 status_update (conn->client_entry, CLT_STARTED);
3983 }
3984
3985 conn->client_entry->session_key_timer = time (NULL);
3986 conn->client_entry->last_connect = time (NULL);
3987
3988 /* put in read state
3989 */
3990 sh_forward_prep_send (conn,
3991 _("AUTH"),
3992 5,
3993 _("AUTH"),
3994 (conn->head[0]|SH_PROTO_SRP));
3995
3996 }
3997 else
3998 {
3999 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
4000 3, conn->pass, conn->peer,
4001 '\\', conn->head[3], '\\', conn->head[4],
4002 '\\', conn->head[5], '\\', conn->head[6]);
4003 sh_forward_do_free (conn);
4004 }
4005 }
4006
4007#else
4008 /* use SRP */
4009
4010
4011 if (state == SH_DO_READ) /* finished reading */
4012 {
4013
4014 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
4015
4016 /* first pass -- client request salt
4017 */
4018 if (conn->pass == 1)
4019 {
4020 TPT((0, FIL__, __LINE__,
4021 _("msg=<Authentication - SALT (1).>\n")));
4022
4023 if (conn->buf == NULL)
4024 {
4025 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
4026 sh_forward_do_free (conn);
4027 SL_RET0(_("check_protocol"));
4028 }
4029
4030 /* search the register
4031 */
4032 this_client = search_register(conn, 0);
4033 if (NULL == this_client)
4034 SL_RET0(_("check_protocol"));
4035
4036 conn->client_entry = this_client;
4037 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
4038
4039 if (0 != check_request_s((char *)&(conn->head[3]), _("SALT"),
4040 conn->peer))
4041 {
4042 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4043 _("No salt requested"), conn->peer);
4044 status_update (conn->client_entry, CLT_FAILED);
4045 conn->client_entry->session_key_timer =
4046 time(NULL) - (2*TIMEOUT_KEY);
4047 sh_forward_do_free (conn);
4048 SL_RET0(_("check_protocol"));
4049 }
4050
4051
4052 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
4053
4054 sh_forward_prep_send (conn,
4055 conn->client_entry->salt,
4056 sl_strlen(conn->client_entry->salt),
4057 u,
4058 (conn->head[0]|SH_PROTO_SRP));
4059 }
4060
4061 /* client has sent A -- third pass
4062 */
4063 else if (conn->pass == 3 &&
4064 conn->client_entry != NULL)
4065 {
4066
4067 TPT((0, FIL__, __LINE__,
4068 _("msg=<Authentication - PC01 (3).>\n")));
4069
4070 if (0 != check_request_s((char *)&(conn->head[3]),_("PC01"),conn->peer)||
4071 conn->buf == NULL
4072 )
4073 {
4074 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4075 _("Invalid client request"), conn->peer);
4076 status_update (conn->client_entry, CLT_FAILED);
4077 conn->client_entry->session_key_timer =
4078 time(NULL) - (2*TIMEOUT_KEY);
4079 sh_forward_do_free (conn);
4080 SL_RET0(_("check_protocol"));
4081 }
4082
4083 if (0 != sh_srp_init())
4084 {
4085 status_update (conn->client_entry, CLT_FAILED);
4086 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4087 MSG_TCP_EBGN);
4088 sh_forward_do_free (conn);
4089 SL_RET0(_("check_protocol"));
4090 }
4091
4092
4093 /* check A, only send B if correct
4094 */
4095 if ( sl_strlen(conn->buf) < SH_BUFSIZE &&
4096 0 == sh_srp_check_zero (conn->buf) )
4097 {
4098 len = sl_strlen(conn->buf)+1;
4099
4100 if (conn->A != NULL)
4101 {
4102 SH_FREE(conn->A);
4103 conn->A = NULL;
4104 }
4105 conn->A = SH_ALLOC(len);
4106 sl_strlcpy (conn->A, conn->buf, len);
4107
4108 /*
4109 * compute B
4110 */
4111 if (0 != sh_srp_make_a ()) /* b random number */
4112 {
4113 status_update (conn->client_entry, CLT_FAILED);
4114
4115 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4116 MSG_TCP_EBGN);
4117 sh_srp_exit();
4118 sh_forward_do_free (conn);
4119 SL_RET0(_("check_protocol"));
4120 }
4121
4122 foo_B = sh_srp_B /* B = v + g^b */
4123 (conn->client_entry->verifier);
4124
4125 if (foo_B == NULL)
4126 {
4127 status_update (conn->client_entry, CLT_FAILED);
4128
4129 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4130 MSG_TCP_EBGN);
4131 sh_srp_exit();
4132 sh_forward_do_free (conn);
4133 SL_RET0(_("check_protocol"));
4134 }
4135
4136 TPT((0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), conn->A));
4137 TPT((0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), foo_B));
4138
4139 /*
4140 * create nonce u
4141 */
4142 ticks = (UINT32) taus_get ();
4143
4144 test = (char *) &ticks;
4145 sh_util_cpylong (u, test, 4); /* u nounce */
4146 u[4] = '\0';
4147 sl_strlcpy(conn->challenge,
4148 sh_tiger_hash(u, TIGER_DATA, 4, hashbuf, sizeof(hashbuf)),
4149 SH_CHALLENGE_SIZE);
4150
4151 TPT((0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), u[0], u[1], u[2], u[3]));
4152 TPT((0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
4153 conn->challenge));
4154
4155 /*
4156 * compute the session key K and M1 = Hash(A,B,K)
4157 */
4158 foo_Ss = sh_srp_S_s (conn->challenge,
4159 conn->A,
4160 conn->client_entry->verifier);
4161
4162 if (foo_Ss == NULL || 0 != sh_srp_check_zero (foo_Ss))
4163 {
4164 status_update (conn->client_entry, CLT_FAILED);
4165
4166 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4167 MSG_TCP_EBGN);
4168 sh_srp_exit();
4169 sh_forward_do_free (conn);
4170 SL_RET0(_("check_protocol"));
4171 }
4172
4173 if (conn->K != NULL)
4174 {
4175 SH_FREE(conn->K);
4176 conn->K = NULL;
4177 }
4178 conn->K = SH_ALLOC(KEY_LEN+1);
4179 sl_strlcpy(conn->K,
4180 sh_tiger_hash(foo_Ss, TIGER_DATA,
4181 sl_strlen(foo_Ss),
4182 hashbuf, sizeof(hashbuf)),
4183 KEY_LEN+1);
4184
4185 if (conn->M1 != NULL)
4186 {
4187 SH_FREE(conn->M1);
4188 conn->M1 = NULL;
4189 }
4190 conn->M1 = SH_ALLOC(KEY_LEN+1);
4191 sh_srp_M (conn->A, foo_B, conn->K, conn->M1, KEY_LEN+1);
4192
4193 TPT((0, FIL__, __LINE__, _("msg=<srp:Ss = %s>\n"), foo_Ss));
4194 TPT((0, FIL__, __LINE__, _("msg=<srp: K = %s>\n"), conn->K));
4195 TPT((0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),conn->M1));
4196
4197 /*
4198 * send B
4199 */
4200 sh_forward_prep_send (conn,
4201 foo_B,
4202 sl_strlen(foo_B)+1,
4203 u,
4204 (conn->head[0]|SH_PROTO_SRP));
4205 if (foo_Ss != NULL)
4206 {
4207 SH_FREE(foo_Ss);
4208 foo_Ss = NULL;
4209 }
4210 if (foo_B != NULL)
4211 {
4212 SH_FREE(foo_B);
4213 foo_B = NULL;
4214 }
4215 }
4216 else
4217 {
4218 status_update (conn->client_entry, CLT_FAILED);
4219
4220 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4221 MSG_TCP_EZERO);
4222 sh_forward_do_free (conn);
4223 }
4224
4225 sh_srp_exit();
4226 }
4227
4228 /* client has sent M1 -- fifth pass
4229 */
4230 else if (conn->pass == 5 &&
4231 conn->client_entry != NULL)
4232 {
4233 TPT((0, FIL__, __LINE__,
4234 _("msg=<Authentication - PC02 (5).>\n")));
4235
4236 /* check that the state is valid
4237 */
4238 if (0 != check_request_s((char *)&(conn->head[3]), _("PC02"),
4239 conn->peer) ||
4240 conn->A == NULL || conn->K == NULL || conn->M1 == NULL)
4241 {
4242 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4243 _("Invalid client request"), conn->peer);
4244 status_update (conn->client_entry, CLT_FAILED);
4245 conn->client_entry->session_key_timer =
4246 time(NULL) - (2*TIMEOUT_KEY);
4247 sh_forward_do_free (conn);
4248 SL_RET0(_("check_protocol"));
4249 }
4250
4251 /* ------ verify M1 = H(A, B, K) -------
4252 * ----- send M2 = H(A, M1, K) -------
4253 */
4254 if (conn->buf != NULL &&
4255 sl_strncmp(conn->buf, conn->M1, KEY_LEN) == 0)
4256 {
4257 /*
4258 * send M2
4259 */
4260 char M_buf[KEY_LEN+1];
4261 sh_forward_prep_send (conn,
4262 sh_srp_M (conn->A, conn->M1, conn->K,
4263 M_buf, sizeof(M_buf)),
4264 KEY_LEN+1,
4265 _("PARP"),
4266 (conn->head[0]|SH_PROTO_SRP));
4267
4268 if (conn->A != NULL) SH_FREE(conn->A); conn->A = NULL;
4269 if (conn->M1 != NULL) SH_FREE(conn->M1); conn->M1 = NULL;
4270 sl_strlcpy(conn->client_entry->session_key,
4271 conn->K, KEY_LEN+1);
4272 TPT((0, FIL__, __LINE__, _("msg=<key %s>\n"),
4273 conn->client_entry->session_key));
4274
4275#ifdef SH_ENCRYPT
4276 err_num = makeKey(&(conn->client_entry->keyInstE),
4277 DIR_ENCRYPT, 192,
4278 conn->client_entry->session_key);
4279 if (err_num < 0)
4280 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4281 errorExplain(err_num, expbuf, sizeof(expbuf)),
4282 _("sh_forward_prep_send_int: makeKey"));
4283 err_num = makeKey(&(conn->client_entry->keyInstD),
4284 DIR_DECRYPT, 192,
4285 conn->client_entry->session_key);
4286 if (err_num < 0)
4287 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4288 errorExplain(err_num, expbuf, sizeof(expbuf)),
4289 _("sh_forward_prep_send_int: makeKey"));
4290#endif
4291
4292 if (conn->K != NULL) SH_FREE(conn->K); conn->K = NULL;
4293
4294 conn->client_entry->last_connect = time (NULL);
4295
4296 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
4297 (conn->client_entry->status_now != CLT_EXITED) &&
4298 (conn->client_entry->status_now != CLT_SUSPEND))
4299 && conn->client_entry->session_key_timer > (time_t) 1)
4300 {
4301 status_update (conn->client_entry, CLT_ILLEGAL);
4302
4303 sh_error_handle((-1), FIL__, __LINE__, 0,
4304 MSG_TCP_ILL,
4305 conn->peer);
4306 }
4307 else if (conn->client_entry->session_key_timer == (time_t) 0)
4308 {
4309 sh_error_handle((-1), FIL__, __LINE__, 0,
4310 MSG_TCP_NEW,
4311 conn->peer);
4312 if (conn->client_entry->status_now != CLT_SUSPEND)
4313 status_update (conn->client_entry, CLT_STARTED);
4314 }
4315 conn->client_entry->session_key_timer = time (NULL);
4316
4317 }
4318 else
4319 {
4320 status_update (conn->client_entry, CLT_FAILED);
4321 conn->client_entry->session_key_timer =
4322 time(NULL) - (2*TIMEOUT_KEY);
4323
4324 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4325 _("Session key mismatch"), conn->peer);
4326 sh_forward_do_free (conn);
4327 }
4328 }
4329
4330 else
4331 {
4332 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
4333 4, conn->pass, conn->peer,
4334 '\\', conn->head[3], '\\', conn->head[4],
4335 '\\', conn->head[5], '\\', conn->head[6]);
4336 sh_forward_do_free (conn);
4337 }
4338 }
4339
4340#endif
4341
4342 else if (state == SH_DO_WRITE) /* finished writing */
4343 {
4344 TPT((0, FIL__, __LINE__, _("msg=<Authentication -- (wait).>\n")));
4345
4346 conn->headcount = 0;
4347 conn->bytecount = 0;
4348 conn->bytes_to_send = 0;
4349 conn->bytes_to_get = 0;
4350 if (conn->buf != NULL)
4351 {
4352 SH_FREE(conn->buf);
4353 conn->buf = NULL;
4354 }
4355 conn->state = CONN_READING;
4356 }
4357 }
4358 SL_RET0(_("check_protocol"));
4359}
4360
4361
4362/***********************************************************
4363 *
4364 * SERVER RECEIVE FUNCTION
4365 *
4366 ***********************************************************
4367 */
4368int sh_forward_do_read (sh_conn_t * conn)
4369{
4370 unsigned long byteread; /* bytes read */
4371
4372#ifdef SH_ENCRYPT
4373
4374 unsigned long blkfac = 0;
4375 /* unsigned long length2; */
4376 char * p = NULL, * q = NULL;
4377 RIJ_BYTE inBlock[B_SIZ];
4378 RIJ_BYTE outBlock[B_SIZ];
4379 unsigned int j;
4380 cipherInstance cipherInst;
4381 int err_num;
4382 char expbuf[SH_ERRBUF_SIZE];
4383#endif
4384
4385 SL_ENTER(_("sh_forward_do_read"));
4386
4387 if (conn->state == CONN_SENDING)
4388 {
4389 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4390 conn->peer);
4391 SL_RETURN( (-1), _("sh_forward_do_read"));
4392 }
4393
4394 if (conn->headcount < SH_HEADER_SIZE)
4395 {
4396 conn->bytes_to_get = SH_HEADER_SIZE - conn->headcount;
4397 byteread = read (conn->fd, &(conn->head[conn->headcount]),
4398 conn->bytes_to_get);
4399 if (byteread > 0 || errno == EINTR)
4400 {
4401 if (byteread > 0)
4402 conn->headcount += byteread;
4403 if (conn->headcount == SH_HEADER_SIZE)
4404 {
4405 conn->bytes_to_get =
4406 (256 * (unsigned int)conn->head[1] +
4407 (unsigned int)conn->head[2]);
4408 SH_SHOWPROT(conn->head, '<');
4409 conn->bytecount = 0;
4410 }
4411 }
4412 else
4413 {
4414 goto conn_reset;
4415 }
4416 SL_RETURN( (0), _("sh_forward_do_read"));
4417 }
4418
4419
4420 /* limit message size
4421 */
4422 /*
4423 conn->bytes_to_get =
4424 (conn->bytes_to_get > (16*SH_BUFSIZE - 1)) ?
4425 (16*SH_BUFSIZE - 1) : conn->bytes_to_get;
4426 */
4427 conn->bytes_to_get = (conn->bytes_to_get > TRANS_BYTES) ?
4428 TRANS_BYTES : conn->bytes_to_get;
4429
4430 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get > 0)
4431 {
4432 if ((conn->bytecount > 0) && (conn->bytes_to_get > conn->bytecount))
4433 {
4434 /* do nothing */;
4435 }
4436 else
4437 {
4438 if (conn->buf != NULL)
4439 SH_FREE (conn->buf);
4440 conn->buf = SH_ALLOC(conn->bytes_to_get + 1); /* <= TRANS_BYTES+1 */
4441 conn->bytecount = 0;
4442 }
4443
4444 byteread = read (conn->fd, &(conn->buf[conn->bytecount]),
4445 conn->bytes_to_get - conn->bytecount);
4446 if (byteread > 0 || errno == EINTR)
4447 {
4448 if (byteread > 0)
4449 conn->bytecount += byteread;
4450 if (conn->bytecount == conn->bytes_to_get)
4451 {
4452 ++conn->pass;
4453 /* always terminate with NULL - we might use sl_strcmp()
4454 */
4455 conn->buf[conn->bytecount] = '\0';
4456 conn->state = CONN_PAUSE;
4457
4458#ifdef SH_ENCRYPT
4459 if ((conn->head[0] & SH_PROTO_EN2) != 0) /* if encrypted */
4460 {
4461 conn->buf =
4462 sh_tools_revertPack (conn->head, conn->buf,
4463 &(conn->client_entry->keyInstD),
4464 conn->bytecount);
4465 }
4466 else if ((conn->head[0] & SH_PROTO_ENC) != 0) /* if encrypted */
4467 {
4468 /* Decrypt only complete blocks.
4469 * If there is an incomplete block,
4470 * something is wrong anyway.
4471 * Decrypt in place.
4472 */
4473 blkfac = conn->bytecount / B_SIZ;
4474 /* length2 = (B_SIZ * blkfac); */
4475 p = conn->buf;
4476 q = conn->buf;
4477
4478 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
4479 if (err_num < 0)
4480 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
4481 errorExplain(err_num, expbuf, sizeof(expbuf)),
4482 _("sh_forward_do_read: cipherInit"));
4483
4484 for (j = 0; j < blkfac; ++j)
4485 {
4486 memcpy(inBlock, p, B_SIZ);
4487 err_num = blockDecrypt(&cipherInst,
4488 &(conn->client_entry->keyInstD),
4489 inBlock, 128 * BNUM, outBlock);
4490 if (err_num < 0)
4491 sh_error_handle((-1), FIL__, __LINE__, -1,
4492 MSG_E_SUBGEN,
4493 errorExplain(err_num, expbuf, sizeof(expbuf)),
4494 _("sh_forward_do_read: blockDecrypt"));
4495 memcpy(q, outBlock, B_SIZ);
4496 p += 16;
4497 q += 16;
4498 }
4499 }
4500#endif
4501
4502 /* ------ HERE CALL check_protocol(conn) ------- */
4503 check_protocol(conn, SH_DO_READ);
4504 }
4505 }
4506 else
4507 {
4508 goto conn_reset;
4509 }
4510 }
4511
4512 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get == 0)
4513 {
4514 if (conn->buf != NULL)
4515 SH_FREE (conn->buf);
4516 conn->buf = NULL;
4517 conn->bytecount = 0;
4518 ++conn->pass;
4519 conn->state = CONN_PAUSE;
4520 /* fprintf(stderr, "\n**** FIXME null read ****\n\n"); */
4521 /* ------ HERE CALL check_protocol(conn) ------- */
4522 check_protocol(conn, SH_DO_READ);
4523 }
4524
4525 SL_RETURN( (0), _("sh_forward_do_read"));
4526
4527 conn_reset:
4528 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4529 conn->peer);
4530 sh_forward_do_free ( conn );
4531 SL_RETURN( (-1), _("sh_forward_do_read"));
4532}
4533
4534#if !defined(O_NONBLOCK)
4535#if defined(O_NDELAY)
4536#define O_NONBLOCK O_NDELAY
4537#else
4538#define O_NONBLOCK 0
4539#endif
4540#endif
4541
4542/* send to the client
4543 */
4544int sh_forward_do_write (sh_conn_t * conn)
4545{
4546 int flags;
4547 long arg = 0;
4548 long bytesent; /* bytes read */
4549
4550 SL_ENTER(_("sh_forward_do_write"));
4551
4552 /* ---- consistency check ------
4553 */
4554 if (conn->state == CONN_READING)
4555 {
4556 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4557 conn->peer);
4558 SL_RETURN( (-1), _("sh_forward_do_write"));
4559 }
4560
4561
4562 flags = retry_fcntl (FIL__, __LINE__, conn->fd, F_GETFL, arg);
4563 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags|O_NONBLOCK);
4564
4565 /* ---- send the header ------
4566 */
4567 if (conn->headcount < SH_HEADER_SIZE)
4568 {
4569 conn->bytes_to_send = SH_HEADER_SIZE - conn->headcount;
4570 bytesent = write (conn->fd,
4571 &(conn->head[conn->headcount]),
4572 conn->bytes_to_send);
4573 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4574 {
4575 if (bytesent > 0)
4576 conn->headcount += bytesent;
4577 if (conn->headcount == SH_HEADER_SIZE)
4578 {
4579 conn->bytes_to_send =
4580 (256 * (int)conn->head[1] + (int)conn->head[2]);
4581 }
4582 }
4583 else
4584 {
4585 goto conn_reset_w;
4586 }
4587 if (conn->fd >= 0)
4588 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4589 SL_RETURN( (0), _("sh_forward_do_write"));
4590 }
4591
4592
4593 /* ---- send the body ------
4594 */
4595
4596 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send > 0 &&
4597 conn->buf != NULL)
4598 {
4599 bytesent = write (conn->fd, &(conn->buf[conn->bytecount]),
4600 conn->bytes_to_send - conn->bytecount);
4601 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4602 {
4603 if (bytesent > 0)
4604 conn->bytecount += bytesent;
4605 if (conn->bytecount == conn->bytes_to_send)
4606 {
4607 ++conn->pass;
4608 conn->state = CONN_PAUSE;
4609 /* ------ HERE CALL check_protocol(conn) ------- */
4610 check_protocol(conn, SH_DO_WRITE);
4611 }
4612 }
4613 else
4614 {
4615 goto conn_reset_w;
4616 }
4617 }
4618
4619 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send == 0)
4620 {
4621 ++conn->pass;
4622 conn->state = CONN_PAUSE;
4623 /* fprintf(stderr, "\n**** FIXME null write ****\n\n"); */
4624 /* ------ HERE CALL check_protocol(conn) ------- */
4625 check_protocol(conn, SH_DO_WRITE);
4626 }
4627
4628 if (conn->fd >= 0)
4629 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4630 SL_RETURN( (0), _("sh_forward_do_write"));
4631
4632 conn_reset_w:
4633 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4634 conn->peer);
4635 sh_forward_do_free ( conn );
4636 SL_RETURN( (-1), _("sh_forward_do_write"));
4637}
4638
4639/* accept a connection from a client
4640 */
4641#include <syslog.h>
4642#ifdef SH_USE_LIBWRAP
4643#include <tcpd.h>
4644
4645#ifndef ALLOW_SEVERITY
4646#define ALLOW_SEVERITY LOG_INFO
4647#define DENY_SEVERITY LOG_WARNING
4648#endif
4649
4650int allow_severity;
4651int deny_severity;
4652#endif
4653
4654int sh_forward_accept (int sock, sh_conn_t * newconn)
4655{
4656 int errflag;
4657 int rc;
4658 struct sockaddr_in addr;
4659#ifdef SH_USE_LIBWRAP
4660 struct request_info request;
4661 char errbuf[128];
4662 char daemon[128];
4663#endif
4664
4665 /* handle AIX (size_t addrlen) in wrapper
4666 */
4667 int addrlen = sizeof(addr);
4668
4669 SL_ENTER(_("sh_forward_accept"));
4670
4671 rc = retry_accept(FIL__, __LINE__, sock,
4672 (struct sockaddr *) &addr, &addrlen);
4673
4674 if (rc >= 0)
4675 {
4676
4677 if (addrlen == 0)
4678 {
4679 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4680 _("Connecting entity unknown"), _("accept"));
4681 newconn->fd = -1;
4682 newconn->state = CONN_FREE;
4683 sl_close_fd(FIL__, __LINE__, rc);
4684 SL_RETURN( (-1), _("sh_forward_accept"));
4685 }
4686
4687#ifdef SH_USE_LIBWRAP
4688 sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
4689 request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
4690 fromhost(&request);
4691 if (!hosts_access(&request))
4692 {
4693 sl_strlcpy(errbuf, _("Refused connection from "), 128);
4694 sl_strlcat(errbuf, eval_client(&request), 128);
4695
4696 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4697 errbuf, _("libwrap"));
4698 newconn->fd = -1;
4699 newconn->state = CONN_FREE;
4700 sl_close_fd(FIL__, __LINE__, rc);
4701 SL_RETURN( (-1), _("sh_forward_accept"));
4702 }
4703#endif
4704
4705 memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
4706
4707 /* prepare for usage of connection
4708 */
4709 (void) retry_fcntl( FIL__, __LINE__, rc, F_SETFD, 1 );
4710 newconn->fd = rc;
4711 newconn->state = CONN_READING;
4712 newconn->timer = (unsigned long) time (NULL);
4713
4714 if (flag_err_info == SL_TRUE)
4715 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CNEW, newconn->fd);
4716
4717 SL_RETURN( (0), _("sh_forward_accept"));
4718 }
4719 else
4720 {
4721 char err_buf[SH_ERRBUF_SIZE];
4722 errflag = errno;
4723 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4724 sh_error_message(errflag,err_buf, sizeof(err_buf)), _("accept"));
4725 newconn->fd = -1;
4726 newconn->state = CONN_FREE;
4727 SL_RETURN( (-1), _("sh_forward_accept"));
4728 }
4729}
4730
4731extern char sh_sig_msg[64]; /* defined in sh_unix.c */
4732
4733/* ------------ port and interface -------
4734 */
4735static unsigned int server_port = SH_DEFAULT_PORT;
4736
4737int sh_forward_set_port (const char * str)
4738{
4739 int retval = 0;
4740 unsigned long i;
4741 char * endptr;
4742
4743 SL_ENTER(_("sh_forward_set_port"));
4744 i = strtoul (str, &endptr, 0);
4745 if (endptr == str) {
4746 retval = -1;
4747 } else if (i > 65535) {
4748 retval = -1;
4749 } else {
4750 server_port = i;
4751 }
4752 SL_RETURN( (retval), _("sh_forward_set_port"));
4753}
4754
4755static struct in_addr server_interface;
4756static int use_server_interface = 0;
4757
4758int sh_forward_set_interface (const char * str)
4759{
4760 if (0 == strcmp(str, _("INADDR_ANY")))
4761 {
4762 use_server_interface = 0;
4763 return 0;
4764 }
4765 if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/)
4766 {
4767 use_server_interface = 0;
4768 return -1;
4769 }
4770 use_server_interface = 1;
4771 return 0;
4772}
4773
4774/* ------------ print error --------------
4775 */
4776struct sock_err_st {
4777 char msg[128];
4778 int errnum;
4779 int port;
4780 int line;
4781 int euid;
4782};
4783
4784static struct sock_err_st sock_err[2];
4785
4786void sh_forward_printerr(char * str, int errnum, unsigned int port, int line)
4787{
4788 int slot = 0;
4789
4790 if (port != server_port)
4791 slot = 1;
4792 if (str == NULL)
4793 sock_err[slot].msg[0] = '\0';
4794 else
4795 sl_strlcpy(sock_err[slot].msg, str, 128);
4796 sock_err[slot].errnum = errnum;
4797 sock_err[slot].port = port;
4798 sock_err[slot].line = line;
4799 sock_err[slot].euid = (int) geteuid();
4800}
4801
4802int sh_forward_printerr_final(int slot)
4803{
4804 char errbuf[SH_ERRBUF_SIZE];
4805
4806 SL_ENTER(_("sh_forward_printerr_final"));
4807 if (sock_err[slot].msg[0] != '\0')
4808 {
4809 dlog(1, FIL__, __LINE__,
4810 _("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"),
4811 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
4812 sock_err[slot].euid,
4813 sock_err[slot].port);
4814 sh_error_handle((-1), FIL__, sock_err[slot].line,
4815 sock_err[slot].errnum, MSG_EXIT_ABORTS,
4816 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
4817 sh.prg_name,
4818 sock_err[slot].msg);
4819 SL_RETURN((-1), _("sh_forward_printerr_final"));
4820 }
4821 SL_RETURN(0, _("sh_forward_printerr_final"));
4822}
4823
4824#define TIME_OUT_DEF 900
4825static unsigned long time_out_val = TIME_OUT_DEF;
4826
4827int sh_forward_set_timeout (const char * c)
4828{
4829 long val;
4830
4831 SL_ENTER(_("sh_forward_set_time_out"));
4832
4833 val = strtol (c, (char **)NULL, 10);
4834
4835 if (val == 0)
4836 {
4837 val = TIME_OUT_DEF;
4838 }
4839 else if (val < 0)
4840 {
4841 time_out_val = TIME_OUT_DEF;
4842 SL_RETURN( (-1), _("sh_forward_set_time_out"));
4843 }
4844
4845 time_out_val = (unsigned long) val;
4846 SL_RETURN( (0), _("sh_forward_set_time_out"));
4847}
4848
4849
4850static sh_conn_t * conns = NULL;
4851static int maxconn = 0; /* maximum number of simultaneous connections */
4852
4853
4854#ifdef INET_SYSLOG
4855#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
4856#define SH_MINSOCK 3
4857int create_syslog_socket (int flag);
4858static int recv_syslog_socket (int fd);
4859static int syslog_sock = -1;
4860#else
4861#define SH_MINSOCK 2
4862#endif
4863
4864extern int pf_unix_fd;
4865
4866/* the tcp socket, and the function to establish it
4867 */
4868static int sh_tcp_sock = -1;
4869
4870int sh_create_tcp_socket (void)
4871{
4872 struct sockaddr_in addr;
4873 int addrlen = sizeof(addr);
4874
4875 int sock = -1;
4876 int errnum = 0;
4877 int flag = 1; /* non-zero to enable an option */
4878
4879 SL_ENTER(_("sh_create_tcp_socket"));
4880
4881 sh_forward_printerr (NULL, 0, server_port, __LINE__);
4882
4883 /* create the socket, bind() it and listen()
4884 */
4885 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
4886 {
4887 errnum = errno;
4888 sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
4889 SL_RETURN((-1), _("sl_create_tcp_socket"));
4890 }
4891 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
4892
4893 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
4894 (void *) &flag, sizeof(flag)) < 0 )
4895 {
4896 errnum = errno;
4897 sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
4898 SL_RETURN((-1), _("sl_create_tcp_socket"));
4899 }
4900
4901 addr.sin_family = AF_INET;
4902 addr.sin_port = htons(server_port);
4903 if (use_server_interface == 0)
4904 addr.sin_addr.s_addr = INADDR_ANY;
4905 else
4906 memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
4907
4908 if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0)
4909 {
4910 errnum = errno;
4911 sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
4912 SL_RETURN((-1), _("sl_create_tcp_socket"));
4913 }
4914
4915 if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
4916 {
4917 errnum = errno;
4918 sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
4919 SL_RETURN((-1), _("sl_create_tcp_socket"));
4920 }
4921
4922 if ( listen(sock, 5) < 0)
4923 {
4924 errnum = errno;
4925 sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
4926 SL_RETURN((-1), _("sl_create_tcp_socket"));
4927 }
4928
4929 sh_tcp_sock = sock;
4930
4931 SL_RETURN((sock), _("sl_create_tcp_socket"));
4932}
4933
4934/*****************************************
4935 *
4936 * This is the server main loop.
4937 *
4938 * The server is set up for listening, and
4939 * and starts a select() loop.
4940 *
4941 *****************************************/
4942
4943void sh_receive()
4944{
4945#ifdef SH_USE_XML
4946 extern int sh_log_file (char * message, char * inet_peer);
4947#endif
4948
4949 int sock = -1;
4950 sh_conn_t * cx;
4951 fd_set readset;
4952 fd_set writeset;
4953 struct timeval tv;
4954 int num_sel;
4955 int errnum;
4956 int nowconn;
4957 int status;
4958 int high_fd;
4959 register int i;
4960 long dummy = 0;
4961 unsigned long time_now;
4962 unsigned long time_last = 0;
4963 unsigned long time_out = time_out_val;
4964
4965 time_t told;
4966 time_t tcurrent;
4967
4968 unsigned long tchkold;
4969
4970 struct sigaction new_act;
4971 struct sigaction old_act;
4972
4973 int setsize_fd;
4974
4975 SL_ENTER(_("sh_receive"));
4976
4977 /* ignore SIGPIPE (instead get EPIPE if connection is closed)
4978 * --- we have called sh_unix_init() already ---
4979 */
4980 new_act.sa_handler = SIG_IGN;
4981 sigemptyset( &new_act.sa_mask ); /* set an empty mask */
4982 new_act.sa_flags = 0; /* init sa_flags */
4983 retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
4984
4985 if ( sh_forward_printerr_final(0) < 0)
4986 {
4987 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4988 }
4989 sock = sh_tcp_sock;
4990
4991 /* ****************************************************************
4992 *
4993 * This is a non-forking server. We use select() on the listen()
4994 * socket to watch for new connections. For new connections, accept()
4995 * will return a new socket that is put in the read/write filesets.
4996 * Data about active connections are kept in the 'conns' table.
4997 *
4998 ******************************************************************/
4999
5000 /* The table to hold info on sockets.
5001 * We reserve 6 file descriptors for misc. use.
5002 * The POSIX lower limit on open files seems to be eight.
5003 */
5004 maxconn = get_open_max() - 6;
5005 /* ugly fix for FreeBSD compiler warning; casting FD_SETSIZE in the
5006 * conditional expression does not suppress the warning... */
5007 setsize_fd = (int)FD_SETSIZE;
5008 maxconn = (setsize_fd < maxconn) ? setsize_fd : maxconn;
5009
5010 if (maxconn < 0 || !sl_ok_muls(maxconn, sizeof(sh_conn_t)))
5011 {
5012 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
5013 0, sock);
5014 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
5015 }
5016 conns = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
5017
5018 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
5019 (maxconn-1), sock);
5020
5021 /* timer
5022 */
5023 tcurrent = (unsigned long) time (NULL);
5024 told = tcurrent;
5025
5026 tchkold = tcurrent;
5027
5028 for (i = SH_MINSOCK; i < maxconn; ++i)
5029 {
5030 conns[i].buf = NULL;
5031 conns[i].K = NULL;
5032 conns[i].A = NULL;
5033 conns[i].M1 = NULL;
5034 conns[i].FileName = NULL;
5035 conns[i].fd = -1;
5036 sh_forward_do_free ( &conns[i]);
5037 }
5038
5039 /* status init
5040 */
5041 server_status.conn_open = 0;
5042 server_status.conn_total = 0;
5043 server_status.conn_max = maxconn-1;
5044 server_status.start = time (NULL);
5045 server_status.last = (time_t) 0;
5046
5047 nowconn = 1;
5048 tv.tv_sec = 5;
5049 tv.tv_usec = 0;
5050
5051 /* conns[0] is the listen() socket. Always in read mode.
5052 */
5053 conns[0].fd = sock;
5054 conns[0].state = CONN_READING;
5055 high_fd = sock;
5056
5057 conns[1].fd = pf_unix_fd;
5058 conns[1].state = CONN_READING;
5059 high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
5060
5061#ifdef INET_SYSLOG
5062 conns[2].fd = -1;
5063 if ( sh_forward_printerr_final(1) < 0)
5064 {
5065 SH_FREE(conns);
5066 conns = NULL;
5067 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
5068 }
5069 sock = syslog_sock;
5070
5071 if (sock >= 0)
5072 {
5073 conns[2].fd = sock;
5074 conns[2].state = CONN_READING;
5075 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5076 }
5077#endif
5078
5079 sh_html_write(all_clients);
5080
5081 /* This is the select() loop.
5082 */
5083 while (1 == 1)
5084 {
5085
5086 if (sig_raised > 0)
5087 {
5088 TPT((0, FIL__, __LINE__, _("msg=<Process a signal.>\n")))
5089
5090 if (sig_termfast == 1) /* SIGTERM */
5091 {
5092 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
5093 strncpy (sh_sig_msg, _("SIGTERM"), 20);
5094 --sig_raised; --sig_urgent;
5095 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
5096 }
5097
5098 if (sig_config_read_again == 1)
5099 {
5100 TPT((0, FIL__, __LINE__, _("msg=<Re-read configuration.>\n")));
5101 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
5102
5103
5104 /* -- Delete the name server cache. --
5105 */
5106
5107 delete_cache();
5108#if defined(WITH_EXTERNAL)
5109 /* -- Delete list of external tasks. --
5110 */
5111 (void) sh_ext_cleanup();
5112#endif
5113#if defined(SH_WITH_MAIL)
5114 sh_nmail_free();
5115#endif
5116 /* - mark all clients dead
5117 * - read configuration file
5118 * - remove clients still dead
5119 */
5120 sh_forward_mark_dead ();
5121
5122 reset_count_dev_console();
5123 reset_count_dev_time();
5124 sl_trust_purge_user();
5125
5126 (void) sh_readconf_read ();
5127 for (i = SH_MINSOCK; i < maxconn; ++i)
5128 if (conns[i].state != CONN_FREE &&
5129 conns[i].client_entry != NULL &&
5130 conns[i].client_entry->dead_flag == 1)
5131 sh_forward_do_free ( &conns[i]);
5132 sh_forward_clean_tree ();
5133
5134 sig_config_read_again = 0;
5135 --sig_raised;
5136 }
5137
5138 if (sig_fresh_trail == 1) /* SIGIOT */
5139 {
5140 /* Logfile access
5141 */
5142#ifdef SH_USE_XML
5143 sh_log_file (NULL, NULL);
5144#endif
5145 TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
5146 sh_error_only_stderr (S_TRUE);
5147 sh_unix_rm_lock_file(sh.srvlog.name);
5148 retry_msleep(3, 0);
5149 sh.flag.log_start = S_TRUE;
5150 sh_error_only_stderr (S_FALSE);
5151 sig_fresh_trail = 0;
5152 --sig_raised;
5153 }
5154
5155
5156 if (sig_terminate == 1 && nowconn < 2) /* SIGQUIT */
5157 {
5158 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
5159 strncpy (sh_sig_msg, _("SIGQUIT"), 20);
5160 --sig_raised; --sig_urgent;
5161 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
5162 }
5163
5164
5165 if (sig_debug_switch == 1) /* SIGUSR1 */
5166 {
5167 TPT((0, FIL__, __LINE__, _("msg=<Debug switch.>\n")));
5168 sh_error_dbg_switch();
5169 sig_debug_switch = 0;
5170 --sig_raised;
5171 }
5172
5173 if (sig_suspend_switch > 0) /* SIGUSR2 */
5174 {
5175 TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
5176 if (sh_global_suspend_flag == 1) {
5177 sh_global_suspend_flag = 0;
5178 } else {
5179 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND,
5180 sh.prg_name);
5181 sh_global_suspend_flag = 1;
5182 }
5183 --sig_suspend_switch;
5184 --sig_raised; --sig_urgent;
5185 }
5186
5187 sig_raised = (sig_raised < 0) ? 0 : sig_raised;
5188 sig_urgent = (sig_urgent < 0) ? 0 : sig_urgent;
5189 TPT((0, FIL__, __LINE__, _("msg=<End signal processing.>\n")));
5190 }
5191
5192 if (sh_global_suspend_flag == 1)
5193 {
5194 (void) retry_msleep (1, 0);
5195 continue;
5196 }
5197
5198 /* Recompute the descriptor set. select() modifies it,
5199 * thus we update it using the info from the connection table.
5200 * Also recompute the number of open connections.
5201 */
5202 FD_ZERO( &readset );
5203 FD_ZERO( &writeset );
5204 FD_SET(conns[0].fd, &readset );
5205 high_fd = conns[0].fd;
5206
5207 if (conns[1].fd > -1)
5208 {
5209 FD_SET(conns[1].fd, &readset );
5210 high_fd = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
5211 }
5212
5213#ifdef INET_SYSLOG
5214 if (conns[2].fd > -1)
5215 {
5216 FD_SET(conns[2].fd, &readset );
5217 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5218 }
5219#endif
5220
5221 time_now = (unsigned long) time (NULL);
5222 nowconn = 1;
5223
5224 for (i = SH_MINSOCK; i < maxconn; ++i)
5225 {
5226 /* eliminate timed out connections
5227 */
5228 if (conns[i].state != CONN_FREE)
5229 {
5230 if (time_now-conns[i].timer > time_out)
5231 {
5232 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMOUT,
5233 conns[i].peer);
5234 sh_forward_do_free ( &conns[i]);
5235 }
5236 else
5237 ++nowconn;
5238 }
5239
5240
5241 if (conns[i].state == CONN_READING)
5242 {
5243 FD_SET(conns[i].fd, &readset);
5244 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5245 }
5246 else if (conns[i].state == CONN_SENDING)
5247 {
5248 FD_SET(conns[i].fd, &writeset);
5249 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5250 }
5251 }
5252
5253 /* -- Exponentially reduce timeout limit if more than 1/2 full. --
5254 */
5255 /* Eliminate this, will cause problems when too much clients are
5256 * starting up. */
5257#if 0
5258 if (nowconn > (maxconn/2))
5259 time_out = ( (time_out/2) > 1) ? (time_out/2) : 1;
5260 else
5261 time_out = time_out_val;
5262#endif
5263
5264
5265 /* -- Do the select(). --
5266 */
5267 num_sel = select(high_fd+1, &readset, &writeset, NULL, &tv);
5268 errnum = errno;
5269
5270 /* reset timeout - modified by select() on some systems
5271 */
5272 tv.tv_sec = 5;
5273 tv.tv_usec = 0;
5274
5275
5276 if ( (time_now - time_last) > 2L)
5277 {
5278 time_last = time_now;
5279 if (sh_html_write(all_clients) < 0)
5280 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5281 }
5282
5283
5284 /* Error handling.
5285 */
5286 if ( num_sel < 0 ) /* some error */
5287 {
5288 char errbuf[SH_ERRBUF_SIZE];
5289
5290 if (sig_raised == 1)
5291 {
5292 sig_raised = 2;
5293 continue;
5294 }
5295
5296 if ( errnum == EINTR)
5297 continue; /* try again */
5298
5299 if ( errnum == EBADF)
5300 {
5301 /* seek and destroy the bad fd
5302 */
5303 for (i = SH_MINSOCK; i < high_fd; ++i)
5304 {
5305 if ((conns[i].state == CONN_READING) ||
5306 (conns[i].state == CONN_SENDING))
5307 {
5308 if (-1 == retry_fcntl(FIL__, __LINE__,
5309 conns[i].fd, F_GETFL, dummy))
5310 sh_forward_do_free ( &conns[i]);
5311 }
5312 }
5313 continue;
5314 }
5315
5316 sh_error_handle((-1), FIL__, __LINE__, errnum, MSG_EXIT_ABORTS,
5317 sh_error_message(errnum, errbuf, sizeof(errbuf)),
5318 sh.prg_name,
5319 _("select"));
5320 aud_exit(FIL__, __LINE__, EXIT_FAILURE );
5321 }
5322
5323
5324 /* log the timestamp
5325 */
5326 if ((tcurrent - told) > sh.looptime )
5327 {
5328 told = tcurrent;
5329#ifdef MEM_DEBUG
5330 sh_mem_check();
5331 sh_unix_count_mlock();
5332#else
5333 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_STAMP);
5334#endif
5335 }
5336
5337#if defined(SH_WITH_MAIL)
5338 /*
5339 * flush the mail queue
5340 */
5341 if (tcurrent - sh.mailTime.alarm_last > sh.mailTime.alarm_interval)
5342 {
5343 TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
5344 (void) sh_nmail_flush ();
5345 sh.mailTime.alarm_last = tcurrent;
5346 }
5347#endif
5348#ifdef MEM_DEBUG
5349 sh_mem_dump();
5350#endif
5351
5352 tcurrent = (unsigned long) time (NULL);
5353
5354 /* check for time limit exceeded
5355 */
5356 if ((tcurrent - tchkold) > (unsigned int) 3 )
5357 {
5358 tchkold = tcurrent;
5359 client_time_check(/* all_clients */);
5360 }
5361
5362 /* seed / re-seed the PRNG if required
5363 */
5364 (void) taus_seed();
5365
5366 /* select() timeout handling.
5367 */
5368 if ( num_sel == 0 ) /* timeout - no connection */
5369 {
5370 if (sh_html_write(all_clients) < 0)
5371 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5372 continue;
5373 }
5374
5375 /* New connection.
5376 */
5377 if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection */
5378 {
5379 --num_sel;
5380 status = 0;
5381 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
5382 {
5383 i = SH_MINSOCK;
5384 while (i < maxconn)
5385 {
5386 if (conns[i].state == CONN_FREE)
5387 {
5388 status = sh_forward_accept (conns[0].fd, &conns[i]);
5389 if (status == 0)
5390 {
5391 high_fd =
5392 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
5393 ++server_status.conn_open;
5394 ++server_status.conn_total;
5395 server_status.last = time (NULL);
5396 }
5397 break;
5398 }
5399 ++i;
5400 }
5401 }
5402 if (status == 0)
5403 continue;
5404 }
5405
5406 /* check for commands on the socket
5407 */
5408 if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
5409 {
5410 sh_socket_poll();
5411 }
5412
5413#ifdef INET_SYSLOG
5414 if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
5415 {
5416 recv_syslog_socket (conns[2].fd);
5417 }
5418#endif
5419
5420 /* Check for pending read/write on the rest of the sockets.
5421 */
5422 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
5423 {
5424 if (sig_termfast == 1)
5425 break;
5426
5427 cx = &conns[i];
5428 if ( cx->state == CONN_READING &&
5429 FD_ISSET( cx->fd, &readset ) )
5430 {
5431 --num_sel;
5432 sh_forward_do_read ( cx );
5433 }
5434 else if ( cx->state == CONN_SENDING &&
5435 FD_ISSET( cx->fd, &writeset ) )
5436 {
5437 --num_sel;
5438 sh_forward_do_write ( cx );
5439 }
5440 }
5441 /* continue */
5442 }
5443 /* notreached */
5444}
5445
5446void free_client_tree (void)
5447{
5448 SL_ENTER(_("free_client_tree"));
5449 zAVLFreeTree (all_clients, free_client);
5450 SL_RET0(_("free_client_tree"));
5451}
5452
5453void sh_forward_free_all ()
5454{
5455 register int i;
5456
5457 SL_ENTER(_("sh_forward_free_all"));
5458
5459 if (conns != NULL)
5460 for (i = SH_MINSOCK; i < maxconn; ++i)
5461 {
5462 sh_forward_do_free ( &conns[i]);
5463 }
5464
5465
5466 free_client_tree ();
5467
5468 if (conns != NULL)
5469 SH_FREE (conns);
5470
5471 SL_RET0(_("sh_forward_free_all"));
5472}
5473
5474#ifdef INET_SYSLOG
5475
5476#ifdef HAVE_INET_ATON
5477static char * my_inet_ntoa(struct in_addr in)
5478{
5479 return inet_ntoa(in);
5480}
5481#else
5482static char * my_inet_ntoa(struct in_addr in)
5483{
5484 unsigned char a, b, c, d;
5485 static char foo[16];
5486 char bar[4];
5487 memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
5488 memcpy (&a, &bar[0], 1);
5489 memcpy (&b, &bar[1], 1);
5490 memcpy (&c, &bar[2], 1);
5491 memcpy (&d, &bar[3], 1);
5492 sprintf(foo, "%d.%d.%d.%d", /* known to fit */
5493 (int) a, (int) b, (int) c, (int) d);
5494 return foo;
5495}
5496#endif
5497
5498
5499/* Unlike Linux / FreeBSD, most systems don't define the stuff below
5500 * in syslog.h
5501 */
5502
5503#ifndef LOG_FAC
5504#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
5505#endif
5506
5507#ifndef LOG_PRI
5508#define LOG_PRI(p) ((p) & LOG_PRIMASK)
5509#endif
5510
5511typedef struct sh_code {
5512 char *c_name;
5513 int c_val;
5514} SH_CODE;
5515
5516SH_CODE sh_facilitynames[] =
5517{
5518#ifdef LOG_AUTH
5519 { N_("auth"), LOG_AUTH },
5520#endif
5521#ifdef LOG_AUTHPRIV
5522 { N_("authpriv"), LOG_AUTHPRIV },
5523#endif
5524#ifdef LOG_CRON
5525 { N_("cron"), LOG_CRON },
5526#endif
5527#ifdef LOG_DAEMON
5528 { N_("daemon"), LOG_DAEMON },
5529#endif
5530#ifdef LOG_FTP
5531 { N_("ftp"), LOG_FTP },
5532#endif
5533#ifdef LOG_KERN
5534 { N_("kern"), LOG_KERN },
5535#endif
5536#ifdef LOG_LPR
5537 { N_("lpr"), LOG_LPR },
5538#endif
5539#ifdef LOG_MAIL
5540 { N_("mail"), LOG_MAIL },
5541#endif
5542#ifdef INTERNAL_MARK
5543 { N_("mark"), INTERNAL_MARK }, /* INTERNAL */
5544#endif
5545#ifdef LOG_NEWS
5546 { N_("news"), LOG_NEWS },
5547#endif
5548#ifdef LOG_AUTH
5549 { N_("security"), LOG_AUTH }, /* DEPRECATED */
5550#endif
5551#ifdef LOG_SYSLOG
5552 { N_("syslog"), LOG_SYSLOG },
5553#endif
5554#ifdef LOG_USER
5555 { N_("user"), LOG_USER },
5556#endif
5557#ifdef LOG_UUCP
5558 { N_("uucp"), LOG_UUCP },
5559#endif
5560#ifdef LOG_LOCAL0
5561 { N_("local0"), LOG_LOCAL0 },
5562#endif
5563#ifdef LOG_LOCAL1
5564 { N_("local1"), LOG_LOCAL1 },
5565#endif
5566#ifdef LOG_LOCAL2
5567 { N_("local2"), LOG_LOCAL2 },
5568#endif
5569#ifdef LOG_LOCAL3
5570 { N_("local3"), LOG_LOCAL3 },
5571#endif
5572#ifdef LOG_LOCAL4
5573 { N_("local4"), LOG_LOCAL4 },
5574#endif
5575#ifdef LOG_LOCAL5
5576 { N_("local5"), LOG_LOCAL5 },
5577#endif
5578#ifdef LOG_LOCAL6
5579 { N_("local6"), LOG_LOCAL6 },
5580#endif
5581#ifdef LOG_LOCAL7
5582 { N_("local7"), LOG_LOCAL7 },
5583#endif
5584 { NULL, -1 }
5585};
5586
5587
5588SH_CODE sh_prioritynames[] =
5589{
5590#ifdef LOG_ALERT
5591 { N_("alert"), LOG_ALERT },
5592#endif
5593#ifdef LOG_CRIT
5594 { N_("crit"), LOG_CRIT },
5595#endif
5596#ifdef LOG_DEBUG
5597 { N_("debug"), LOG_DEBUG },
5598#endif
5599#ifdef LOG_EMERG
5600 { N_("emerg"), LOG_EMERG },
5601#endif
5602#ifdef LOG_ERR
5603 { N_("err"), LOG_ERR },
5604#endif
5605#ifdef LOG_ERR
5606 { N_("error"), LOG_ERR }, /* DEPRECATED */
5607#endif
5608#ifdef LOG_INFO
5609 { N_("info"), LOG_INFO },
5610#endif
5611#ifdef INTERNAL_NOPRI
5612 { N_("none"), INTERNAL_NOPRI }, /* INTERNAL */
5613#endif
5614#ifdef LOG_NOTICE
5615 { N_("notice"), LOG_NOTICE },
5616#endif
5617#ifdef LOG_EMERG
5618 { N_("panic"), LOG_EMERG }, /* DEPRECATED */
5619#endif
5620#ifdef LOG_WARNING
5621 { N_("warn"), LOG_WARNING }, /* DEPRECATED */
5622#endif
5623#ifdef LOG_WARNING
5624 { N_("warning"), LOG_WARNING },
5625#endif
5626 { NULL, -1 }
5627};
5628
5629static int enable_syslog_socket = S_FALSE;
5630
5631static int recv_syslog_socket (int fd)
5632{
5633 static time_t return_next = 0;
5634 int priority = 0;
5635 int fac, pri;
5636 int i;
5637 char * cfac = NULL;
5638 char * cpri = NULL;
5639 int res;
5640 char * tmp;
5641 char * bptr;
5642 char * ptr = NULL;
5643 char buf[1048];
5644 struct sockaddr_in from;
5645 char errbuf[SH_ERRBUF_SIZE];
5646
5647 /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
5648 * but *int everywhere else. Because socklen_t is unsigned int, there
5649 * should be no problem as long as sizeof(struct sockaddr_in) < INT_MAX ...
5650 */
5651 int fromlen = sizeof(from);
5652
5653 if (enable_syslog_socket == S_FALSE)
5654 return 0;
5655
5656 SL_ENTER(_("recv_syslog_socket"));
5657
5658 if (return_next > 0)
5659 {
5660 if ( (time(NULL) - return_next) < 2)
5661 SL_RETURN( 0, _("recv_syslog_socket"));
5662 else
5663 return_next = 0;
5664 }
5665
5666 res = recvfrom(fd, buf, 1047, 0, (struct sockaddr *) &from, &fromlen);
5667
5668 if (res > 0)
5669 {
5670 res = (res < 1047) ? res : 1047;
5671 buf[res] = '\0';
5672 if (res > 1 && buf[res-1] == '\n')
5673 buf[res-1] = '\0';
5674
5675 /* here we expect an xml formatted message, thus we don't
5676 escape xml special chars (flag == 0) */
5677 /* commented out to not escape twice */
5678 /* bptr = sh_tools_safe_name(buf, 0); */
5679 bptr = buf;
5680
5681 if (!bptr || !(*bptr))
5682 {
5683 res = errno;
5684 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5685 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5686 sh_error_message(res, errbuf, sizeof(errbuf)),
5687 my_inet_ntoa(from.sin_addr));
5688 SL_RETURN( (-1), _("recv_syslog_socket"));
5689 }
5690
5691 TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
5692 my_inet_ntoa(from.sin_addr)));
5693 ptr = bptr;
5694 i = 0;
5695 if (*ptr == '<')
5696 {
5697 ++ptr; ++i;
5698 while (i < res &&
5699 (unsigned char) *ptr > 47 && (unsigned char) *ptr < 58)
5700 {
5701 priority = 10 * priority + (*ptr - '0');
5702 ++ptr;
5703 ++i;
5704 }
5705 if (*ptr == '>')
5706 ++ptr;
5707 }
5708 fac = LOG_FAC(priority);
5709 i = 0;
5710 while (sh_facilitynames[i].c_name != NULL)
5711 {
5712 if (sh_facilitynames[i].c_val == (fac<<3))
5713 { cfac = sh_util_strdup(_(sh_facilitynames[i].c_name)); break; }
5714 ++i;
5715 }
5716 pri = LOG_PRI(priority);
5717 i = 0;
5718 while (sh_prioritynames[i].c_name != NULL)
5719 {
5720 if (sh_prioritynames[i].c_val == pri)
5721 { cpri = sh_util_strdup(_(sh_prioritynames[i].c_name)); break; }
5722 ++i;
5723 }
5724
5725 /* here we do not expect an xml formatted message, thus we escape
5726 xml special chars (flag == 1) */
5727 tmp = sh_tools_safe_name (ptr, 1);
5728 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_INET_SYSLOG,
5729 my_inet_ntoa(from.sin_addr),
5730 (cfac == NULL) ? _("none") : cfac,
5731 (cpri == NULL) ? _("none") : cpri,
5732 (ptr == NULL) ? _("none") : ptr);
5733 if (cfac != NULL)
5734 SH_FREE(cfac);
5735 if (cpri != NULL)
5736 SH_FREE(cpri);
5737 SH_FREE(tmp);
5738 /* SH_FREE(bptr); */
5739 }
5740
5741 else if (res < 0 && errno != EINTR)
5742 {
5743 res = errno;
5744 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5745 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
5746 sh_error_message(res, errbuf, sizeof(errbuf)),
5747 my_inet_ntoa(from.sin_addr));
5748
5749 /* don't accept anything the next 2 seconds
5750 */
5751 return_next = time(NULL);
5752 SL_RETURN( (-1), _("recv_syslog_socket"));
5753 }
5754 SL_RETURN( (0), _("recv_syslog_socket"));
5755}
5756
5757int set_syslog_active(const char * c)
5758{
5759 return sh_util_flagval(c, &enable_syslog_socket);
5760}
5761
5762/* callerFlag == S_TRUE means override the enable_syslog_socket flag
5763 */
5764int create_syslog_socket (int callerFlag)
5765{
5766 int flag = 1; /* non-zero to enable an option */
5767 int sock;
5768 int errnum;
5769 int res;
5770 struct sockaddr_in addr;
5771 int addrlen = sizeof(addr);
5772
5773 SL_ENTER(_("create_syslog_socket"));
5774
5775 if (callerFlag == S_FALSE)
5776 {
5777 if (enable_syslog_socket == S_FALSE && syslog_sock >= 0)
5778 {
5779 /* user does not wish to use this facility
5780 */
5781 TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
5782 sl_close_fd(FIL__, __LINE__, syslog_sock);
5783 syslog_sock = -1;
5784 }
5785 SL_RETURN((-1), _("create_syslog_socket"));
5786 }
5787
5788 sh_forward_printerr (NULL, 0, 514, __LINE__);
5789
5790 /* create the socket, bind() it and listen()
5791 */
5792 sock = socket(AF_INET, SOCK_DGRAM, 0);
5793
5794 if (sock < 0)
5795 {
5796 errnum = errno;
5797 sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
5798 SL_RETURN((-1), _("create_syslog_socket"));
5799 }
5800 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
5801
5802 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5803 (void *) &flag, sizeof(flag)) < 0 )
5804 {
5805 errnum = errno;
5806 sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
5807 errnum, 514, __LINE__);
5808 SL_RETURN((-1), _("create_syslog_socket"));
5809 }
5810
5811#if defined(SO_BSDCOMPAT)
5812 if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
5813 (void *) &flag, sizeof(flag)) < 0 )
5814 {
5815 errnum = errno;
5816 sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
5817 errnum, 514, __LINE__);
5818 SL_RETURN((-1), _("create_syslog_socket"));
5819 }
5820#endif
5821
5822 memset(&addr, 0, sizeof(addr));
5823 addr.sin_family = AF_INET;
5824 addr.sin_port = htons(514);
5825
5826 res = bind(sock, (struct sockaddr *) &addr, addrlen);
5827
5828 if ( res < 0)
5829 {
5830 errnum = errno;
5831 sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
5832 sl_close_fd(FIL__, __LINE__, sock);
5833 SL_RETURN((-1), _("create_syslog_socket"));
5834 }
5835
5836 syslog_sock = sock;
5837
5838 SL_RETURN((sock), _("create_syslog_socket"));
5839}
5840/* #ifdef INET_SYSLOG */
5841#endif
5842
5843
5844
5845/* #ifdef SH_WITH_SERVER */
5846#endif
5847
5848
5849
5850
5851
5852
Note: See TracBrowser for help on using the repository browser.