source: trunk/src/sh_forward.c@ 132

Last change on this file since 132 was 132, checked in by rainer, 18 years ago

Make utility functions thread-safe.

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