source: trunk/src/sh_forward.c@ 136

Last change on this file since 136 was 133, checked in by rainer, 17 years ago

Reentrant checksum/hash functions.

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