source: trunk/src/sh_forward.c@ 479

Last change on this file since 479 was 407, checked in by katerina, 12 years ago

Fix for tickets #309, #310.

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