source: trunk/src/sh_forward.c@ 180

Last change on this file since 180 was 178, checked in by katerina, 16 years ago

Increase server timeout (ticket #116).

File size: 144.5 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;
[137]279 char hashbuf[KEYBUF_SIZE];
[1]280
281 if (password == NULL)
282 dez = (unsigned char *) &(skey->pw[0]);
283 else if (sl_strlen(password) < PW_LEN)
284 {
285 fprintf(stderr, _("Password has less than %d chars !\n"),
286 PW_LEN);
287 _exit(EXIT_FAILURE);
288 }
289
290 if (password == NULL)
291 {
292 /* --- copy password ---
293 */
294 for (i = 0; i < PW_LEN; ++i)
295 {
296 skey->vernam[i] = (char)(*dez);
297 ++dez;
298 }
299 (void) sl_strlcpy (skey->vernam,
[137]300 sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN,
301 hashbuf, sizeof(hashbuf)),
[1]302 KEY_LEN+1);
303 }
304 else
305 {
306 (void) sl_strlcpy (skey->vernam, password, KEY_LEN+1);
307 }
308
[34]309 len = sl_strlen(salt) + 1;
310 if (sl_ok_adds(len, sl_strlen(skey->vernam)))
311 len += sl_strlen(skey->vernam);
312 if (nounce != NULL && sl_ok_adds(len, sl_strlen(nounce)))
[1]313 len += sl_strlen(nounce);
314
315 /* H(s,P)
316 */
317 combi = SH_ALLOC(len);
318 (void) sl_strlcpy (combi, salt, len);
319 (void) sl_strlcat (combi, skey->vernam, len);
320 if (nounce != NULL)
321 (void) sl_strlcat (combi, nounce, len);
322 (void) sl_strlcpy (hash,
323 sh_tiger_hash(combi, TIGER_DATA,
[137]324 (unsigned long) sl_strlen(combi),
325 hashbuf, sizeof(hashbuf)),
[1]326 KEY_LEN+1);
327
328 /*
329 fprintf(stderr, "DD: A: <%s>\n", salt);
330 fprintf(stderr, "DD: P: <%s>\n", skey->pw);
331 fprintf(stderr, "DD: V: <%s>\n", skey->vernam);
332 fprintf(stderr, "DD: C: <%s>\n", combi);
333 fprintf(stderr, "DD: H: <%s>\n", hash);
334 */
335
336 SH_FREE (combi);
337 hash[KEY_LEN] = '\0';
338 return;
339}
340#endif
341
[27]342#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
[1]343
344static int count_dev_server = 0;
345
346void reset_count_dev_server(void)
347{
348 count_dev_server = 0;
349 return;
350}
351
[22]352int sh_forward_setlogserver (const char * address)
[1]353{
354 SL_ENTER(_("sh_forward_setlogserver"));
355
356 if (address != NULL && count_dev_server < 2
357 && sl_strlen(address) < SH_PATHBUF && sl_strlen(address) > 0)
358 {
359 if (count_dev_server == 0)
360 (void) sl_strlcpy (sh.srvexport.name, address, SH_PATHBUF);
361 else
362 (void) sl_strlcpy (sh.srvexport.alt, address, SH_PATHBUF);
363
364 ++count_dev_server;
365 SL_RETURN (0, _("sh_forward_setlogserver"));
366 }
367 SL_RETURN (-1, _("sh_forward_setlogserver"));
368}
369
370static
371int sh_forward_send_intern (int mysocket, char protocol, char * micro,
372 char * msgbuf, unsigned long length, int docrypt)
373{
374 unsigned long numbytes, countbytes;
375 int flag_err = 0;
376 unsigned char head[SH_HEADER_SIZE];
377 char * outbuf;
378
379#ifdef SH_ENCRYPT
380
381 unsigned long blkfac;
382 int rem;
383 unsigned long length2;
384 char * msg2buf = NULL;
385 char * p, * q;
386 RIJ_BYTE inBlock[B_SIZ];
387 RIJ_BYTE outBlock[B_SIZ];
388 unsigned long j;
389 cipherInstance cipherInst;
390 int err_num;
[132]391 char expbuf[SH_ERRBUF_SIZE];
[1]392#else
393 docrypt = SL_FALSE; /* dummy to fix compiler warning */
394#endif
395
396 SL_ENTER(_("sh_forward_send_intern"));
397
398#ifdef SH_ENCRYPT
399 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != (char)0))
400 {
401 put_header (head, (int)protocol, &length, micro);
[34]402 msg2buf = sh_tools_makePack (head, msgbuf, length,
[1]403 &(skey->keyInstE));
404 /*@-usedef@*/
405 length = (unsigned long) (256 * (unsigned int)head[1] +
406 (unsigned int)head[2]);
407 /*@+usedef@*/
408 outbuf = msg2buf;
409 }
410 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != (char)0))
411 {
412 blkfac = length/B_SIZ;
413 rem = (int) (length - (B_SIZ * blkfac));
[34]414 length2 = (B_SIZ * blkfac);
415 if ((rem > 0) && (length2+B_SIZ) > length2)
416 length2 += B_SIZ;
417 else
418 rem = 0;
[1]419
420 msg2buf = SH_ALLOC((size_t)length2);
421 p = msgbuf;
422 q = msg2buf;
423
424 err_num = cipherInit (&cipherInst, (RIJ_BYTE)MODE_CBC, NULL);
425
426 if (err_num < 0)
427 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]428 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]429 _("sh_forward_send_intern: cipherInit"));
430
431
432 for (j = 0; j < blkfac; ++j)
433 {
434 memcpy(inBlock, p, B_SIZ);
435 err_num = blockEncrypt(&cipherInst, &(skey->keyInstE),
436 inBlock, 128 * BNUM, outBlock);
437 if (err_num < 0)
438 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]439 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]440 _("sh_forward_send_intern: blockEncrypt"));
441 memcpy(q, outBlock, B_SIZ);
442 p += B_SIZ;
443 q += B_SIZ;
444 }
445 if (rem > 0)
446 {
447 memset(inBlock, 0, B_SIZ);
448 memcpy(inBlock, p, (size_t)rem);
449 err_num = blockEncrypt(&cipherInst, &(skey->keyInstE),
450 inBlock, 128 * BNUM, outBlock);
451 if (err_num < 0)
452 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]453 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]454 _("sh_forward_send_intern: blockEncrypt"));
455 memcpy(q, outBlock, B_SIZ);
456 q += B_SIZ;
457 }
458
459 outbuf = msg2buf;
460 length = length2;
461 put_header (head, (int)protocol, &length, micro);
462 }
463 else
464 {
465 outbuf = msgbuf;
466 put_header (head, (int)protocol, &length, micro);
467 }
468#else
469 outbuf = msgbuf;
470 put_header (head, (int)protocol, &length, micro);
471#endif
472
473 SH_SHOWPROT(head,'>');
474
475 numbytes = SH_HEADER_SIZE;
476 countbytes = write_port (mysocket,
477 (char *) head, numbytes,
478 &flag_err, 300);
479
480 if (countbytes == numbytes && outbuf != NULL)
481 {
482 numbytes = (length);
483 countbytes = write_port (mysocket,
484 outbuf, numbytes,
485 &flag_err, 300);
486 }
487
488#ifdef SH_ENCRYPT
489 /*@-usedef@*/
490 if (msg2buf != NULL)
491 SH_FREE(msg2buf);
492 /*@+usedef@*/
493#endif
494
495 if (countbytes == numbytes)
496 {
497 SL_RETURN( 0, _("sh_forward_send_intern"));
498 }
499 else
500 {
501 SL_RETURN( flag_err, _("sh_forward_send_intern"));
502 }
503}
504static
505int sh_forward_send (int mysocket, char protocol, char * micro,
506 char * msgbuf, unsigned long length)
507{
508 int i;
509 SL_ENTER(_("sh_forward_send"));
510 TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
511 i = sh_forward_send_intern (mysocket, protocol, micro,
512 msgbuf, length, S_FALSE);
513 SL_RETURN(i, _("sh_forward_send"));
514}
515static
516int sh_forward_send_crypt (int mysocket, char protocol, char * micro,
517 char * msgbuf, unsigned long length)
518{
519 int i;
520 SL_ENTER(_("sh_forward_send_crypt"));
521#ifdef SH_ENCRYPT
522 TPT(( 0, FIL__, __LINE__, _("msg=<Send encrypted.>\n")));
523#else
524 TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
525#endif
526 i = sh_forward_send_intern (mysocket, protocol, micro,
527 msgbuf, length, S_TRUE);
528 SL_RETURN(i, _("sh_forward_send_crypt"));
529}
530
531
532/* receive answer, add a trailing NULL to terminate string
533 * rev 0.8
534 */
535static
536long sh_forward_receive_intern (int mysocket, char protocol, char * micro,
537 char * msgbuf, unsigned long length,
538 int docrypt)
539{
540 unsigned long numbytes, countbytes;
541 int flag_err = -1;
542 unsigned char head[SH_HEADER_SIZE];
543
544#ifdef SH_ENCRYPT
545
546 unsigned long head_length;
547 unsigned long blkfac;
548 /* unsigned long length2; */
549 char * p, * q, * tmp;
550 RIJ_BYTE inBlock[B_SIZ];
551 RIJ_BYTE outBlock[B_SIZ];
552 unsigned long j;
553 cipherInstance cipherInst;
554 int err_num;
[132]555 char expbuf[SH_ERRBUF_SIZE];
[1]556#else
557 docrypt = SL_FALSE; /* dummy to fix compiler warning */
558#endif
559
560 SL_ENTER(_("sh_forward_receive_intern"));
561
[34]562#ifdef SH_ENCRYPT
563 /* make sure length is not multiple of B_SIZ, see below
564 */
565 ASSERT_RET((length % B_SIZ != 0), _("length % 16 != 0"), flag_err);
566#endif
567
[1]568 if (micro != NULL)
569 micro[4] = '\0';
570
571 if (msgbuf != NULL)
572 msgbuf[0] = '\0';
573
574 numbytes = SH_HEADER_SIZE;
575 countbytes = read_port (mysocket,
576 (char *) head, numbytes,
577 &flag_err, 300);
578
579 if (countbytes != numbytes)
580 {
581 TPT(( 0, FIL__, __LINE__, _("msg=<countbytes != numbytes>\n")));
582 SL_RETURN(flag_err, _("sh_forward_receive_intern"));
583 }
584 /*@-usedef +ignoresigns@*/
585 else if (head[0] != protocol &&
586 (head[0] & SH_PROTO_SRP) == (char)0 /* not set */)
587 {
588 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISMATCH);
589 SL_RETURN((-1), _("sh_forward_receive_intern"));
590 }
591 /*@+usedef -ignoresigns@*/
592 else
593 {
594 get_header (head, &numbytes, micro);
595 SH_SHOWPROT(head, '<');
596
597 if (numbytes > 0)
598 {
599 numbytes = (numbytes > length ? length : numbytes);
600
601 countbytes = read_port (mysocket,
602 msgbuf, numbytes,
603 &flag_err, 300);
604
605 if (countbytes < length)
606 msgbuf[countbytes] = '\0';
607 else
608 msgbuf[length-1] = '\0';
609
610 if (flag_err != 0)
611 {
612 TPT(( 0, FIL__, __LINE__, _("msg=<read error>\n")));
613 SL_RETURN((-1), _("sh_forward_receive_intern"));
614 }
615 }
616 }
617
618#ifdef SH_ENCRYPT
619 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_EN2) != (char)0))
620 {
621 tmp = SH_ALLOC((size_t)length);
622 memcpy(tmp, msgbuf, (size_t)length);
623 tmp = sh_tools_revertPack (head, tmp, &(skey->keyInstD), countbytes);
624
625 head_length = (unsigned long) (256 * (unsigned int)head[1] +
626 (unsigned int)head[2]);
627
[34]628 /*
629 * revertPack returns header with length <= (original_length-16), so
630 * the following msgbuf[length] = '\0' is always safe.
631 * Nevertheless, check for proper length.
632 */
633 if (head_length <= (length-1))
634 length = head_length;
635 else
636 --length;
637
[1]638 memcpy(msgbuf, tmp, (size_t)length);
639 msgbuf[length] = '\0';
640 SH_FREE(tmp);
641 if (countbytes == numbytes)
642 {
643 countbytes = length; /* to avoid error on return, see below */
644 }
645 numbytes = length;
646 }
647 else if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != (char)0))
648 {
649 /* Decrypt only complete blocks. If there is an incomplete block,
650 * something is wrong anyway.
651 * Decrypt in place.
652 */
653 blkfac = countbytes/B_SIZ;
[34]654
[1]655 p = msgbuf;
656 q = msgbuf;
657
658 err_num = cipherInit (&cipherInst, (RIJ_BYTE)MODE_CBC, NULL);
659
660 if (err_num < 0)
661 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]662 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]663 _("sh_forward_receive_intern: cipherInit"));
664
[34]665 /* here we want to have (length % B_SIZ != 0), such that the
666 * terminating '\0' cannot be overwritten
667 */
[1]668 for (j = 0; j < blkfac; ++j)
669 {
670 memcpy(inBlock, p, B_SIZ);
671 err_num = blockDecrypt(&cipherInst, &(skey->keyInstD),
672 inBlock, 128 * BNUM, outBlock);
673 if (err_num < 0)
674 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]675 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]676 _("sh_forward_receive_intern: blockDecrypt"));
677 memcpy(q, outBlock, B_SIZ);
[34]678 p += B_SIZ;
679 q += B_SIZ;
[1]680 }
681 }
682#endif
683
684 if (countbytes == numbytes)
685 {
686 SL_RETURN(((long)numbytes), _("sh_forward_receive_intern"));
687 }
688 else
689 {
690 TPT(( 0, FIL__, __LINE__, _("msg=<short read>\n")));
691 SL_RETURN(flag_err, _("sh_forward_receive_intern"));
692 }
693}
694
695static
696long sh_forward_receive (int mysocket, char protocol, char * micro,
697 char * msgbuf, unsigned long length)
698{
699 long i;
700 SL_ENTER(_("sh_forward_receive"));
701 TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
702 i = sh_forward_receive_intern (mysocket, protocol, micro,
703 msgbuf, length, S_FALSE);
704 SL_RETURN(i, _("sh_forward_receive"));
705}
706
707static
708long sh_forward_receive_crypt (int mysocket, char protocol, char * micro,
709 char * msgbuf, unsigned long length)
710{
711 long i;
712 SL_ENTER(_("sh_forward_receive_crypt"));
713#ifdef SH_ENCRYPT
714 TPT(( 0, FIL__, __LINE__, _("msg=<Receive encrypted.>\n")));
715#else
716 TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
717#endif
718 i = sh_forward_receive_intern (mysocket, protocol, micro,
719 msgbuf, length, S_TRUE);
720 SL_RETURN(i, _("sh_forward_receive"));
721}
722
723/**************************************************
724 *
725 *
726 * C L I E N T
727 *
728 *
729 ***************************************************/
730
731
732#include <time.h>
733
734static SH_FIFO * fifo = NULL;
735
736static long sh_forward_try (char * errmsg);
737
[27]738static unsigned int ServerPort = SH_DEFAULT_PORT;
[1]739
[27]740int sh_forward_server_port (const char * str)
741{
742 unsigned long l;
743 char * endptr;
744
745 SL_ENTER(_("sh_forward_server_port"));
746
747 l = strtoul (str, &endptr, 0);
748 if (l > 65535 || endptr == str)
749 {
750 SL_RETURN (-1, _("sh_forward_server_port"));
751 }
752 ServerPort = (unsigned int) l;
753 SL_RETURN (0, _("sh_forward_server_port"));
754}
755
[1]756long sh_forward (char * errmsg)
757{
758 static int have_server = GOOD;
759 long status;
760 char * popmsg;
761 static int failed = GOOD;
762
763 SL_ENTER(_("sh_forward"));
764
765 /* --- No log server available. ---
766 */
767 if (have_server == GOOD && sh.srvexport.name[0] == '\0')
768 {
769 have_server = BAD;
770 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NONAME);
771 SL_RETURN (-1, _("sh_forward"));
772 }
773 else if (have_server == BAD)
774 {
775 SL_RETURN (-1, _("sh_forward"));
776 }
777
778 /* --- Allocate fifo. ---
779 */
780 if (fifo == NULL)
781 {
782 fifo = SH_ALLOC(sizeof(SH_FIFO));
783 fifo_init(fifo);
784 }
785
786 /* --- Check for messages on the queue, and send them first. ---
787 */
788 while (NULL != (popmsg = pop_list(fifo)) )
789 {
790 status = sh_forward_try (popmsg);
791 if (status != 0)
792 {
793 (void) push_tail_list (fifo, popmsg);
794 SH_FREE(popmsg);
795 if (SH_FIFO_MAX == push_list (fifo, errmsg))
796 {
797 SL_RETURN (-2, _("sh_forward"));
798 }
799 SL_RETURN (-1, _("sh_forward"));
800 }
801 SH_FREE(popmsg);
802 }
803
804 /* --- Now send the error message. ---
805 */
806 status = sh_forward_try (errmsg);
807 if (status != 0)
808 {
809 if (failed == GOOD)
810 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
811 _("log server"),
812 sh.srvexport.name);
813 failed = BAD;
814 if (SH_FIFO_MAX == push_list (fifo, errmsg)) /* push message on stack */
815 {
816 SL_RETURN (-2, _("sh_forward"));
817 }
818 SL_RETURN (-1, _("sh_forward"));
819 }
820
821 failed = GOOD;
822 SL_RETURN (0, _("sh_forward"));
823}
824
825static long sh_forward_try_impl (char * errmsg, char what);
826
827static long sh_forward_try (char * errmsg)
828{
829 long i;
830 SL_ENTER(_("sh_forward_try"));
831 i = sh_forward_try_impl (errmsg, (char)SH_PROTO_MSG);
832 SL_RETURN(i, _("sh_forward_try"));
833}
834
835long sh_forward_req_file (char * file)
836{
837 long i;
838 char tmp_file[8];
839 SL_ENTER(_("sh_forward_req_file"));
840 (void) sl_strlcpy(tmp_file, file, 8);
841 i = sh_forward_try_impl (tmp_file, (char)SH_PROTO_BIG);
842 SL_RETURN(i, _("sh_forward_req_file"));
843}
844
845static long sh_forward_try_impl (char * errmsg, char what)
846{
847 static int initialized = BAD;
848 static int conn_state = GOOD;
849 int sockfd;
850 int flag_err;
851 char * answer;
852
853 unsigned char theProto;
854
855 char hash[KEY_LEN+1];
856 size_t len;
857 char * buffer;
858#ifdef SH_ENCRYPT_2
859 size_t pos; /* for the server command */
860#endif
861 char head_u[5];
862
863 char nsrv[KEY_LEN+1];
864 char nclt[KEY_LEN+1];
865 SL_TICKET sfd = -1;
866 int transfercount;
867
868 char foo_M1[KEY_LEN+1];
869 UINT32 ticks;
870
871 char error_msg[256];
872 char error_call[SH_MINIBUF];
873 int error_num = 0;
874
875#ifdef USE_SRP_PROTOCOL
876 char u_real[SH_CHALLENGE_SIZE];
877 char * foo_A;
878 char * foo_Sc;
879 char * M;
880#else
881 char nounce[KEY_LEN+1];
882 char temp[2*KEY_LEN+1];
883 char nonce_u[KEY_LEN+1];
884#endif
885
886#ifdef SH_ENCRYPT
887 int err_num;
[132]888 char expbuf[SH_ERRBUF_SIZE];
[1]889#endif
890
891 static time_t time_now = 1200;
892 static time_t time_last = 0;
893
894 static time_t timeout_val = 1;
[133]895 char hashbuf[KEYBUF_SIZE];
896 char sigbuf[KEYBUF_SIZE];
[1]897
898 SL_ENTER(_("sh_forward_try_impl"));
899
900 /* --- No message to transmit. ---
901 */
902 if (errmsg == NULL && initialized == GOOD)
903 SL_RETURN( 0, _("sh_forward_try_impl"));
904
905 /* --- Connection in bad state. ---
906 */
907 if (initialized == BAD || conn_state == BAD)
908 {
909 timeout_val =
910 (time_t)((timeout_val > TIMEOUT_CON) ? TIMEOUT_CON : timeout_val);
911
912 /* --- Retry bad attempt only after some time. ---
913 */
914 time_now = time (NULL);
915 if ((time_now - time_last) < timeout_val)
916 {
917 TPT(( 0, FIL__, __LINE__, _("msg=<Within deadtime, no retry.>\n")));
918 SL_RETURN( (-1), _("sh_forward_try_impl"));
919 }
920 TPT(( 0, FIL__, __LINE__, _("msg=<Retry.>\n")));
921 }
922 time_last = time (NULL);
923
924
925 /* --- Try to connect to log server. ---
926 */
927 error_call[0] = '\0';
928
929 sockfd = connect_port_2 (sh.srvexport.name, sh.srvexport.alt,
[27]930 ServerPort,
[1]931 error_call, &error_num, error_msg, 256);
932
933 if (sockfd < 0)
934 {
935 conn_state = BAD;
936 timeout_val *= 2;
937 sh_error_handle ((-1), FIL__, __LINE__, error_num,
938 MSG_E_NET, error_msg, error_call,
939 _("export"), sh.srvexport.name);
940 SL_RETURN( (-1), _("sh_forward_try_impl"));
941 }
942
943 conn_state = GOOD;
944
945 /*************************
946 *
947 * initialization
948 *
949 */
950
951 flag_err = 0;
952 answer = SH_ALLOC(512);
953 MLOCK(answer, 512);
954
955
956#ifndef USE_SRP_PROTOCOL
957
958 /**************************************************
959 *
960 * --- challenge/response authentication ---
961 *
962 **************************************************/
963
964 if (initialized == BAD)
965 {
966 theProto = (unsigned char) SH_PROTO_SRP;
967
968 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: entry>\n")));
969
970 (void) sl_strlcpy (answer, sh.host.name, 512);
971
972 flag_err = sh_forward_send (sockfd, (char) theProto, _("SALT"),
973 answer, (unsigned long)sl_strlen(answer));
974
975 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent SALT, flag_err = %d>\n"),
976 flag_err));
977
978 /* get nonce from server
979 */
980 if (flag_err == 0)
981 {
982 flag_err = (int) sh_forward_receive (sockfd, (char)theProto, head_u,
983 answer, 511);
984 flag_err = (flag_err < 0) ? flag_err : 0;
985 TPT(( 0, FIL__, __LINE__,
986 _("msg=<c/r: rcvt nonce, flag_err = %d>\n"),
987 flag_err));
988 }
989
990 /* entry point for jump from message forward if session key must
991 * be re-initialized
992 */
993 initBlock:
994
995 if (0 == check_request (head_u, _("INIT")) &&
996 flag_err == 0 &&
997 sl_strlen(answer) > KEY_LEN )
998 (void) sl_strlcpy(nounce, &answer[KEY_LEN], KEY_LEN+1);
999 else
1000 flag_err = (-1);
1001
1002 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: rcvt INIT, flag_err = %d>\n"),
1003 flag_err));
1004
1005 /* verify random nonce v from server H(v, P)v
1006 */
1007 sh_passwd (nounce, NULL, NULL, temp);
1008 if ( 0 != sl_strncmp(temp, answer, KEY_LEN))
1009 flag_err = (-1);
1010
1011 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: vrfy nonce, flag_err = %d>\n"),
1012 flag_err));
1013
1014
1015 /* --- Create own nonce. ---
1016 */
[137]1017 ticks = (UINT32) taus_get ();
1018
[1]1019 (void) sl_strlcpy(nonce_u,
1020 sh_tiger_hash((char *) &ticks,
1021 TIGER_DATA,
[133]1022 (unsigned long)sizeof(UINT32),
1023 hashbuf, sizeof(hashbuf)),
[1]1024 KEY_LEN+1);
1025
1026 /* --- Form the message H(H(u,v),P)u ---
1027 */
1028 (void) sl_strlcpy(temp, nonce_u, 2*KEY_LEN+1);
1029 (void) sl_strlcat(temp, nounce, 2*KEY_LEN+1);
1030 (void) sl_strlcpy(temp,
1031 sh_tiger_hash(temp,
1032 TIGER_DATA,
[133]1033 (unsigned long)sl_strlen(temp),
1034 hashbuf, sizeof(hashbuf)),
[1]1035 KEY_LEN+1);
1036 sh_passwd (temp, NULL, NULL, foo_M1);
1037 (void) sl_strlcpy(temp, foo_M1, 2*KEY_LEN+1);
1038 (void) sl_strlcat(temp, nonce_u, 2*KEY_LEN+1);
1039
1040 /* --- Send it to server. ---
1041 */
1042 if (flag_err == 0)
1043 {
1044 flag_err = (int) sh_forward_send (sockfd,
1045 (char)(theProto|SH_PROTO_SRP),
1046 _("PASS"), temp,
1047 (unsigned long)sl_strlen(temp));
1048 TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent PASS, flag_err = %d>\n"),
1049 flag_err));
1050 }
1051
1052 if (flag_err == 0)
1053 {
1054 flag_err = (int)sh_forward_receive (sockfd,
1055 (char)(theProto|SH_PROTO_SRP),
1056 head_u, answer, 511);
1057 sh_passwd (nounce, NULL, nonce_u, foo_M1);
1058 (void) sl_strlcpy (skey->session, foo_M1, KEY_LEN+1);
1059#ifdef SH_ENCRYPT
1060 err_num = makeKey(&(skey->keyInstE),
1061 (RIJ_BYTE)DIR_ENCRYPT, 192, skey->session);
1062 if (err_num < 0)
1063 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]1064 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]1065 _("sh_forward_try_impl: makeKey"));
1066
1067 err_num = makeKey(&(skey->keyInstD),
1068 (RIJ_BYTE)DIR_DECRYPT, 192, skey->session);
1069 if (err_num < 0)
1070 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]1071 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]1072 _("sh_forward_try_impl: make_key"));
1073#endif
1074 initialized = GOOD;
1075 }
1076
1077 if (initialized == BAD)
1078 {
1079 timeout_val *= 2;
1080 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
[34]1081 memset(answer, 0, 512);
[1]1082 MUNLOCK(answer, 512);
1083 SH_FREE(answer);
1084 SL_RETURN( (-1), _("sh_forward_try_impl"));
1085 }
1086 else
1087 {
1088 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
1089 }
1090 }
1091
1092#else
1093
1094
1095 /* This is the SRP authenticated key exchange protocol.
1096 * Produces a session key skey->session.
1097 */
1098 if (initialized == BAD)
1099 {
1100 TPT(( 0, FIL__, __LINE__, _("msg=<srp: entry>\n")));
1101
1102 theProto = SH_PROTO_SRP;
1103
1104 sl_strlcpy (answer, sh.host.name, 512);
1105 flag_err = sh_forward_send (sockfd, theProto, _("SALT "),
1106 answer, sl_strlen(answer));
1107
1108 TPT(( 0, FIL__, __LINE__, _("msg=<srp: sent SALT, flag_err = %d>\n"),
1109 flag_err));
1110
1111 if (flag_err == 0)
1112 {
1113 flag_err = sh_forward_receive (sockfd, theProto, head_u,
1114 answer, 511);
1115 flag_err = (flag_err < 0) ? flag_err : 0;
1116 TPT(( 0, FIL__, __LINE__,
1117 _("msg=<srp: rcvt nonce, flag_err = %d>\n"),
1118 flag_err));
1119 }
1120
1121 /* Entry point for jump from message forward if session key must
1122 * be re-initialized.
1123 */
1124 initBlock:
1125 TPT(( 0, FIL__, __LINE__, _("msg=<srp: INIT>\n")));
1126
1127 if (flag_err == 0 &&
1128 (0 == check_request (head_u, _("INIT"))))
1129 {
1130 if (0 != sh_srp_init())
1131 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EBGN);
1132 else /* if (0 == sh_srp_init()) */
1133 {
1134 TPT(( 0, FIL__, __LINE__, _("msg=<srp: bignum initialized>\n")));
1135
1136 sh_srp_x (answer, NULL); /* x password */
1137 sh_srp_make_a (); /* a random number */
1138 foo_A = sh_srp_A(); /* g^a */
1139
1140 TPT(( 0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), foo_A));
1141
1142 if (foo_A == NULL)
1143 flag_err = (-1);
1144
1145 if (flag_err == 0)
1146 flag_err = sh_forward_send (sockfd,
1147 (theProto|SH_PROTO_SRP),
1148 _("PC01"),
1149 foo_A, sl_strlen(foo_A)+1);
1150 if (flag_err == 0)
1151 {
1152 flag_err = sh_forward_receive (sockfd,
1153 (theProto|SH_PROTO_SRP),
1154 head_u,
1155 answer, 511);
1156 flag_err = (flag_err < 0) ? flag_err : 0;
1157 TPT(( 0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), answer));
1158 TPT(( 0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), head_u[0], head_u[1], head_u[2], head_u[3]));
1159 }
1160
1161 /* u nounce */
1162 /* B answer */
1163 /* S = (B-g^x)^(a+ux) */
1164
1165 if (flag_err == 0)
1166 {
1167 if (0 != sh_srp_check_zero (answer))
1168 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EZERO);
1169 else /* if (0 != sh_srp_check_zero (answer)) */
1170 {
[133]1171 sl_strlcpy(u_real, sh_tiger_hash(head_u, TIGER_DATA, 4,
1172 hashbuf, sizeof(hashbuf)),
[1]1173 SH_CHALLENGE_SIZE);
1174 foo_Sc = sh_srp_S_c (u_real, answer);
1175
1176 TPT(( 0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
1177 u_real));
1178 TPT(( 0, FIL__, __LINE__, _("msg=<srp:Sc = %s>\n"),
1179 foo_Sc));
1180
1181 /* --- Now send H(A,B,H(Sc)) and check. ---
1182 */
1183 if (foo_Sc != NULL)
1184 {
[133]1185 sh_srp_M(foo_A,
1186 answer,
1187 sh_tiger_hash(foo_Sc,
1188 TIGER_DATA,
1189 sl_strlen(foo_Sc),
1190 hashbuf, sizeof(hashbuf)),
1191 foo_M1, KEY_LEN+1);
[1]1192
[133]1193
[1]1194 TPT(( 0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),
1195 foo_M1));
1196
1197 flag_err = sh_forward_send(sockfd,
1198 (theProto|SH_PROTO_SRP),
1199 _("PC02"),
1200 foo_M1, KEY_LEN+1);
1201 }
1202 else
1203 {
1204 flag_err = (-1);
1205 }
1206
1207 if (flag_err == 0)
1208 {
1209 flag_err =sh_forward_receive(sockfd,
1210 (theProto|SH_PROTO_SRP),
1211 head_u,
1212 answer, 511);
1213 flag_err = (flag_err < 0) ? flag_err : 0;
1214 TPT(( 0, FIL__, __LINE__, _("msg=<srp: M = %s>\n"),
1215 answer));
1216 }
1217
1218 if (flag_err == 0 &&
1219 (0 == check_request (head_u, _("PARP"))))
1220 {
1221 /* ------ verify M2 = H(A, M1, K) --------
1222 */
[133]1223 char M_buf[KEY_LEN+1];
[1]1224 M = sh_srp_M (foo_A, foo_M1,
1225 sh_tiger_hash(foo_Sc,
1226 TIGER_DATA,
[133]1227 sl_strlen(foo_Sc),
1228 hashbuf, sizeof(hashbuf)),
1229 M_buf, sizeof(M_buf)
1230 );
[1]1231 if (M != NULL &&
1232 0 == sl_strncmp (answer, M, KEY_LEN+1))
1233 {
1234 sl_strlcpy (skey->session,
1235 sh_tiger_hash(foo_Sc,
1236 TIGER_DATA,
[133]1237 sl_strlen(foo_Sc),
1238 hashbuf, sizeof(hashbuf)),
[1]1239 KEY_LEN+1);
1240 TPT(( 0, FIL__, __LINE__,
1241 _("msg=<srp: Key = %s>\n"),
1242 skey->session));
1243
1244#ifdef SH_ENCRYPT
1245 err_num = makeKey(&(skey->keyInstE),
1246 DIR_ENCRYPT,
1247 192, skey->session);
1248 if (err_num < 0)
1249 sh_error_handle((-1), FIL__, __LINE__, -1,
1250 MSG_E_SUBGEN,
[132]1251 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]1252 _("sh_forward_try_impl: makeKey"));
1253 err_num = makeKey(&(skey->keyInstD),
1254 DIR_DECRYPT,
1255 192, skey->session);
1256 if (err_num < 0)
1257 sh_error_handle((-1), FIL__, __LINE__, -1,
1258 MSG_E_SUBGEN,
[132]1259 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]1260 _("sh_forward_try_impl: makeKey"));
1261#endif
1262 initialized = GOOD;
1263 }
1264 }
1265 if (foo_Sc != NULL)
1266 SH_FREE(foo_Sc);
1267 }
1268 }
1269 if (foo_A != NULL)
1270 SH_FREE(foo_A);
1271 sh_srp_exit();
1272 }
1273 }
1274
1275 if (initialized == BAD)
1276 {
1277 timeout_val *= 2;
1278 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
[34]1279 memset(answer, '\0', 512);
[1]1280 MUNLOCK(answer, 512);
1281 SH_FREE(answer);
1282 SL_RETURN( (-1), _("sh_forward_try_impl"));
1283 }
1284 else
1285 {
[12]1286 if (flag_err_info == SL_TRUE)
1287 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
[1]1288 }
1289 }
1290
1291#endif
1292
1293 /* no message, just session key negotiated
1294 */
1295 if (errmsg == NULL)
1296 {
1297 timeout_val = 1;
[34]1298 memset(answer, 0, 512);
[1]1299 MUNLOCK(answer, 512);
1300 SH_FREE(answer);
1301 TPT(( 0, FIL__, __LINE__, _("msg=<No message.>\n")));
1302 SL_RETURN( (0), _("sh_forward_try_impl"));
1303 }
1304 else if (what == (char)SH_PROTO_BIG)
1305 {
1306 MUNLOCK(answer, 512);
1307 SH_FREE (answer);
1308 answer = SH_ALLOC(TRANS_BYTES + 256);
1309 MLOCK(answer, TRANS_BYTES + 256);
1310 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer.>\n")));
1311 }
1312
1313
1314 (void) sl_strlcpy (answer, sh_util_siggen(skey->session,
1315 sh.host.name,
[133]1316 sl_strlen(sh.host.name),
1317 sigbuf, sizeof(sigbuf)),
[1]1318 KEY_LEN+1);
1319 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"), sh.host.name));
1320 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"), skey->session));
1321 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), answer));
1322
1323
1324 (void) sl_strlcat (answer, sh.host.name, 512);
1325
1326 TPT((0, FIL__, __LINE__, _("msg=<mesg %s>\n"), answer));
1327
1328 /***********************************************
1329 *
1330 * send the message
1331 *
1332 */
1333
1334 if (what == (char) SH_PROTO_MSG)
1335 {
1336 theProto = (unsigned char)SH_PROTO_MSG;
1337
1338 /* say HELO
1339 */
1340
1341 flag_err = sh_forward_send (sockfd,
1342 (char)theProto, _("HELO"),
1343 answer,
1344 (unsigned long)sl_strlen(answer));
1345 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1346 answer, flag_err));
1347 if (flag_err == 0)
1348 {
1349 /* --- Get challenge. ---
1350 */
1351 flag_err = (int) sh_forward_receive (sockfd,
1352 (char)SH_PROTO_MSG, head_u,
1353 answer, 255);
1354 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s, u %s, status %d.>\n"),
1355 answer, hu_trans(head_u), flag_err));
1356 flag_err = (flag_err < 0) ? flag_err : 0;
1357
1358 if (flag_err == 0)
1359 {
1360
1361 /* --- Re-negotiate key. ---
1362 */
1363 if (0 == check_request_nerr(head_u, _("INIT")))
1364 {
1365 flag_err = 0;
1366 initialized = BAD;
1367 goto initBlock;
1368 }
1369
1370 else if (0 == check_request(head_u, _("TALK")))
1371 {
1372
1373 /* --- Save the challenge. ---
1374 */
1375 (void) sl_strlcpy(nsrv, answer, KEY_LEN + 1);
1376
1377 /* --- Hash(msg,challenge,sessionkey). ---
1378 */
1379 len = sl_strlen(errmsg) + sl_strlen(answer)
1380 + KEY_LEN + 1;
1381 len = (size_t)((len < 256) ? 256 : len);
1382 buffer = SH_ALLOC(len);
1383 MLOCK(buffer, len);
1384 (void) sl_strlcpy(buffer, errmsg, len);
1385 (void) sl_strlcat(buffer, answer, len);
1386 (void) sl_strlcpy(hash,
1387 sh_util_siggen (skey->session,
1388 buffer,
[133]1389 sl_strlen(buffer),
1390 sigbuf, sizeof(sigbuf)),
[1]1391 KEY_LEN+1);
1392 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1393 sh_util_siggen(skey->session, buffer,
[133]1394 sl_strlen(buffer), sigbuf, sizeof(sigbuf))));
[1]1395
1396 (void) sl_strlcpy(buffer, errmsg, len);
1397 (void) sl_strlcat(buffer, hash, len);
1398
1399 flag_err =
1400 sh_forward_send_crypt (sockfd,
1401#ifdef SH_ENCRYPT
1402#ifdef SH_ENCRYPT_2
1403 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_EN2),
1404#else
1405 (char)(SH_PROTO_MSG|SH_PROTO_ENC),
1406#endif
1407#else
1408 (char)(SH_PROTO_MSG),
1409#endif
1410 _("MESG"),
1411 buffer,
1412 (unsigned long)(sl_strlen(buffer)+1));
1413 TPT(( 0, FIL__, __LINE__,
1414 _("msg=<Sent %s, status %d.>\n"),
1415 answer, flag_err));
1416
1417 /* --- Get confirmation. ---
1418 */
1419 if (flag_err == 0)
1420 {
1421 flag_err = (int)
1422 sh_forward_receive_crypt (sockfd,
1423#ifdef SH_ENCRYPT
1424#ifdef SH_ENCRYPT_2
1425 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_EN2|SH_PROTO_END),
1426#else
1427 (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_END),
1428#endif
1429#else
1430 (char)(SH_PROTO_MSG|SH_PROTO_END),
1431#endif
1432 head_u,
1433 answer, 255);
1434 TPT(( 0, FIL__, __LINE__,
1435 _("msg=<Rcvt %s, u %s, status %d.>\n"),
1436 answer, hu_trans(head_u), flag_err));
1437 flag_err = (flag_err < 0) ? flag_err : 0;
1438 }
1439
1440
1441 /* --- Check confirmation. ---
1442 */
1443 if (flag_err == 0)
1444 {
1445 /* CLIENT CONF RECV
1446 *
1447 * first KEY_LEN bytes must be
1448 * sig(skey->session (errmsg nsrv))
1449 *
1450 */
1451 (void) sl_strlcpy(buffer, errmsg, len);
1452 (void) sl_strlcat(buffer, nsrv, len);
1453 flag_err = sl_strncmp(answer,
1454 sh_util_siggen(skey->session,
1455 buffer,
[133]1456 sl_strlen(buffer),
1457 sigbuf, sizeof(sigbuf)),
[1]1458 KEY_LEN);
1459 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1460 sh_util_siggen(skey->session, buffer,
[133]1461 sl_strlen(buffer), sigbuf, sizeof(sigbuf))));
[1]1462
1463 if (flag_err != 0)
1464 {
1465#ifdef ENOMSG
1466 flag_err = ENOMSG;
1467#else
1468 flag_err = EIO;
1469#endif
1470 sh_error_handle((-1), FIL__, __LINE__, flag_err,
1471 MSG_TCP_NOCONF);
1472 }
1473 else
1474 {
1475#ifdef SH_ENCRYPT_2
1476 /* --- SERVER CMD --- */
1477 if (answer[KEY_LEN] != '\0' &&
1478 sl_strlen(answer) > (2*KEY_LEN))
1479 {
1480 pos = sl_strlen(answer) - (2*KEY_LEN);
1481 /*
1482 * buffer is >= 256
1483 * answer has <= 255 bytes
1484 */
1485 (void) sl_strlcpy(buffer, &answer[KEY_LEN],
1486 pos+1);
1487 flag_err =
1488 sl_strncmp(&answer[KEY_LEN+pos],
1489 sh_util_siggen(skey->session,
1490 buffer,
[133]1491 pos,
1492 sigbuf, sizeof(sigbuf)),
[1]1493 KEY_LEN);
1494
1495 TPT((0, FIL__, __LINE__,
1496 _("CONF RECV <%d> <%s>\n"),
1497 flag_err, &answer[KEY_LEN]));
1498
1499 if (flag_err != 0) {
1500 sh_error_handle((-1), FIL__, __LINE__,
1501 flag_err,
1502 MSG_TCP_NOCONF);
[27]1503 }
1504#ifdef SH_WITH_CLIENT
1505 else {
[1]1506 sh_socket_server_cmd(buffer);
1507 }
[27]1508#endif
[1]1509 flag_err = 0;
1510
1511 } else {
1512
1513 TPT((0, FIL__, __LINE__,
1514 _("CONF RECV <0> <[null]>\n")));
1515
1516 }
1517 /* --- SERVER CMD END --- */
1518#endif
[12]1519 if (flag_err_debug == SL_TRUE)
1520 sh_error_handle((-1), FIL__, __LINE__, 0,
1521 MSG_TCP_CONF);
[1]1522 }
1523 }
1524
1525 memset(buffer, 0, len);
1526 MUNLOCK(buffer, len);
1527 SH_FREE(buffer);
1528 }
1529 else
1530 {
1531 /* --- Unexpected reply from server. ---
1532 */
1533 sh_error_handle((-1), FIL__, __LINE__, 0,
1534 MSG_TCP_UNEXP);
1535 flag_err = (-1);
1536 }
1537 }
1538 }
1539 }
1540
1541
1542 else if (what == (char)SH_PROTO_BIG)
1543 {
1544 theProto = (unsigned char) SH_PROTO_BIG;
1545
1546 /* --- Say HELO ---
1547 */
1548 flag_err = sh_forward_send (sockfd, (char) theProto, _("HELO"),
1549 answer, (unsigned long)sl_strlen(answer));
1550 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1551 answer, flag_err));
1552
1553 if (flag_err == 0)
1554 {
1555 /* --- Get NSRV. ---
1556 */
1557 flag_err = (int) sh_forward_receive (sockfd,
1558 (char)SH_PROTO_BIG, head_u,
1559 answer, 255);
1560 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s, u %s, status %d.>\n"),
1561 answer, hu_trans(head_u), flag_err));
1562 flag_err = (flag_err < 0) ? flag_err : 0;
1563 }
1564
1565 if (flag_err == 0)
1566 {
1567
1568 /* --- Re-negotiate key. ---
1569 */
1570 if (0 == check_request_nerr(head_u, _("INIT")))
1571 {
1572 flag_err = 0;
1573 initialized = BAD;
1574 goto initBlock;
1575 }
1576
1577
1578 else if (0 == check_request(head_u, _("NSRV")))
1579 {
1580#ifdef SH_ENCRYPT
1581 /* --- Set encryption flag. ---
1582 */
1583#ifdef SH_ENCRYPT_2
1584 theProto =
1585 (unsigned char)(SH_PROTO_BIG | SH_PROTO_ENC | SH_PROTO_EN2);
1586#else
1587 theProto = (unsigned char)(SH_PROTO_BIG | SH_PROTO_ENC);
1588#endif
1589#endif
1590
1591 (void) sl_strlcpy(nsrv, answer, KEY_LEN+1);
1592
1593 /* --- Generate a nonce. ---
1594 */
[137]1595 ticks = (UINT32) taus_get ();
[1]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
[137]1899 val[0] = taus_get ();
1900 val[1] = taus_get ();
[1]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 */
[170]2222void sh_forward_mark_dead (void)
[1]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 */
[170]2240void sh_forward_clean_tree (void)
[1]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 */
[170]2501static int client_time_check(void)
[1]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 }
2647 }
2648 if (he == NULL || *p == NULL)
2649 {
2650 sl_strlcpy(tmp_peer_IP,
2651 inet_ntoa (*(struct in_addr *) &(addr_peer.sin_addr)),
2652 16);
2653 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
2654 claim, h_peer, tmp_peer_IP);
2655 SL_RETURN ((0), _("check_addr"));
2656 }
2657 }
2658
2659
2660 if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
2661 {
2662 SL_RETURN ((0), _("check_addr"));
2663 }
2664 else
2665 {
2666 i = 0;
2667 while (he->h_aliases[i] != NULL)
2668 {
2669 if (0 == sl_strcmp(he->h_aliases[i], h_name))
2670 {
2671 flag = 1;
2672 break;
2673 }
2674 ++i;
2675 }
2676 if (flag == 0)
2677 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKUP,
2678 claim, h_peer);
2679 }
2680
2681 SL_RETURN ((0), _("check_addr"));
2682}
2683
2684static int UseSocketPeer = S_FALSE;
2685
[22]2686int set_socket_peer (const char * c)
[1]2687{
2688 return sh_util_flagval(c, &UseSocketPeer);
2689}
2690
2691
2692/* -- Search register. --
2693 */
2694client_t * search_register(sh_conn_t * conn, int pos)
2695{
2696 client_t * this_client;
2697 char peer_ip[16];
2698 char peer_name[MAXHOSTNAMELEN+1];
2699 char * search_string;
2700 struct sockaddr_in peer_addr;
2701 struct hostent * he;
2702 char ** p = NULL;
2703
2704 SL_ENTER(_("search_register"));
2705
2706 if (UseSocketPeer == S_TRUE)
2707 {
2708 peer_addr = conn->addr_peer;
2709 sl_strlcpy(peer_ip,
2710 inet_ntoa (*(struct in_addr *) &(peer_addr.sin_addr)), 16);
2711
2712 /* get canonical name of socket peer
2713 */
2714 he = sh_gethostbyaddr ((char *) &(peer_addr.sin_addr),
2715 sizeof(peer_addr.sin_addr),
2716 AF_INET);
2717
2718 if (he != NULL && he->h_name != NULL)
2719 {
2720 if (0 == sl_strcmp(he->h_name, _("localhost")))
2721 sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
2722 else
2723 sl_strlcpy(peer_name, he->h_name, MAXHOSTNAMELEN + 1);
2724
2725 /* Reverse lookup
2726 */
2727 if (0 != sl_strncmp(peer_ip, _("127."), 4))
2728 {
2729 he = sh_gethostbyname(peer_name);
2730
2731 if (he != NULL)
2732 {
2733 for (p = he->h_addr_list; *p; ++p)
2734 {
2735 if (0 == memcmp (*p, &(peer_addr.sin_addr),
2736 sizeof(peer_addr.sin_addr)))
2737 break;
2738 }
2739 }
2740 if (he == NULL || *p == NULL)
2741 {
2742 /*
2743 sh_error_handle(lookup_err, FIL__, __LINE__, 0,
2744 MSG_TCP_LOOKERS,
2745 conn->buf[pos], peer_name, peer_ip);
2746 */
2747 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2748 }
2749 }
2750 }
2751 else
2752 {
2753 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
2754 }
2755 search_string = peer_name;
2756 }
2757 else
2758 {
2759 search_string = &(conn->buf[pos]);
2760
2761 if (0 != check_addr (search_string, conn->addr_peer))
2762 {
2763 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2764 _("Reverse lookup failed"), search_string);
2765 sh_forward_do_free (conn);
2766 SL_RETURN( NULL, _("search_register"));
2767 }
2768 }
2769
2770 /* ---- search the register -----
2771 */
2772 this_client = zAVLSearch(all_clients, search_string);
2773
2774 if (this_client == NULL)
2775 {
2776 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2777 _("Not in client list"), search_string);
2778 sh_forward_do_free (conn);
2779 SL_RETURN( NULL, _("search_register"));
2780 }
2781 if (this_client->exit_flag == 1)
2782 {
2783 TPT((0, FIL__, __LINE__, _("msg=<this_client->exit_flag == 1>\n")));
2784 this_client->session_key_timer = (time_t) 0;
2785 this_client->session_key[0] = '\0';
2786 this_client->exit_flag = 0;
2787 }
2788 TPT((0, FIL__, __LINE__, _("msg=<search_register: client %s>\n"),
2789 this_client->hostname));
2790 TPT((0, FIL__, __LINE__, _("msg=<search_register: key %s>\n"),
2791 this_client->session_key));
2792 SL_RETURN( this_client, _("search_register"));
2793}
2794
2795
2796/************************************************************************
2797 *
2798 * Here we check the message received, and decide on the answer to send
2799 * (if any). The connection is in CONN_PAUSED state, thus we must:
2800 * (i) define the proper reaction
2801 * (ii) reset to CONN_READING or CONN_WRITING or CONN_FREE
2802 * (iii) eventually reset the connection entry
2803 *
2804 *************************************************************************/
2805static
2806void check_protocol(sh_conn_t * conn, int state)
2807{
2808 client_t * this_client;
2809
2810 char * cmd;
2811
2812 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
2813 char * buffer;
2814
2815 int clt_sev;
2816 char * ptok;
2817
2818 UINT32 ticks;
[22]2819 size_t len;
[1]2820 int i;
2821 char * test;
2822 char u[5] = "OOOO";
2823
2824 SL_TICKET sfd = -1;
2825 char * read_buf = 0;
2826 char * send_buf;
2827 int bytes;
2828
2829#ifdef SH_ENCRYPT
2830 int blkfac;
2831 int rem;
2832 int send_bytes;
2833 int err_num;
[132]2834 char expbuf[SH_ERRBUF_SIZE];
[1]2835#endif
2836
2837
2838#ifdef USE_SRP_PROTOCOL
2839 char * foo_B;
2840 char * foo_Ss;
2841#endif
[133]2842 char hashbuf[KEYBUF_SIZE];
2843 char sigbuf[KEYBUF_SIZE];
[1]2844
2845 SL_ENTER(_("check_protocol"));
2846
2847 /* seed / re-seed the PRNG if required
2848 */
2849 (void) taus_seed();
2850
2851
2852 /* protocols:
2853 * -- (iii) file transfer
2854 * -- (ii) authenticated message transfer
2855 * -- (i) SRP key exchange
2856 */
2857
2858 /* --------- FILE TRANSFER -----------
2859 */
2860 if ( (conn->head[0] & SH_PROTO_SRP) == 0 &&
2861 (conn->head[0] & SH_PROTO_BIG) != 0 /* is set */ )
2862 {
2863
2864 if (state == SH_DO_READ) /* finished reading */
2865 {
2866 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
2867
2868 /* -- Client requests challenge. --
2869 */
2870 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
2871 {
2872
2873 TPT(( 0, FIL__, __LINE__,
2874 _("msg=<File transfer - HELO (1).>\n")));
2875
2876 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN)
2877 {
2878 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
2879 sh_forward_do_free (conn);
2880 SL_RET0(_("check_protocol"));
2881 }
2882
2883 /* ---- search the register -----
2884 */
2885
2886 this_client = search_register (conn, KEY_LEN);
2887 if (this_client == NULL)
2888 SL_RET0(_("check_protocol"));
2889
2890 /* ---- force authentication -----
2891 */
2892
2893 if (this_client->session_key[0] == '\0' ||
2894 (time(NULL) - this_client->session_key_timer)
2895 > (time_t) TIMEOUT_KEY )
2896 {
2897 /* fake an auth request and jump there
2898 */
2899 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
2900 conn->head[3] = 'S';
2901 conn->head[4] = 'A';
2902 conn->head[5] = 'L';
2903 conn->head[6] = 'T';
[12]2904 if (flag_err_info == SL_TRUE)
2905 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
2906 &(conn->buf[KEY_LEN]));
[22]2907 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
2908 /* &(conn->buf[KEY_LEN]) is hostname */
2909 /* may overlap, thus only memmove is correct */
2910 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
[1]2911 this_client->session_key[0] = '\0';
2912 this_client->session_key_timer = (time_t) 1;
2913 goto servInit;
2914 }
2915
2916 /* --- check whether hostname is properly signed ---
2917 */
2918 if (conn->K != NULL)
2919 {
2920 SH_FREE(conn->K);
2921 conn->K = NULL;
2922 }
2923
[34]2924 /* FIXME
2925 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
2926 if (sl_ok_adds(len, KEY_LEN))
2927 len += KEY_LEN;
2928 len = (len < (KEY_LEN+1)) ? (KEY_LEN+1) : len;
2929 */
2930 conn->K = SH_ALLOC(KEY_LEN+1);
2931
[1]2932 sl_strlcpy (conn->K,
2933 sh_util_siggen(this_client->session_key,
2934 &(conn->buf[KEY_LEN]),
[133]2935 sl_strlen(&(conn->buf[KEY_LEN])),
2936 sigbuf, sizeof(sigbuf)),
[1]2937 KEY_LEN+1);
2938 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
2939 &(conn->buf[KEY_LEN])));
2940 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
2941 this_client->session_key));
2942 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
2943 sh_util_siggen(this_client->session_key,
2944 &(conn->buf[KEY_LEN]),
[133]2945 sl_strlen(&(conn->buf[KEY_LEN])),
2946 sigbuf, sizeof(sigbuf))));
[1]2947
2948 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
2949 {
2950 TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf));
2951 TPT((0, FIL__, __LINE__, _("msg=<srv %s>\n"), conn->K));
2952 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2953 _("Signature mismatch"),
2954 &(conn->buf[KEY_LEN]));
2955
2956 this_client->session_key_timer =
2957 time(NULL) - (2*TIMEOUT_KEY);
2958
2959 sh_forward_do_free (conn);
2960 SL_RET0(_("check_protocol"));
2961 }
2962 SH_FREE(conn->K);
2963 conn->K = NULL;
2964
2965 /* --- create and send a nonce ---
2966 */
2967
2968 conn->client_entry = this_client;
2969 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
2970
[137]2971 ticks = (UINT32) taus_get ();
2972
[1]2973 if (conn->K != NULL)
2974 {
2975 SH_FREE(conn->K);
2976 conn->K = NULL;
2977 }
2978 conn->K = SH_ALLOC(KEY_LEN+1);
2979 sl_strlcpy (conn->K,
2980 sh_tiger_hash ((char *) &ticks,
[133]2981 TIGER_DATA, sizeof(UINT32),
2982 hashbuf, sizeof(hashbuf)),
[1]2983 KEY_LEN+1);
2984
2985 TPT((0, FIL__, __LINE__, _("msg=<send nonce>\n")));
2986 sh_forward_prep_send (conn, conn->K, KEY_LEN+1, _("NSRV"),
2987 SH_PROTO_BIG);
2988 }
2989
2990 /* --- Client has send a message. Check state and message. ---
2991 */
2992 else if (0 == check_request_nerr((char *)&(conn->head[3]), _("NCLT")) &&
2993 conn->client_entry != NULL &&
2994 sl_strlen(conn->buf) > KEY_LEN &&
2995 conn->K != NULL)
2996 {
2997
2998 TPT(( 0, FIL__, __LINE__,
2999 _("msg=<File transfer - NCLT (3).>\n")));
3000
3001 /* --- get client nonce and compute hash ---
3002 */
3003 if (conn->A != NULL)
3004 {
3005 SH_FREE(conn->A);
3006 conn->A = NULL;
3007 }
3008 conn->A = SH_ALLOC(3*KEY_LEN+1);
3009 sl_strlcpy (conn->A, conn->K, KEY_LEN+1);
[22]3010 sl_strlcat(conn->A, conn->buf, /* truncate */
[1]3011 2*KEY_LEN+1);
3012 sl_strlcat(conn->A, conn->client_entry->session_key,
3013 3*KEY_LEN+1);
[133]3014 sl_strlcpy (conn->K, sh_tiger_hash(conn->A,TIGER_DATA,3*KEY_LEN,
3015 hashbuf, sizeof(hashbuf)),
[1]3016 KEY_LEN+1);
3017 SH_FREE(conn->A);
3018 conn->A = NULL;
3019
3020
3021#ifdef SH_ENCRYPT
3022 if ((conn->client_entry->encf_flag != 0) &&
3023 ((conn->head[0] & SH_PROTO_ENC) == 0))
3024 {
3025 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3026 _("file download"),
3027#ifdef SH_ENCRYPT_2
3028 _("version2"),
3029#else
3030 _("version1"),
3031#endif
3032 _("none"));
3033 if (sl_strlen(conn->buf) > (KEY_LEN + 5)) {
3034 if (sh_tools_hash_vfy(conn->K, conn->buf, KEY_LEN+5)) {
3035 if (conn->buf[KEY_LEN+4] == conn->head[0]) {
3036 /* conn->client_entry->encf_flag = 0 */ ; /* FIXME */
3037 }
3038 }
3039 }
3040 }
3041 else if ((conn->client_entry->encf_flag != 0) &&
3042 ((conn->head[0] & SH_MASK_ENC) !=
3043 conn->client_entry->encf_flag))
3044 {
3045 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3046 MSG_TCP_MISENC,
3047 _("file download"),
3048#ifdef SH_ENCRYPT_2
3049 _("version2"),
3050#else
3051 _("version1"),
3052#endif
3053 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1")
3054 );
3055 conn->client_entry->encf_flag =
3056 (conn->head[0] & SH_MASK_ENC);
3057 }
3058#else
3059 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3060 {
3061 sh_error_handle((-1), FIL__, __LINE__, 0,
3062 MSG_TCP_MISENC,
3063 _("file download"),
3064 _("none"),
3065 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3066 }
3067#endif
3068
3069
3070 /* ---- K = H(NSRV, NCLT, session_key) -------
3071 */
3072
3073 if (conn->FileName != NULL)
3074 {
3075 SH_FREE(conn->FileName);
3076 conn->FileName = NULL;
3077 }
3078
3079 if (0 == sl_strncmp (_("CONF"), &(conn->buf[KEY_LEN]), 4))
3080 {
3081 strcpy(conn->FileType, _("CONF")); /* known to fit */
3082 conn->FileName = get_client_conf_file(conn->peer,
3083 &(conn->FileLength));
3084 conn->FileSent = 0;
3085 }
3086 else if (0 == sl_strncmp (_("DATA"), &(conn->buf[KEY_LEN]), 4))
3087 {
3088 strcpy(conn->FileType, _("DATA")); /* known to fit */
3089 conn->FileName = get_client_data_file(conn->peer,
3090 &(conn->FileLength));
3091 conn->FileSent = 0;
3092 }
3093 else
3094 {
3095 ptok = sh_util_safe_name(&(conn->buf[KEY_LEN]));
3096 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FFILE,
3097 conn->peer,
3098 ptok);
3099 SH_FREE(ptok);
3100 status_update (conn->client_entry, CLT_FAILED);
3101 sh_forward_do_free (conn);
3102 }
3103
3104 bytes = -1;
3105
3106 if (conn != NULL && conn->FileName != NULL)
3107 {
3108 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3109 if (!SL_ISERROR(sfd))
3110 {
3111 read_buf = SH_ALLOC(TRANS_BYTES);
3112 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3113 sl_close(sfd);
3114 }
3115
3116 else
3117 {
3118 sh_error_handle((-1), FIL__, __LINE__, sfd,
3119 MSG_E_ACCESS,
3120 (long) geteuid(),
3121 conn->FileName);
3122 }
3123 if (bytes >= 0)
3124 {
3125#ifdef SH_ENCRYPT
3126 /* need to send N * B_SIZ bytes
3127 */
3128 blkfac = bytes / B_SIZ;
3129 rem = bytes - (blkfac * B_SIZ);
3130 if (rem != 0)
3131 {
3132 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3133 ++blkfac;
3134 send_bytes = blkfac * B_SIZ;
3135 }
3136 else
3137 send_bytes = bytes;
3138
3139 send_buf = hash_me(conn->K, read_buf,
3140 send_bytes);
3141
3142 sh_forward_prep_send_crypt (conn, send_buf,
3143 send_bytes+KEY_LEN,
3144 _("FILE"),
3145 SH_PROTO_BIG|conn->client_entry->encf_flag);
3146#else
3147 send_buf = hash_me(conn->K, read_buf, bytes);
3148 sh_forward_prep_send_crypt (conn, send_buf,
3149 bytes+KEY_LEN,
3150 _("FILE"), SH_PROTO_BIG);
3151#endif
3152 conn->FileSent += bytes;
3153 if (send_buf != NULL)
3154 {
3155 SH_FREE(send_buf);
3156 }
3157 SH_FREE(read_buf);
3158 }
3159 }
3160
3161 if (conn == NULL || conn->FileName == NULL ||
3162 SL_ISERROR(sfd) || bytes < 0)
3163 {
3164 sh_error_handle((-1), FIL__, __LINE__, sfd, MSG_TCP_NFILE,
3165 conn->peer,
3166 (conn->FileName == NULL) ?
3167 _("(NULL)") : conn->FileName);
3168 status_update (conn->client_entry, CLT_FAILED);
3169 sh_forward_do_free (conn);
3170 }
3171
3172 }
3173
3174 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3175 _("RECV")) &&
3176 conn->client_entry != NULL &&
3177 conn->K != NULL &&
3178 conn->FileName != NULL)
3179 {
3180
3181 TPT(( 0, FIL__, __LINE__,
3182 _("msg=<File transfer - RCVT (5+).>\n")));
3183
3184 if (conn->FileSent == conn->FileLength)
3185 {
3186 send_buf = hash_me(conn->K, conn->peer,
3187 sl_strlen(conn->peer));
3188#ifdef SH_ENCRYPT
3189 sh_forward_prep_send_crypt (conn, send_buf,
3190 sl_strlen(conn->peer)+KEY_LEN,
3191 _("EEOT"),
3192 SH_PROTO_BIG|conn->client_entry->encf_flag);
3193#else
3194 sh_forward_prep_send_crypt (conn, send_buf,
3195 sl_strlen(conn->peer)+KEY_LEN,
3196 _("EEOT"),
3197 SH_PROTO_BIG);
3198#endif
3199 SH_FREE(send_buf);
3200 }
3201 else
3202 {
3203 bytes = -1;
3204 sfd = sl_open_read(conn->FileName, SL_YESPRIV);
3205 if (!SL_ISERROR(sfd))
3206 {
3207 read_buf = SH_ALLOC(TRANS_BYTES);
3208 sl_seek (sfd, (off_t) conn->FileSent);
3209 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
3210 sl_close(sfd);
3211 }
3212 else
3213 {
3214 sh_error_handle((-1), FIL__, __LINE__, sfd,
3215 MSG_E_ACCESS,
3216 (long) geteuid(),
3217 conn->FileName);
3218 }
3219 if (bytes >= 0)
3220 {
3221#ifdef SH_ENCRYPT
3222 /* need to send N * B_SIZ bytes
3223 */
3224 blkfac = bytes / B_SIZ;
3225 rem = bytes - (blkfac * B_SIZ);
3226 if (rem != 0)
3227 {
3228 memset(&read_buf[bytes], '\n', (B_SIZ-rem));
3229 ++blkfac;
3230 send_bytes = blkfac * B_SIZ;
3231 }
3232 else
3233 send_bytes = bytes;
3234
3235 send_buf = hash_me(conn->K, read_buf,
3236 send_bytes);
3237
3238 sh_forward_prep_send_crypt (conn, send_buf,
3239 send_bytes+KEY_LEN,
3240 _("FILE"),
3241 SH_PROTO_BIG|conn->client_entry->encf_flag);
3242#else
3243
3244 send_buf = hash_me(conn->K, read_buf, bytes);
3245 sh_forward_prep_send_crypt (conn, send_buf,
3246 bytes+KEY_LEN,
3247 _("FILE"),
3248 SH_PROTO_BIG);
3249#endif
3250
3251 conn->FileSent += bytes;
3252 SH_FREE(send_buf);
3253 SH_FREE(read_buf);
3254 }
3255 else
3256 {
3257 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NFILE,
3258 conn->peer,
3259 (conn->FileName == NULL) ?
3260 _("(NULL)") : conn->FileName);
3261 status_update (conn->client_entry, CLT_FAILED);
3262 sh_forward_do_free (conn);
3263 }
3264 }
3265 }
3266
3267
3268 else if (0 == check_request_nerr((char *)&(conn->head[3]),
3269 _("EOTE")) &&
3270 conn->client_entry != NULL)
3271 {
3272
3273 TPT(( 0, FIL__, __LINE__,
3274 _("msg=<File transfer - EOTE (7).>\n")));
3275
[12]3276 if (flag_err_info == SL_TRUE)
3277 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKFILE,
3278 conn->peer);
[1]3279
3280 if ((conn->client_entry->status_now != CLT_SUSPEND) &&
3281 (conn->client_entry->status_now != CLT_TOOLONG))
3282 { status_update (conn->client_entry, CLT_FILE); }
3283 else
3284 { conn->client_entry->session_key[0] = '\0'; }
3285 conn->client_entry->last_connect = time (NULL);
3286 sh_forward_do_free (conn);
3287 }
3288
3289
3290 /* client does something unexpected
3291 */
3292 else /* ---- ??? ----- */
3293 {
3294 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3295 1, conn->pass, conn->peer,
3296 '\\', conn->head[3], '\\',conn->head[4],
3297 '\\', conn->head[5], '\\',conn->head[6]);
3298 status_update (conn->client_entry, CLT_FAILED);
3299 sh_forward_do_free (conn);
3300 }
3301 }
3302
3303 else if (state == SH_DO_WRITE) /* finished writing */
3304 {
3305 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - (wait).>\n")));
3306
3307 /* challenge is sent, now wait for message from client
3308 */
3309 conn->headcount = 0;
3310 conn->bytecount = 0;
3311 conn->bytes_to_send = 0;
3312 conn->bytes_to_get = 0;
3313 if (conn->buf != NULL)
3314 {
3315 SH_FREE(conn->buf);
3316 conn->buf = NULL;
3317 }
3318 conn->state = CONN_READING;
3319 }
3320 SL_RET0(_("check_protocol"));
3321 }
3322
3323 /* --------- message exchange -----------
3324 */
3325 if ((conn->head[0] & SH_PROTO_SRP) == 0 &&
3326 (conn->head[0] & SH_PROTO_MSG) != 0 /* is set */ )
3327 {
3328
3329 if (state == SH_DO_READ) /* finished reading */
3330 {
3331
3332 TPT(( 0, FIL__, __LINE__, _("msg=<Message transfer - entry.>\n")));
3333
3334 /* client requests challenge
3335 */
3336 if (0 == check_request_nerr ((char *)&(conn->head[3]), _("HELO")))
3337 {
3338
3339 TPT(( 0, FIL__, __LINE__,
3340 _("msg=<Message transfer - HELO (1).>\n")));
3341
3342 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN )
3343 {
3344 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3345 sh_forward_do_free (conn);
3346 SL_RET0(_("check_protocol"));
3347 }
3348
3349 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3350
3351 /* ---- search the register -----
3352 */
3353 this_client = search_register (conn, KEY_LEN);
3354 if (NULL == this_client)
3355 SL_RET0(_("check_protocol"));
3356
3357 /* ---- force authentication -----
3358 */
3359 if ( (this_client->session_key[0] == '\0') ||
3360 ((time(NULL)-this_client->session_key_timer)
3361 > (time_t) TIMEOUT_KEY)
3362 )
3363 {
3364
3365 /* fake an auth request and jump there
3366 */
3367 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
3368 conn->head[3] = 'S';
3369 conn->head[4] = 'A';
3370 conn->head[5] = 'L';
3371 conn->head[6] = 'T';
[12]3372 if (flag_err_info == SL_TRUE)
3373 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
3374 &(conn->buf[KEY_LEN]));
[22]3375 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
3376 /* &(conn->buf[KEY_LEN]) is hostname */
3377 /* may overlap, thus only memmove is correct */
3378 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
[1]3379 this_client->session_key[0] = '\0';
3380 this_client->session_key_timer = (time_t) 1;
3381
3382 goto servInit;
3383 }
3384
3385 /* check whether hostname is properly signed
3386 */
3387 if (conn->K != NULL)
3388 {
3389 SH_FREE(conn->K);
3390 conn->K = NULL;
3391 }
[34]3392 /* FIXME len = sl_strlen(&(conn->buf[KEY_LEN])) + KEY_LEN + 1; */
3393 conn->K = SH_ALLOC(KEY_LEN + 1);
[1]3394
3395 sl_strlcpy (conn->K,
3396 sh_util_siggen(this_client->session_key,
3397 &(conn->buf[KEY_LEN]),
[133]3398 sl_strlen(&(conn->buf[KEY_LEN])),
3399 sigbuf, sizeof(sigbuf)),
[1]3400 KEY_LEN+1);
3401 TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"),
3402 &(conn->buf[KEY_LEN])));
3403 TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"),
3404 this_client->session_key));
3405 TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), conn->K));
3406
3407 if (0 != sl_strncmp(conn->K, conn->buf, KEY_LEN))
3408 {
3409 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s>\n"), conn->buf));
3410 TPT(( 0, FIL__, __LINE__, _("msg=<Want %s>\n"), conn->K));
3411 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3412 _("Signature mismatch"),
3413 &(conn->buf[KEY_LEN]));
3414
3415 this_client->session_key_timer =
3416 time(NULL) - (2*TIMEOUT_KEY);
3417
3418 sh_forward_do_free (conn);
3419 SL_RET0(_("check_protocol"));
3420 }
3421 SH_FREE(conn->K);
3422 conn->K = NULL;
3423
3424 /* -- create a nonce and send it --
3425 */
3426
3427 conn->client_entry = this_client;
3428 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
3429
[137]3430 ticks = (UINT32) taus_get ();
3431
[1]3432 test = (char *) &ticks;
3433 sh_util_cpylong (conn->challenge, test, 4);
3434 conn->challenge[4] = '\0';
3435 for (i = 0; i < 4; ++i)
3436 if (conn->challenge[i] == '\0')
3437 conn->challenge[i] = 0x01;
3438
3439 sh_forward_prep_send (conn, conn->challenge, 5, _("TALK"),
3440 SH_PROTO_MSG);
3441 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s.>\n"),
3442 hu_trans(conn->challenge)));
3443 }
3444
3445 /* Client has send a message. Check whether we are in proper
3446 * state, and verify message.
3447 */
3448 else if (0 ==
3449 check_request_nerr((char *)&(conn->head[3]), _("MESG")) &&
3450 conn->client_entry != NULL &&
3451 conn->client_entry->session_key[0] != '\0' &&
3452 (len = sl_strlen(conn->buf) - KEY_LEN) > 0 &&
3453 sl_strlen(conn->challenge) == 4)
3454 {
3455 TPT(( 0, FIL__, __LINE__,
3456 _("msg=<Message transfer - MESG (3).>\n")));
3457
3458#ifdef SH_ENCRYPT
3459 if (conn->client_entry->encf_flag == 0) {
3460 conn->client_entry->ency_flag = 0;
3461 }
3462 if ((conn->client_entry->ency_flag != 0) &&
3463 ((conn->head[0] & SH_PROTO_ENC) == 0))
3464 {
3465 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
3466 _("message transfer"),
3467#ifdef SH_ENCRYPT_2
3468 _("version2"),
3469#else
3470 _("version1"),
3471#endif
3472 _("none"));
3473 /* conn->client_entry->ency_flag = 0; */
3474 }
3475 else if ((conn->client_entry->ency_flag != 0) &&
3476 ((conn->head[0] & SH_MASK_ENC) !=
3477 conn->client_entry->ency_flag))
3478 {
3479 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
3480 MSG_TCP_MISENC,
3481 _("message transfer"),
3482#ifdef SH_ENCRYPT_2
3483 _("version2"),
3484#else
3485 _("version1"),
3486#endif
3487 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3488 conn->client_entry->ency_flag =
3489 (conn->head[0] & SH_MASK_ENC);
3490 }
3491#else
3492 if ((conn->head[0] & SH_PROTO_ENC) != 0)
3493 {
3494 sh_error_handle((-1), FIL__, __LINE__, 0,
3495 MSG_TCP_MISENC,
3496 _("message transfer"),
3497 _("none"),
3498 ((conn->head[0] & SH_PROTO_EN2) == SH_PROTO_EN2) ? _("version2") : _("version1"));
3499 }
3500#endif
3501
3502 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
3503 /* get hash from message end, truncate message
3504 */
3505 sl_strlcpy(hash, &(conn->buf[len]), KEY_LEN+1);
3506 conn->buf[len] = '\0';
3507
3508 /* verify hash
3509 */
3510 buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL);
3511 i = sl_strncmp(hash,
3512 sh_util_siggen(conn->client_entry->session_key,
3513 buffer,
[133]3514 sl_strlen(buffer),
3515 sigbuf, sizeof(sigbuf)),
[1]3516 KEY_LEN);
3517 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3518 sh_util_siggen(conn->client_entry->session_key,
3519 buffer,
[133]3520 sl_strlen(buffer),
3521 sigbuf, sizeof(sigbuf))));
[1]3522
3523
3524 if (0 != i)
3525 {
3526 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3527 status_update (conn->client_entry, CLT_FAILED);
3528 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3529 _("Msg signature mismatch"), conn->peer);
3530 conn->client_entry->session_key_timer =
3531 time(NULL) - (2*TIMEOUT_KEY);
3532 sh_forward_do_free (conn);
3533 SL_RET0(_("check_protocol"));
3534 }
3535 else
3536 {
3537 conn->client_entry->last_connect = time (NULL);
3538
3539 if (NULL != sl_strstr(conn->buf, _("EXIT")))
3540 {
3541 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3542 conn->client_entry->exit_flag = 1;
3543 status_update (conn->client_entry, CLT_EXITED);
3544 }
3545 else if (NULL != sl_strstr(conn->buf, _("PANIC")))
3546 {
3547 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3548 status_update (conn->client_entry, CLT_PANIC);
3549 }
3550 else if (NULL != sl_strstr(conn->buf, _("SUSPEND")))
3551 {
3552 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3553 status_update (conn->client_entry, CLT_SUSPEND);
3554 }
3555 else if (NULL != sl_strstr(conn->buf, _("POLICY")))
3556 {
3557 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3558 status_update (conn->client_entry, CLT_POLICY);
3559 }
3560 else if (NULL != sl_strstr(conn->buf,
3561 _("File check completed")))
3562 {
3563 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3564 status_update (conn->client_entry, CLT_CHECK);
3565 }
3566 else if (NULL != sl_strstr(conn->buf, _("START")))
3567 {
3568 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3569 sh_socket_add2reload (conn->client_entry->hostname);
3570 if (conn->client_entry->status_now == CLT_SUSPEND) {
3571 status_update (conn->client_entry, CLT_ILLEGAL);
3572 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3573 conn->peer);
3574 }
3575 else
3576 status_update (conn->client_entry, CLT_STARTED);
3577 }
3578 else
3579 {
3580 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
3581 if (0 != sl_strcmp(conn->buf,
3582 _("Runtime configuration reloaded")))
3583 {
3584 sh_socket_add2reload (conn->client_entry->hostname);
3585 }
3586 status_update (conn->client_entry, CLT_MSG);
3587 }
3588
3589 TPT((0, FIL__, __LINE__, _("msg=<status updated>\n")));
3590 clt_sev = atoi(conn->buf);
3591 clt_class = (-1);
3592 ptok = strchr(conn->buf, '?');
3593 if (ptok != NULL)
3594 {
3595 ++ptok;
3596 if (ptok != NULL && sh.flag.client_class == S_TRUE)
3597 clt_class = atoi(ptok); /* is a global */
3598 ptok = strchr(ptok, '?');
3599 if (ptok != NULL)
3600 ++ptok;
3601 }
3602 if (sh.flag.client_severity == S_FALSE)
3603 clt_sev = (-1);
3604
3605 /* here we expect an xml formatted message, thus we don't
3606 escape xml special chars (flag == 0) */
3607 ptok =
3608 sh_tools_safe_name ((ptok!=NULL) ? ptok : conn->buf, 0);
3609
3610 /* push client name to error routine
3611 */
3612 sh_error_set_peer(sh_strip_domain (conn->peer));
3613 sh_error_handle(clt_sev, FIL__, __LINE__, 0, MSG_TCP_MSG,
3614 sh_strip_domain (conn->peer),
3615 ptok);
3616 sh_error_set_peer(NULL);
3617
3618 TPT((0, FIL__, __LINE__, _("msg=<%s>\n"), ptok));
3619 SH_FREE(ptok);
3620 clt_class = (-1);
3621 }
3622 memset(buffer, '\0', sl_strlen(buffer));
3623 SH_FREE(buffer);
3624
3625 /* SERVER CONF SEND
3626 */
3627 buffer = sh_util_strconcat(conn->buf,
3628 conn->challenge,
3629 NULL);
3630 sl_strlcpy(hash,
3631 sh_util_siggen ( conn->client_entry->session_key,
3632 buffer,
[133]3633 sl_strlen(buffer),
3634 sigbuf, sizeof(sigbuf)),
[1]3635 KEY_LEN+1);
3636
3637 /* --- SERVER CMD --- */
3638 cmd = sh_socket_check (conn->peer);
3639
3640 if (cmd != NULL)
3641 {
3642 /* max cmd size is SH_MAXMSGLEN bytes
3643 */
3644 sl_strlcpy(&hash[KEY_LEN], cmd, SH_MAXMSGLEN);
3645 sl_strlcat(&hash[KEY_LEN],
3646 sh_util_siggen ( conn->client_entry->session_key,
3647 &hash[KEY_LEN],
[133]3648 sl_strlen(&hash[KEY_LEN]),
3649 sigbuf, sizeof(sigbuf)),
[1]3650 SH_MAXMSGLEN+KEY_LEN+1);
3651
3652 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <%s>\n"),
3653 &hash[KEY_LEN]));
3654
3655 } else {
3656
3657 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <[NULL]>\n")));
3658
3659 }
3660 /* --- SERVER CMD END --- */
3661
3662 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
3663 sh_util_siggen(conn->client_entry->session_key,
3664 buffer,
[133]3665 sl_strlen(buffer),
3666 sigbuf, sizeof(sigbuf))));
[1]3667
3668#ifdef SH_ENCRYPT
3669 sh_forward_prep_send_crypt (conn, hash,
3670 sl_strlen(hash) /* KEY_LEN */,
3671 _("CONF"),
3672 SH_PROTO_MSG|SH_PROTO_END|conn->client_entry->ency_flag);
3673#else
3674 sh_forward_prep_send_crypt (conn, hash,
3675 sl_strlen(hash) /* KEY_LEN */,
3676 _("CONF"),
3677 SH_PROTO_MSG|SH_PROTO_END);
3678#endif
3679
3680 memset(buffer, '\0', sl_strlen(buffer));
3681 SH_FREE(buffer);
3682
3683 /* sh_forward_do_free (conn); */
3684 }
3685
3686 /* client does something unexpected
3687 */
3688 else /* ---- ??? ----- */
3689 {
3690 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3691 2, conn->pass, conn->peer,
3692 '\\', conn->head[3], '\\',conn->head[4],
3693 '\\', conn->head[5], '\\',conn->head[6]);
3694 status_update (conn->client_entry, CLT_FAILED);
3695 conn->client_entry->session_key_timer =
3696 time(NULL) - (2*TIMEOUT_KEY);
3697 sh_forward_do_free (conn);
3698 }
3699 }
3700 else if (state == SH_DO_WRITE) /* finished writing */
3701 {
3702 if (0 != (conn->head[0] & SH_PROTO_END))
3703 {
[12]3704 if (flag_err_debug == SL_TRUE)
3705 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKMSG,
3706 sh_strip_domain (conn->peer));
[1]3707 sh_forward_do_free (conn);
3708 SL_RET0(_("check_protocol"));
3709 }
3710
3711 TPT(( 0, FIL__, __LINE__, _("msg=<Msg transfer - (wait).>\n")));
3712
3713 /* challenge is sent, now wait for message from client
3714 */
3715 conn->headcount = 0;
3716 conn->bytecount = 0;
3717 conn->bytes_to_send = 0;
3718 conn->bytes_to_get = 0;
3719 if (conn->buf != NULL)
3720 {
3721 SH_FREE(conn->buf);
3722 conn->buf = NULL;
3723 }
3724 conn->state = CONN_READING;
3725 }
3726 TPT((0, FIL__, __LINE__, _("msg=<return>\n") ));
3727 SL_RET0(_("check_protocol"));
3728 }
3729
3730 /* --------- authentication -----------
3731 */
3732
3733 /* entry point for jump from message forward if session key must
3734 * be re-initialized
3735 */
3736 servInit:
3737
3738 if ( (conn->head[0] & SH_PROTO_SRP) != 0 /* is set */ )
3739 {
3740
3741#ifndef USE_SRP_PROTOCOL
3742
3743 if (state == SH_DO_READ) /* finished reading */
3744 {
3745 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3746
3747 /* first pass -- client request salt
3748 */
3749 if (conn->pass == 1)
3750 {
3751
3752 TPT((0, FIL__, __LINE__,
3753 _("msg=<Authentication - SALT (1).>\n")));
3754
3755 if (conn->buf == NULL || sl_strlen(conn->buf) == 0)
3756 {
3757 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3758 sh_forward_do_free (conn);
3759 SL_RET0(_("check_protocol"));
3760 }
3761
3762
3763 /* search the register
3764 */
3765
3766 this_client = search_register (conn, 0);
3767 if (NULL == this_client)
3768 SL_RET0(_("check_protocol"));
3769
3770
3771 conn->client_entry = this_client;
3772 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
3773
3774 if (0 != check_request_s((char *)&(conn->head[3]),
3775 _("SALT"),conn->peer))
3776 {
3777 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3778 _("No salt requested"), conn->peer);
3779 status_update (conn->client_entry, CLT_FAILED);
3780 conn->client_entry->session_key_timer =
3781 time(NULL) - (2*TIMEOUT_KEY);
3782 sh_forward_do_free (conn);
3783 SL_RET0(_("check_protocol"));
3784 }
3785
3786
3787 /* -- create server nounce v --
3788 */
[137]3789 ticks = (UINT32) taus_get ();
[1]3790
3791 if (conn->A != NULL)
3792 {
3793 SH_FREE(conn->A);
3794 conn->A = NULL;
3795 }
3796 conn->A = SH_ALLOC(KEY_LEN+1);
3797
3798 sl_strlcpy(conn->A,
3799 sh_tiger_hash((char *) &ticks,
[133]3800 TIGER_DATA, sizeof(UINT32),
3801 hashbuf, sizeof(hashbuf)),
[1]3802 KEY_LEN+1);
3803 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
3804
3805 if (conn->M1 != NULL)
3806 {
3807 SH_FREE(conn->M1);
3808 conn->M1 = NULL;
3809 }
3810 conn->M1 = SH_ALLOC(2*KEY_LEN+1);
3811
3812 /* compute hash key H(v(server), P)v(server)
3813 */
3814 sh_passwd (conn->A, conn->client_entry->verifier,
3815 NULL, conn->M1);
3816
3817 sl_strlcat(conn->M1, conn->A, 2*KEY_LEN+1);
3818
3819
3820 /* --- send H(v(server), P)v(server) ----
3821 */
3822 sh_forward_prep_send (conn,
3823 conn->M1,
3824 sl_strlen(conn->M1),
3825 u,
3826 (conn->head[0]|SH_PROTO_SRP));
3827
3828 SH_FREE(conn->M1);
3829 conn->M1 = NULL;
3830 }
3831
3832 /* client -- third pass
3833 * Message is H(H(u,v),P)u
3834 *
3835 * A := v, verifier := H(password),
3836 */
3837 else if (conn->pass == 3 &&
3838 conn->client_entry != NULL)
3839 {
3840
3841 TPT((0, FIL__, __LINE__,
3842 _("msg=<Authentication - PASS (3).>\n")));
3843
3844 if (0 != check_request_s((char *) &(conn->head[3]), _("PASS"),
3845 conn->peer) ||
3846 sl_strlen(conn->buf) <= KEY_LEN ||
3847 conn->A == NULL)
3848 {
3849 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3850 _("Invalid client request"), conn->peer);
3851 status_update (conn->client_entry, CLT_FAILED);
3852 conn->client_entry->session_key_timer =
3853 time(NULL) - (2*TIMEOUT_KEY);
3854 sh_forward_do_free (conn);
3855 SL_RET0(_("check_protocol"));
3856 }
3857
3858 /* store random nonce u from client
3859 */
3860 if (conn->K != NULL)
3861 {
3862 SH_FREE(conn->K);
3863 conn->K = NULL;
3864 }
3865 conn->K = SH_ALLOC(KEY_LEN+1);
3866 sl_strlcpy(conn->K, &(conn->buf[KEY_LEN]), KEY_LEN+1);
3867
3868 /* verify random nonce u from client
3869 */
3870 if (conn->M1 != NULL)
3871 {
3872 SH_FREE(conn->M1);
3873 conn->M1 = NULL;
3874 }
3875 conn->M1 = sh_util_strconcat(conn->K, conn->A, NULL);
3876
3877 TPT((0, FIL__, __LINE__, _("msg=<c/r: K = %s>\n"), conn->K));
3878 TPT((0, FIL__, __LINE__, _("msg=<c/r: A = %s>\n"), conn->A));
3879 TPT((0, FIL__, __LINE__, _("msg=<c/r: M = %s>\n"), conn->M1));
3880
3881 sl_strlcpy(hash, sh_tiger_hash (conn->M1,
3882 TIGER_DATA,
[133]3883 sl_strlen(conn->M1),
3884 hashbuf, sizeof(hashbuf)),
3885 KEY_LEN+1);
[1]3886 sh_passwd (hash, conn->client_entry->verifier, NULL, conn->M1);
3887
3888 TPT((0, FIL__, __LINE__, _("msg=<c/r: H = %s>\n"), hash));
3889 TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1));
3890
3891 if ( 0 != sl_strncmp(conn->M1, conn->buf, KEY_LEN))
3892 {
3893 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
3894 _("Session key mismatch"), conn->peer);
3895 status_update (conn->client_entry, CLT_FAILED);
3896 conn->client_entry->session_key_timer =
3897 time(NULL) - (2*TIMEOUT_KEY);
3898 sh_forward_do_free (conn);
3899 SL_RET0(_("check_protocol"));
3900 }
3901
3902
3903 /* ---- compute hash key H(v, P, u) ----
3904 */
3905
3906 sh_passwd (conn->A, conn->client_entry->verifier, conn->K,
3907 conn->M1);
3908
3909 sl_strlcpy(conn->client_entry->session_key,
3910 conn->M1, KEY_LEN+1);
3911 TPT((0, FIL__, __LINE__, _("msg=<c/r: Key = %s>\n"),
3912 conn->client_entry->session_key));
3913
3914#ifdef SH_ENCRYPT
3915 err_num = makeKey(&(conn->client_entry->keyInstE),
3916 DIR_ENCRYPT, 192,
3917 conn->client_entry->session_key);
3918 if (err_num < 0)
3919 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]3920 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]3921 _("check_protocol: makeKey"));
3922 err_num = makeKey(&(conn->client_entry->keyInstD),
3923 DIR_DECRYPT, 192,
3924 conn->client_entry->session_key);
3925 if (err_num < 0)
3926 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]3927 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]3928 _("check_protocol: makeKey"));
3929#endif
3930
3931 if (conn->K != NULL) SH_FREE (conn->K);
3932 conn->K = NULL;
3933 if (conn->A != NULL) SH_FREE (conn->A);
3934 conn->A = NULL;
3935 if (conn->M1 != NULL) SH_FREE (conn->M1);
3936 conn->M1 = NULL;
3937
3938 /* if (conn->client_entry->status_now == CLT_STARTED */
3939 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
3940 (conn->client_entry->status_now != CLT_EXITED) &&
3941 (conn->client_entry->status_now != CLT_SUSPEND))
3942 && conn->client_entry->session_key_timer > (time_t) 1)
3943 {
3944 status_update (conn->client_entry, CLT_ILLEGAL);
3945 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
3946 conn->peer);
3947 }
3948 else if (conn->client_entry->session_key_timer == (time_t) 0)
3949 {
3950 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NEW,
3951 conn->peer);
3952 if (conn->client_entry->status_now != CLT_SUSPEND)
3953 status_update (conn->client_entry, CLT_STARTED);
3954 }
3955
3956 conn->client_entry->session_key_timer = time (NULL);
3957 conn->client_entry->last_connect = time (NULL);
3958
3959 /* put in read state
3960 */
3961 sh_forward_prep_send (conn,
3962 _("AUTH"),
3963 5,
3964 _("AUTH"),
3965 (conn->head[0]|SH_PROTO_SRP));
3966
3967 }
3968 else
3969 {
3970 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
3971 3, conn->pass, conn->peer,
3972 '\\', conn->head[3], '\\', conn->head[4],
3973 '\\', conn->head[5], '\\', conn->head[6]);
3974 sh_forward_do_free (conn);
3975 }
3976 }
3977
3978#else
3979 /* use SRP */
3980
3981
3982 if (state == SH_DO_READ) /* finished reading */
3983 {
3984
3985 TPT((0, FIL__, __LINE__, _("msg=<Authentication - entry.>\n")));
3986
3987 /* first pass -- client request salt
3988 */
3989 if (conn->pass == 1)
3990 {
3991 TPT((0, FIL__, __LINE__,
3992 _("msg=<Authentication - SALT (1).>\n")));
3993
3994 if (conn->buf == NULL)
3995 {
3996 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
3997 sh_forward_do_free (conn);
3998 SL_RET0(_("check_protocol"));
3999 }
4000
4001 /* search the register
4002 */
4003 this_client = search_register(conn, 0);
4004 if (NULL == this_client)
4005 SL_RET0(_("check_protocol"));
4006
4007 conn->client_entry = this_client;
4008 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
4009
4010 if (0 != check_request_s((char *)&(conn->head[3]), _("SALT"),
4011 conn->peer))
4012 {
4013 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4014 _("No salt requested"), conn->peer);
4015 status_update (conn->client_entry, CLT_FAILED);
4016 conn->client_entry->session_key_timer =
4017 time(NULL) - (2*TIMEOUT_KEY);
4018 sh_forward_do_free (conn);
4019 SL_RET0(_("check_protocol"));
4020 }
4021
4022
4023 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
4024
4025 sh_forward_prep_send (conn,
4026 conn->client_entry->salt,
4027 sl_strlen(conn->client_entry->salt),
4028 u,
4029 (conn->head[0]|SH_PROTO_SRP));
4030 }
4031
4032 /* client has sent A -- third pass
4033 */
4034 else if (conn->pass == 3 &&
4035 conn->client_entry != NULL)
4036 {
4037
4038 TPT((0, FIL__, __LINE__,
4039 _("msg=<Authentication - PC01 (3).>\n")));
4040
4041 if (0 != check_request_s((char *)&(conn->head[3]),_("PC01"),conn->peer)||
4042 conn->buf == NULL
4043 )
4044 {
4045 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4046 _("Invalid client request"), conn->peer);
4047 status_update (conn->client_entry, CLT_FAILED);
4048 conn->client_entry->session_key_timer =
4049 time(NULL) - (2*TIMEOUT_KEY);
4050 sh_forward_do_free (conn);
4051 SL_RET0(_("check_protocol"));
4052 }
4053
4054 if (0 != sh_srp_init())
4055 {
4056 status_update (conn->client_entry, CLT_FAILED);
4057 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4058 MSG_TCP_EBGN);
4059 sh_forward_do_free (conn);
4060 SL_RET0(_("check_protocol"));
4061 }
4062
4063
4064 /* check A, only send B if correct
4065 */
4066 if ( sl_strlen(conn->buf) < SH_BUFSIZE &&
4067 0 == sh_srp_check_zero (conn->buf) )
4068 {
4069 len = sl_strlen(conn->buf)+1;
4070
4071 if (conn->A != NULL)
4072 {
4073 SH_FREE(conn->A);
4074 conn->A = NULL;
4075 }
4076 conn->A = SH_ALLOC(len);
4077 sl_strlcpy (conn->A, conn->buf, len);
4078
4079 /*
4080 * compute B
4081 */
4082 if (0 != sh_srp_make_a ()) /* b random number */
4083 {
4084 status_update (conn->client_entry, CLT_FAILED);
4085
4086 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4087 MSG_TCP_EBGN);
4088 sh_srp_exit();
4089 sh_forward_do_free (conn);
4090 SL_RET0(_("check_protocol"));
4091 }
4092
4093 foo_B = sh_srp_B /* B = v + g^b */
4094 (conn->client_entry->verifier);
4095
4096 if (foo_B == NULL)
4097 {
4098 status_update (conn->client_entry, CLT_FAILED);
4099
4100 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4101 MSG_TCP_EBGN);
4102 sh_srp_exit();
4103 sh_forward_do_free (conn);
4104 SL_RET0(_("check_protocol"));
4105 }
4106
4107 TPT((0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), conn->A));
4108 TPT((0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), foo_B));
4109
4110 /*
4111 * create nonce u
4112 */
[137]4113 ticks = (UINT32) taus_get ();
4114
[1]4115 test = (char *) &ticks;
4116 sh_util_cpylong (u, test, 4); /* u nounce */
4117 u[4] = '\0';
4118 sl_strlcpy(conn->challenge,
[133]4119 sh_tiger_hash(u, TIGER_DATA, 4, hashbuf, sizeof(hashbuf)),
[1]4120 SH_CHALLENGE_SIZE);
4121
4122 TPT((0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), u[0], u[1], u[2], u[3]));
4123 TPT((0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
4124 conn->challenge));
4125
4126 /*
4127 * compute the session key K and M1 = Hash(A,B,K)
4128 */
4129 foo_Ss = sh_srp_S_s (conn->challenge,
4130 conn->A,
4131 conn->client_entry->verifier);
4132 if (foo_Ss == NULL)
4133 {
4134 status_update (conn->client_entry, CLT_FAILED);
4135
4136 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4137 MSG_TCP_EBGN);
4138 sh_srp_exit();
4139 sh_forward_do_free (conn);
4140 SL_RET0(_("check_protocol"));
4141 }
4142
4143 if (conn->K != NULL)
4144 {
4145 SH_FREE(conn->K);
4146 conn->K = NULL;
4147 }
4148 conn->K = SH_ALLOC(KEY_LEN+1);
4149 sl_strlcpy(conn->K,
4150 sh_tiger_hash(foo_Ss, TIGER_DATA,
[133]4151 sl_strlen(foo_Ss),
4152 hashbuf, sizeof(hashbuf)),
[1]4153 KEY_LEN+1);
4154
4155 if (conn->M1 != NULL)
4156 {
4157 SH_FREE(conn->M1);
4158 conn->M1 = NULL;
4159 }
4160 conn->M1 = SH_ALLOC(KEY_LEN+1);
[133]4161 sh_srp_M (conn->A, foo_B, conn->K, conn->M1, KEY_LEN+1);
[1]4162
4163 TPT((0, FIL__, __LINE__, _("msg=<srp:Ss = %s>\n"), foo_Ss));
4164 TPT((0, FIL__, __LINE__, _("msg=<srp: K = %s>\n"), conn->K));
4165 TPT((0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),conn->M1));
4166
4167 /*
4168 * send B
4169 */
4170 sh_forward_prep_send (conn,
4171 foo_B,
4172 sl_strlen(foo_B)+1,
4173 u,
4174 (conn->head[0]|SH_PROTO_SRP));
4175 if (foo_Ss != NULL)
4176 {
4177 SH_FREE(foo_Ss);
4178 foo_Ss = NULL;
4179 }
4180 if (foo_B != NULL)
4181 {
4182 SH_FREE(foo_B);
4183 foo_B = NULL;
4184 }
4185 }
4186 else
4187 {
4188 status_update (conn->client_entry, CLT_FAILED);
4189
4190 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
4191 MSG_TCP_EZERO);
4192 sh_forward_do_free (conn);
4193 }
4194
4195 sh_srp_exit();
4196 }
4197
4198 /* client has sent M1 -- fifth pass
4199 */
4200 else if (conn->pass == 5 &&
4201 conn->client_entry != NULL)
4202 {
4203 TPT((0, FIL__, __LINE__,
4204 _("msg=<Authentication - PC02 (5).>\n")));
4205
4206 /* check that the state is valid
4207 */
4208 if (0 != check_request_s((char *)&(conn->head[3]), _("PC02"),
4209 conn->peer) ||
4210 conn->A == NULL || conn->K == NULL || conn->M1 == NULL)
4211 {
4212 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4213 _("Invalid client request"), conn->peer);
4214 status_update (conn->client_entry, CLT_FAILED);
4215 conn->client_entry->session_key_timer =
4216 time(NULL) - (2*TIMEOUT_KEY);
4217 sh_forward_do_free (conn);
4218 SL_RET0(_("check_protocol"));
4219 }
4220
4221 /* ------ verify M1 = H(A, B, K) -------
4222 * ----- send M2 = H(A, M1, K) -------
4223 */
4224 if (conn->buf != NULL &&
4225 sl_strncmp(conn->buf, conn->M1, KEY_LEN) == 0)
4226 {
4227 /*
4228 * send M2
4229 */
[133]4230 char M_buf[KEY_LEN+1];
[1]4231 sh_forward_prep_send (conn,
[133]4232 sh_srp_M (conn->A, conn->M1, conn->K,
4233 M_buf, sizeof(M_buf)),
[1]4234 KEY_LEN+1,
4235 _("PARP"),
4236 (conn->head[0]|SH_PROTO_SRP));
4237
4238 if (conn->A != NULL) SH_FREE(conn->A); conn->A = NULL;
4239 if (conn->M1 != NULL) SH_FREE(conn->M1); conn->M1 = NULL;
4240 sl_strlcpy(conn->client_entry->session_key,
4241 conn->K, KEY_LEN+1);
4242 TPT((0, FIL__, __LINE__, _("msg=<key %s>\n"),
4243 conn->client_entry->session_key));
4244
4245#ifdef SH_ENCRYPT
4246 err_num = makeKey(&(conn->client_entry->keyInstE),
4247 DIR_ENCRYPT, 192,
4248 conn->client_entry->session_key);
4249 if (err_num < 0)
4250 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]4251 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]4252 _("sh_forward_prep_send_int: makeKey"));
4253 err_num = makeKey(&(conn->client_entry->keyInstD),
4254 DIR_DECRYPT, 192,
4255 conn->client_entry->session_key);
4256 if (err_num < 0)
4257 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]4258 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]4259 _("sh_forward_prep_send_int: makeKey"));
4260#endif
4261
4262 if (conn->K != NULL) SH_FREE(conn->K); conn->K = NULL;
4263
4264 conn->client_entry->last_connect = time (NULL);
4265
4266 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
4267 (conn->client_entry->status_now != CLT_EXITED) &&
4268 (conn->client_entry->status_now != CLT_SUSPEND))
4269 && conn->client_entry->session_key_timer > (time_t) 1)
4270 {
4271 status_update (conn->client_entry, CLT_ILLEGAL);
4272
4273 sh_error_handle((-1), FIL__, __LINE__, 0,
4274 MSG_TCP_ILL,
4275 conn->peer);
4276 }
4277 else if (conn->client_entry->session_key_timer == (time_t) 0)
4278 {
4279 sh_error_handle((-1), FIL__, __LINE__, 0,
4280 MSG_TCP_NEW,
4281 conn->peer);
4282 if (conn->client_entry->status_now != CLT_SUSPEND)
4283 status_update (conn->client_entry, CLT_STARTED);
4284 }
4285 conn->client_entry->session_key_timer = time (NULL);
4286
4287 }
4288 else
4289 {
4290 status_update (conn->client_entry, CLT_FAILED);
4291 conn->client_entry->session_key_timer =
4292 time(NULL) - (2*TIMEOUT_KEY);
4293
4294 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
4295 _("Session key mismatch"), conn->peer);
4296 sh_forward_do_free (conn);
4297 }
4298 }
4299
4300 else
4301 {
4302 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
4303 4, conn->pass, conn->peer,
4304 '\\', conn->head[3], '\\', conn->head[4],
4305 '\\', conn->head[5], '\\', conn->head[6]);
4306 sh_forward_do_free (conn);
4307 }
4308 }
4309
4310#endif
4311
4312 else if (state == SH_DO_WRITE) /* finished writing */
4313 {
4314 TPT((0, FIL__, __LINE__, _("msg=<Authentication -- (wait).>\n")));
4315
4316 conn->headcount = 0;
4317 conn->bytecount = 0;
4318 conn->bytes_to_send = 0;
4319 conn->bytes_to_get = 0;
4320 if (conn->buf != NULL)
4321 {
4322 SH_FREE(conn->buf);
4323 conn->buf = NULL;
4324 }
4325 conn->state = CONN_READING;
4326 }
4327 }
4328 SL_RET0(_("check_protocol"));
4329}
4330
4331
4332/***********************************************************
4333 *
4334 * SERVER RECEIVE FUNCTION
4335 *
4336 ***********************************************************
4337 */
4338int sh_forward_do_read (sh_conn_t * conn)
4339{
4340 unsigned long byteread; /* bytes read */
4341
4342#ifdef SH_ENCRYPT
4343
4344 unsigned long blkfac = 0;
4345 /* unsigned long length2; */
4346 char * p = NULL, * q = NULL;
4347 RIJ_BYTE inBlock[B_SIZ];
4348 RIJ_BYTE outBlock[B_SIZ];
4349 unsigned int j;
4350 cipherInstance cipherInst;
4351 int err_num;
[132]4352 char expbuf[SH_ERRBUF_SIZE];
[1]4353#endif
4354
4355 SL_ENTER(_("sh_forward_do_read"));
4356
4357 if (conn->state == CONN_SENDING)
4358 {
4359 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4360 conn->peer);
4361 SL_RETURN( (-1), _("sh_forward_do_read"));
4362 }
4363
4364 if (conn->headcount < SH_HEADER_SIZE)
4365 {
4366 conn->bytes_to_get = SH_HEADER_SIZE - conn->headcount;
4367 byteread = read (conn->fd, &(conn->head[conn->headcount]),
4368 conn->bytes_to_get);
4369 if (byteread > 0 || errno == EINTR)
4370 {
4371 if (byteread > 0)
4372 conn->headcount += byteread;
4373 if (conn->headcount == SH_HEADER_SIZE)
4374 {
4375 conn->bytes_to_get =
4376 (256 * (unsigned int)conn->head[1] +
4377 (unsigned int)conn->head[2]);
4378 SH_SHOWPROT(conn->head, '<');
4379 conn->bytecount = 0;
4380 }
4381 }
4382 else
4383 {
4384 goto conn_reset;
4385 }
4386 SL_RETURN( (0), _("sh_forward_do_read"));
4387 }
4388
4389
4390 /* limit message size
4391 */
4392 /*
4393 conn->bytes_to_get =
4394 (conn->bytes_to_get > (16*SH_BUFSIZE - 1)) ?
4395 (16*SH_BUFSIZE - 1) : conn->bytes_to_get;
4396 */
4397 conn->bytes_to_get = (conn->bytes_to_get > TRANS_BYTES) ?
4398 TRANS_BYTES : conn->bytes_to_get;
4399
4400 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get > 0)
4401 {
4402 if ((conn->bytecount > 0) && (conn->bytes_to_get > conn->bytecount))
4403 {
4404 /* do nothing */;
4405 }
4406 else
4407 {
4408 if (conn->buf != NULL)
4409 SH_FREE (conn->buf);
[34]4410 conn->buf = SH_ALLOC(conn->bytes_to_get + 1); /* <= TRANS_BYTES+1 */
[1]4411 conn->bytecount = 0;
4412 }
4413
4414 byteread = read (conn->fd, &(conn->buf[conn->bytecount]),
4415 conn->bytes_to_get - conn->bytecount);
4416 if (byteread > 0 || errno == EINTR)
4417 {
4418 if (byteread > 0)
4419 conn->bytecount += byteread;
4420 if (conn->bytecount == conn->bytes_to_get)
4421 {
4422 ++conn->pass;
4423 /* always terminate with NULL - we might use sl_strcmp()
4424 */
4425 conn->buf[conn->bytecount] = '\0';
4426 conn->state = CONN_PAUSE;
4427
4428#ifdef SH_ENCRYPT
4429 if ((conn->head[0] & SH_PROTO_EN2) != 0) /* if encrypted */
4430 {
4431 conn->buf =
4432 sh_tools_revertPack (conn->head, conn->buf,
4433 &(conn->client_entry->keyInstD),
4434 conn->bytecount);
4435 }
4436 else if ((conn->head[0] & SH_PROTO_ENC) != 0) /* if encrypted */
4437 {
4438 /* Decrypt only complete blocks.
4439 * If there is an incomplete block,
4440 * something is wrong anyway.
4441 * Decrypt in place.
4442 */
4443 blkfac = conn->bytecount / B_SIZ;
4444 /* length2 = (B_SIZ * blkfac); */
4445 p = conn->buf;
4446 q = conn->buf;
4447
4448 err_num = cipherInit (&cipherInst, MODE_CBC, NULL);
4449 if (err_num < 0)
4450 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
[132]4451 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]4452 _("sh_forward_do_read: cipherInit"));
4453
4454 for (j = 0; j < blkfac; ++j)
4455 {
4456 memcpy(inBlock, p, B_SIZ);
4457 err_num = blockDecrypt(&cipherInst,
4458 &(conn->client_entry->keyInstD),
4459 inBlock, 128 * BNUM, outBlock);
4460 if (err_num < 0)
4461 sh_error_handle((-1), FIL__, __LINE__, -1,
4462 MSG_E_SUBGEN,
[132]4463 errorExplain(err_num, expbuf, sizeof(expbuf)),
[1]4464 _("sh_forward_do_read: blockDecrypt"));
4465 memcpy(q, outBlock, B_SIZ);
4466 p += 16;
4467 q += 16;
4468 }
4469 }
4470#endif
4471
4472 /* ------ HERE CALL check_protocol(conn) ------- */
4473 check_protocol(conn, SH_DO_READ);
4474 }
4475 }
4476 else
4477 {
4478 goto conn_reset;
4479 }
4480 }
4481
4482 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get == 0)
4483 {
4484 if (conn->buf != NULL)
4485 SH_FREE (conn->buf);
4486 conn->buf = NULL;
4487 conn->bytecount = 0;
4488 ++conn->pass;
4489 conn->state = CONN_PAUSE;
4490 /* fprintf(stderr, "\n**** FIXME null read ****\n\n"); */
4491 /* ------ HERE CALL check_protocol(conn) ------- */
4492 check_protocol(conn, SH_DO_READ);
4493 }
4494
4495 SL_RETURN( (0), _("sh_forward_do_read"));
4496
4497 conn_reset:
4498 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4499 conn->peer);
4500 sh_forward_do_free ( conn );
4501 SL_RETURN( (-1), _("sh_forward_do_read"));
4502}
4503
4504#if !defined(O_NONBLOCK)
4505#if defined(O_NDELAY)
4506#define O_NONBLOCK O_NDELAY
4507#else
4508#define O_NONBLOCK 0
4509#endif
4510#endif
4511
4512/* send to the client
4513 */
4514int sh_forward_do_write (sh_conn_t * conn)
4515{
4516 int flags;
4517 long arg = 0;
4518 long bytesent; /* bytes read */
4519
4520 SL_ENTER(_("sh_forward_do_write"));
4521
4522 /* ---- consistency check ------
4523 */
4524 if (conn->state == CONN_READING)
4525 {
4526 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
4527 conn->peer);
4528 SL_RETURN( (-1), _("sh_forward_do_write"));
4529 }
4530
4531
4532 flags = retry_fcntl (FIL__, __LINE__, conn->fd, F_GETFL, arg);
4533 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags|O_NONBLOCK);
4534
4535 /* ---- send the header ------
4536 */
4537 if (conn->headcount < SH_HEADER_SIZE)
4538 {
4539 conn->bytes_to_send = SH_HEADER_SIZE - conn->headcount;
4540 bytesent = write (conn->fd,
4541 &(conn->head[conn->headcount]),
4542 conn->bytes_to_send);
4543 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4544 {
4545 if (bytesent > 0)
4546 conn->headcount += bytesent;
4547 if (conn->headcount == SH_HEADER_SIZE)
4548 {
4549 conn->bytes_to_send =
4550 (256 * (int)conn->head[1] + (int)conn->head[2]);
4551 }
4552 }
4553 else
4554 {
4555 goto conn_reset_w;
4556 }
4557 if (conn->fd >= 0)
4558 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4559 SL_RETURN( (0), _("sh_forward_do_write"));
4560 }
4561
4562
4563 /* ---- send the body ------
4564 */
4565
4566 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send > 0 &&
4567 conn->buf != NULL)
4568 {
4569 bytesent = write (conn->fd, &(conn->buf[conn->bytecount]),
4570 conn->bytes_to_send - conn->bytecount);
4571 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
4572 {
4573 if (bytesent > 0)
4574 conn->bytecount += bytesent;
4575 if (conn->bytecount == conn->bytes_to_send)
4576 {
4577 ++conn->pass;
4578 conn->state = CONN_PAUSE;
4579 /* ------ HERE CALL check_protocol(conn) ------- */
4580 check_protocol(conn, SH_DO_WRITE);
4581 }
4582 }
4583 else
4584 {
4585 goto conn_reset_w;
4586 }
4587 }
4588
4589 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send == 0)
4590 {
4591 ++conn->pass;
4592 conn->state = CONN_PAUSE;
4593 /* fprintf(stderr, "\n**** FIXME null write ****\n\n"); */
4594 /* ------ HERE CALL check_protocol(conn) ------- */
4595 check_protocol(conn, SH_DO_WRITE);
4596 }
4597
4598 if (conn->fd >= 0)
4599 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
4600 SL_RETURN( (0), _("sh_forward_do_write"));
4601
4602 conn_reset_w:
4603 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
4604 conn->peer);
4605 sh_forward_do_free ( conn );
4606 SL_RETURN( (-1), _("sh_forward_do_write"));
4607}
4608
4609/* accept a connection from a client
4610 */
4611#include <syslog.h>
4612#ifdef SH_USE_LIBWRAP
4613#include <tcpd.h>
4614
4615#ifndef ALLOW_SEVERITY
4616#define ALLOW_SEVERITY LOG_INFO
4617#define DENY_SEVERITY LOG_WARNING
4618#endif
4619
4620int allow_severity;
4621int deny_severity;
4622#endif
4623
4624int sh_forward_accept (int sock, sh_conn_t * newconn)
4625{
4626 int errflag;
4627 int rc;
4628 struct sockaddr_in addr;
4629#ifdef SH_USE_LIBWRAP
4630 struct request_info request;
4631 char errbuf[128];
4632 char daemon[128];
4633#endif
4634
4635 /* handle AIX (size_t addrlen) in wrapper
4636 */
4637 int addrlen = sizeof(addr);
4638
4639 SL_ENTER(_("sh_forward_accept"));
4640
4641 rc = retry_accept(FIL__, __LINE__, sock,
4642 (struct sockaddr *) &addr, &addrlen);
4643
4644 if (rc >= 0)
4645 {
4646
4647 if (addrlen == 0)
4648 {
4649 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4650 _("Connecting entity unknown"), _("accept"));
4651 newconn->fd = -1;
4652 newconn->state = CONN_FREE;
4653 close(rc);
4654 SL_RETURN( (-1), _("sh_forward_accept"));
4655 }
4656
4657#ifdef SH_USE_LIBWRAP
4658 sl_strlcpy(daemon, SH_INSTALL_NAME, 128);
4659 request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
4660 fromhost(&request);
4661 if (!hosts_access(&request))
4662 {
4663 sl_strlcpy(errbuf, _("Refused connection from "), 128);
4664 sl_strlcat(errbuf, eval_client(&request), 128);
4665
4666 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
4667 errbuf, _("libwrap"));
4668 newconn->fd = -1;
4669 newconn->state = CONN_FREE;
4670 close(rc);
4671 SL_RETURN( (-1), _("sh_forward_accept"));
4672 }
4673#endif
4674
4675 memcpy (&(newconn->addr_peer), &addr, sizeof(struct sockaddr_in));
4676
4677 /* prepare for usage of connection
4678 */
4679 (void) retry_fcntl( FIL__, __LINE__, rc, F_SETFD, 1 );
4680 newconn->fd = rc;
4681 newconn->state = CONN_READING;
4682 newconn->timer = (unsigned long) time (NULL);
4683
[12]4684 if (flag_err_info == SL_TRUE)
4685 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CNEW, newconn->fd);
[1]4686
4687 SL_RETURN( (0), _("sh_forward_accept"));
4688 }
4689 else
4690 {
[132]4691 char err_buf[SH_ERRBUF_SIZE];
[1]4692 errflag = errno;
4693 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
[132]4694 sh_error_message(errflag,err_buf, sizeof(err_buf)), _("accept"));
[1]4695 newconn->fd = -1;
4696 newconn->state = CONN_FREE;
4697 SL_RETURN( (-1), _("sh_forward_accept"));
4698 }
4699}
4700
4701extern char sh_sig_msg[64]; /* defined in sh_unix.c */
4702
4703/* ------------ port and interface -------
4704 */
4705static unsigned int server_port = SH_DEFAULT_PORT;
4706
[22]4707int sh_forward_set_port (const char * str)
[1]4708{
4709 int retval = 0;
4710 unsigned long i;
[22]4711 char * endptr;
[1]4712
4713 SL_ENTER(_("sh_forward_set_port"));
4714 i = strtoul (str, &endptr, 0);
4715 if (endptr == str) {
4716 retval = -1;
4717 } else if (i > 65535) {
4718 retval = -1;
4719 } else {
4720 server_port = i;
4721 }
4722 SL_RETURN( (retval), _("sh_forward_set_port"));
4723}
4724
4725static struct in_addr server_interface;
4726static int use_server_interface = 0;
4727
[22]4728int sh_forward_set_interface (const char * str)
[1]4729{
4730 if (0 == strcmp(str, _("INADDR_ANY")))
4731 {
4732 use_server_interface = 0;
4733 return 0;
4734 }
4735 if (0 == /*@-unrecog@*/inet_aton(str, &server_interface)/*@+unrecog@*/)
4736 {
4737 use_server_interface = 0;
4738 return -1;
4739 }
4740 use_server_interface = 1;
4741 return 0;
4742}
4743
4744/* ------------ print error --------------
4745 */
4746struct sock_err_st {
4747 char msg[128];
4748 int errnum;
4749 int port;
4750 int line;
4751 int euid;
4752};
4753
4754static struct sock_err_st sock_err[2];
4755
4756void sh_forward_printerr(char * str, int errnum, unsigned int port, int line)
4757{
4758 int slot = 0;
4759
4760 if (port != server_port)
4761 slot = 1;
4762 if (str == NULL)
4763 sock_err[slot].msg[0] = '\0';
4764 else
4765 sl_strlcpy(sock_err[slot].msg, str, 128);
4766 sock_err[slot].errnum = errnum;
4767 sock_err[slot].port = port;
4768 sock_err[slot].line = line;
4769 sock_err[slot].euid = (int) geteuid();
4770}
4771
4772int sh_forward_printerr_final(int slot)
4773{
[132]4774 char errbuf[SH_ERRBUF_SIZE];
4775
[1]4776 SL_ENTER(_("sh_forward_printerr_final"));
4777 if (sock_err[slot].msg[0] != '\0')
4778 {
4779 dlog(1, FIL__, __LINE__,
4780 _("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]4781 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
4782 sock_err[slot].euid,
[1]4783 sock_err[slot].port);
4784 sh_error_handle((-1), FIL__, sock_err[slot].line,
4785 sock_err[slot].errnum, MSG_EXIT_ABORTS,
[132]4786 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
[1]4787 sh.prg_name,
4788 sock_err[slot].msg);
4789 SL_RETURN((-1), _("sh_forward_printerr_final"));
4790 }
4791 SL_RETURN(0, _("sh_forward_printerr_final"));
4792}
4793
4794static sh_conn_t * conns = NULL;
[178]4795#define TIME_OUT_DEF 900
[1]4796static int maxconn = 0; /* maximum number of simultaneous connections */
4797
4798
4799#ifdef INET_SYSLOG
4800#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
4801#define SH_MINSOCK 3
4802int create_syslog_socket (int flag);
4803static int recv_syslog_socket (int fd);
4804static int syslog_sock = -1;
4805#else
4806#define SH_MINSOCK 2
4807#endif
4808
4809extern int pf_unix_fd;
4810
4811/* the tcp socket, and the function to establish it
4812 */
4813static int sh_tcp_sock = -1;
4814
[170]4815int sh_create_tcp_socket (void)
[1]4816{
4817 struct sockaddr_in addr;
4818 int addrlen = sizeof(addr);
4819
4820 int sock = -1;
4821 int errnum = 0;
4822 int flag = 1; /* non-zero to enable an option */
4823
4824 SL_ENTER(_("sh_create_tcp_socket"));
4825
4826 sh_forward_printerr (NULL, 0, server_port, __LINE__);
4827
4828 /* create the socket, bind() it and listen()
4829 */
4830 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
4831 {
4832 errnum = errno;
4833 sh_forward_printerr (_("socket"), errnum, server_port, __LINE__);
4834 SL_RETURN((-1), _("sl_create_tcp_socket"));
4835 }
4836 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
4837
4838 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
4839 (void *) &flag, sizeof(flag)) < 0 )
4840 {
4841 errnum = errno;
4842 sh_forward_printerr (_("setsockopt"), errnum, server_port, __LINE__);
4843 SL_RETURN((-1), _("sl_create_tcp_socket"));
4844 }
4845
4846 addr.sin_family = AF_INET;
4847 addr.sin_port = htons(server_port);
4848 if (use_server_interface == 0)
4849 addr.sin_addr.s_addr = INADDR_ANY;
4850 else
4851 memcpy(&addr.sin_addr, &server_interface, sizeof(struct in_addr));
4852
4853 if ( bind(sock, (struct sockaddr *) &addr, addrlen) < 0)
4854 {
4855 errnum = errno;
4856 sh_forward_printerr (_("bind"), errnum, server_port, __LINE__);
4857 SL_RETURN((-1), _("sl_create_tcp_socket"));
4858 }
4859
4860 if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
4861 {
4862 errnum = errno;
4863 sh_forward_printerr (_("fcntl"), errnum, server_port, __LINE__);
4864 SL_RETURN((-1), _("sl_create_tcp_socket"));
4865 }
4866
4867 if ( listen(sock, 5) < 0)
4868 {
4869 errnum = errno;
4870 sh_forward_printerr (_("listen"), errnum, server_port, __LINE__);
4871 SL_RETURN((-1), _("sl_create_tcp_socket"));
4872 }
4873
4874 sh_tcp_sock = sock;
4875
4876 SL_RETURN((sock), _("sl_create_tcp_socket"));
4877}
4878
4879/*****************************************
4880 *
4881 * This is the server main loop.
4882 *
4883 * The server is set up for listening, and
4884 * and starts a select() loop.
4885 *
4886 *****************************************/
4887
4888void sh_receive()
4889{
4890#ifdef SH_USE_XML
4891 extern int sh_log_file (char * message, char * inet_peer);
4892#endif
4893
4894 int sock = -1;
4895 sh_conn_t * cx;
4896 fd_set readset;
4897 fd_set writeset;
4898 struct timeval tv;
4899 int num_sel;
4900 int errnum;
4901 int nowconn;
4902 int status;
4903 int high_fd;
4904 register int i;
4905 long dummy = 0;
4906 unsigned long time_now;
4907 unsigned long time_last = 0;
4908 unsigned long time_out = TIME_OUT_DEF;
4909
4910 time_t told;
4911 time_t tcurrent;
4912
4913 unsigned long tchkold;
4914
4915 struct sigaction new_act;
4916 struct sigaction old_act;
[171]4917
4918 int setsize_fd;
[1]4919
4920 SL_ENTER(_("sh_receive"));
4921
4922 /* ignore SIGPIPE (instead get EPIPE if connection is closed)
4923 * --- we have called sh_unix_init() already ---
4924 */
4925 new_act.sa_handler = SIG_IGN;
[22]4926 sigemptyset( &new_act.sa_mask ); /* set an empty mask */
4927 new_act.sa_flags = 0; /* init sa_flags */
[1]4928 retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
4929
4930 if ( sh_forward_printerr_final(0) < 0)
4931 {
4932 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
4933 }
4934 sock = sh_tcp_sock;
4935
4936 /* ****************************************************************
4937 *
4938 * This is a non-forking server. We use select() on the listen()
4939 * socket to watch for new connections. For new connections, accept()
4940 * will return a new socket that is put in the read/write filesets.
4941 * Data about active connections are kept in the 'conns' table.
4942 *
4943 ******************************************************************/
4944
4945 /* The table to hold info on sockets.
4946 * We reserve 6 file descriptors for misc. use.
4947 * The POSIX lower limit on open files seems to be eight.
4948 */
[171]4949 maxconn = get_open_max() - 6;
4950 /* ugly fix for FreeBSD compiler warning; casting FD_SETSIZE in the
4951 * conditional expression does not suppress the warning... */
4952 setsize_fd = (int)FD_SETSIZE;
4953 maxconn = (setsize_fd < maxconn) ? setsize_fd : maxconn;
[1]4954
[34]4955 if (maxconn < 0 || !sl_ok_muls(maxconn, sizeof(sh_conn_t)))
4956 {
4957 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
4958 0, sock);
4959 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
4960 }
[1]4961 conns = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
4962
4963 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
4964 (maxconn-1), sock);
4965
4966 /* timer
4967 */
4968 tcurrent = (unsigned long) time (NULL);
4969 told = tcurrent;
4970
4971 tchkold = tcurrent;
4972
4973 for (i = SH_MINSOCK; i < maxconn; ++i)
4974 {
4975 conns[i].buf = NULL;
4976 conns[i].K = NULL;
4977 conns[i].A = NULL;
4978 conns[i].M1 = NULL;
4979 conns[i].FileName = NULL;
4980 conns[i].fd = -1;
4981 sh_forward_do_free ( &conns[i]);
4982 }
4983
4984 /* status init
4985 */
4986 server_status.conn_open = 0;
4987 server_status.conn_total = 0;
4988 server_status.conn_max = maxconn-1;
4989 server_status.start = time (NULL);
4990 server_status.last = (time_t) 0;
4991
4992 nowconn = 1;
4993 tv.tv_sec = 5;
4994 tv.tv_usec = 0;
4995
4996 /* conns[0] is the listen() socket. Always in read mode.
4997 */
4998 conns[0].fd = sock;
4999 conns[0].state = CONN_READING;
5000 high_fd = sock;
5001
5002 conns[1].fd = pf_unix_fd;
5003 conns[1].state = CONN_READING;
5004 high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd;
5005
5006#ifdef INET_SYSLOG
5007 conns[2].fd = -1;
5008 if ( sh_forward_printerr_final(1) < 0)
5009 {
5010 SH_FREE(conns);
5011 conns = NULL;
5012 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
5013 }
5014 sock = syslog_sock;
5015
5016 if (sock >= 0)
5017 {
5018 conns[2].fd = sock;
5019 conns[2].state = CONN_READING;
5020 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5021 }
5022#endif
5023
5024 sh_html_write(all_clients);
5025
5026 /* This is the select() loop.
5027 */
5028 while (1 == 1)
5029 {
5030
5031 if (sig_raised > 0)
5032 {
5033 TPT((0, FIL__, __LINE__, _("msg=<Process a signal.>\n")))
5034
5035 if (sig_termfast == 1) /* SIGTERM */
5036 {
5037 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
5038 strncpy (sh_sig_msg, _("SIGTERM"), 20);
5039 --sig_raised; --sig_urgent;
5040 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
5041 }
5042
5043 if (sig_config_read_again == 1)
5044 {
5045 TPT((0, FIL__, __LINE__, _("msg=<Re-read configuration.>\n")));
5046 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
5047
5048
5049 /* -- Delete the name server cache. --
5050 */
5051
5052 delete_cache();
5053#if defined(WITH_EXTERNAL)
5054 /* -- Delete list of external tasks. --
5055 */
5056 (void) sh_ext_cleanup();
5057#endif
5058 /* - mark all clients dead
5059 * - read configuration file
5060 * - remove clients still dead
5061 */
5062 sh_forward_mark_dead ();
5063
5064#if defined(SH_WITH_MAIL)
5065 reset_count_dev_mail();
5066#endif
5067 reset_count_dev_console();
5068 reset_count_dev_time();
5069 sl_trust_purge_user();
5070
5071 (void) sh_readconf_read ();
5072 for (i = SH_MINSOCK; i < maxconn; ++i)
5073 if (conns[i].state != CONN_FREE &&
5074 conns[i].client_entry != NULL &&
5075 conns[i].client_entry->dead_flag == 1)
5076 sh_forward_do_free ( &conns[i]);
5077 sh_forward_clean_tree ();
5078
5079 sig_config_read_again = 0;
5080 --sig_raised;
5081 }
5082
5083 if (sig_fresh_trail == 1) /* SIGIOT */
5084 {
5085 /* Logfile access
5086 */
5087#ifdef SH_USE_XML
5088 sh_log_file (NULL, NULL);
5089#endif
5090 TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
5091 sh_error_only_stderr (S_TRUE);
5092 sh_unix_rm_lock_file(sh.srvlog.name);
5093 retry_msleep(3, 0);
5094 sh.flag.log_start = S_TRUE;
5095 sh_error_only_stderr (S_FALSE);
5096 sig_fresh_trail = 0;
5097 --sig_raised;
5098 }
5099
5100
5101 if (sig_terminate == 1 && nowconn < 2) /* SIGQUIT */
5102 {
5103 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
5104 strncpy (sh_sig_msg, _("SIGQUIT"), 20);
5105 --sig_raised; --sig_urgent;
5106 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
5107 }
5108
5109
5110 if (sig_debug_switch == 1) /* SIGUSR1 */
5111 {
5112 TPT((0, FIL__, __LINE__, _("msg=<Debug switch.>\n")));
5113 sh_error_dbg_switch();
5114 sig_debug_switch = 0;
5115 --sig_raised;
5116 }
5117
[19]5118 if (sig_suspend_switch > 0) /* SIGUSR2 */
[1]5119 {
5120 TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
5121 if (sh_global_suspend_flag == 1) {
5122 sh_global_suspend_flag = 0;
5123 } else {
5124 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND,
5125 sh.prg_name);
5126 sh_global_suspend_flag = 1;
5127 }
[19]5128 --sig_suspend_switch;
[1]5129 --sig_raised; --sig_urgent;
5130 }
5131
5132 sig_raised = (sig_raised < 0) ? 0 : sig_raised;
5133 sig_urgent = (sig_urgent < 0) ? 0 : sig_urgent;
5134 TPT((0, FIL__, __LINE__, _("msg=<End signal processing.>\n")));
5135 }
5136
5137 if (sh_global_suspend_flag == 1)
5138 {
5139 (void) retry_msleep (1, 0);
5140 continue;
5141 }
5142
5143 /* Recompute the descriptor set. select() modifies it,
5144 * thus we update it using the info from the connection table.
5145 * Also recompute the number of open connections.
5146 */
5147 FD_ZERO( &readset );
5148 FD_ZERO( &writeset );
5149 FD_SET(conns[0].fd, &readset );
5150 high_fd = conns[0].fd;
5151
5152 if (conns[1].fd > -1)
5153 {
5154 FD_SET(conns[1].fd, &readset );
5155 high_fd = (high_fd > conns[1].fd) ? high_fd : conns[1].fd;
5156 }
5157
5158#ifdef INET_SYSLOG
5159 if (conns[2].fd > -1)
5160 {
5161 FD_SET(conns[2].fd, &readset );
5162 high_fd = (high_fd > conns[2].fd) ? high_fd : conns[2].fd;
5163 }
5164#endif
5165
5166 time_now = (unsigned long) time (NULL);
5167 nowconn = 1;
5168
5169 for (i = SH_MINSOCK; i < maxconn; ++i)
5170 {
5171 /* eliminate timed out connections
5172 */
5173 if (conns[i].state != CONN_FREE)
5174 {
5175 if (time_now-conns[i].timer > time_out)
5176 {
5177 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMOUT,
5178 conns[i].peer);
5179 sh_forward_do_free ( &conns[i]);
5180 }
5181 else
5182 ++nowconn;
5183 }
5184
5185
5186 if (conns[i].state == CONN_READING)
5187 {
5188 FD_SET(conns[i].fd, &readset);
5189 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5190 }
5191 else if (conns[i].state == CONN_SENDING)
5192 {
5193 FD_SET(conns[i].fd, &writeset);
5194 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
5195 }
5196 }
5197
5198 /* -- Exponentially reduce timeout limit if more than 1/2 full. --
5199 */
5200 if (nowconn > (maxconn/2))
5201 time_out = ( (time_out/2) > 1) ? (time_out/2) : 1;
5202 else
5203 time_out = TIME_OUT_DEF;
5204
5205
5206
5207 /* -- Do the select(). --
5208 */
5209 num_sel = select(high_fd+1, &readset, &writeset, NULL, &tv);
5210 errnum = errno;
5211
5212 /* reset timeout - modified by select() on some systems
5213 */
5214 tv.tv_sec = 5;
5215 tv.tv_usec = 0;
5216
5217
5218 if ( (time_now - time_last) > 2L)
5219 {
5220 time_last = time_now;
5221 if (sh_html_write(all_clients) < 0)
5222 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5223 }
5224
5225
5226 /* Error handling.
5227 */
5228 if ( num_sel < 0 ) /* some error */
5229 {
[132]5230 char errbuf[SH_ERRBUF_SIZE];
5231
[1]5232 if (sig_raised == 1)
5233 {
5234 sig_raised = 2;
5235 continue;
5236 }
5237
5238 if ( errnum == EINTR)
5239 continue; /* try again */
5240
5241 if ( errnum == EBADF)
5242 {
5243 /* seek and destroy the bad fd
5244 */
5245 for (i = SH_MINSOCK; i < high_fd; ++i)
5246 {
5247 if ((conns[i].state == CONN_READING) ||
5248 (conns[i].state == CONN_SENDING))
5249 {
5250 if (-1 == retry_fcntl(FIL__, __LINE__,
5251 conns[i].fd, F_GETFL, dummy))
5252 sh_forward_do_free ( &conns[i]);
5253 }
5254 }
5255 continue;
5256 }
5257
5258 sh_error_handle((-1), FIL__, __LINE__, errnum, MSG_EXIT_ABORTS,
[132]5259 sh_error_message(errnum, errbuf, sizeof(errbuf)),
[1]5260 sh.prg_name,
5261 _("select"));
5262 aud_exit(FIL__, __LINE__, EXIT_FAILURE );
5263 }
5264
5265
5266 /* log the timestamp
5267 */
5268 if ((tcurrent - told) > sh.looptime )
5269 {
5270 told = tcurrent;
5271#ifdef MEM_DEBUG
5272 sh_mem_check();
5273 sh_unix_count_mlock();
5274#else
5275 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_STAMP);
5276#endif
5277 }
5278
5279#if defined(SH_WITH_MAIL)
5280 /*
5281 * flush the mail queue
5282 */
5283 if (tcurrent - sh.mailTime.alarm_last > sh.mailTime.alarm_interval)
5284 {
5285 TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
5286 (void) sh_mail_msg (NULL);
5287 sh.mailTime.alarm_last = tcurrent;
5288 }
5289#endif
5290#ifdef MEM_DEBUG
5291 sh_mem_dump();
5292#endif
5293
5294 tcurrent = (unsigned long) time (NULL);
5295
[19]5296 /* check for time limit exceeded
5297 */
5298 if ((tcurrent - tchkold) > (unsigned int) 3 )
5299 {
5300 tchkold = tcurrent;
5301 client_time_check(/* all_clients */);
5302 }
5303
5304 /* seed / re-seed the PRNG if required
5305 */
5306 (void) taus_seed();
5307
[1]5308 /* select() timeout handling.
5309 */
5310 if ( num_sel == 0 ) /* timeout - no connection */
5311 {
5312 if (sh_html_write(all_clients) < 0)
5313 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
5314 continue;
5315 }
5316
5317 /* New connection.
5318 */
5319 if ( FD_ISSET(conns[0].fd , &readset )) /* a new connection */
5320 {
5321 --num_sel;
5322 status = 0;
5323 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
5324 {
5325 i = SH_MINSOCK;
5326 while (i < maxconn)
5327 {
5328 if (conns[i].state == CONN_FREE)
5329 {
5330 status = sh_forward_accept (conns[0].fd, &conns[i]);
5331 if (status == 0)
5332 {
5333 high_fd =
5334 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
5335 ++server_status.conn_open;
5336 ++server_status.conn_total;
5337 server_status.last = time (NULL);
5338 }
5339 break;
5340 }
5341 ++i;
5342 }
5343 }
5344 if (status == 0)
5345 continue;
5346 }
5347
5348 /* check for commands on the socket
5349 */
5350 if (conns[1].fd > (-1) && FD_ISSET(conns[1].fd , &readset ))
5351 {
5352 sh_socket_poll();
5353 }
5354
5355#ifdef INET_SYSLOG
5356 if (conns[2].fd > (-1) && FD_ISSET(conns[2].fd , &readset ))
5357 {
5358 recv_syslog_socket (conns[2].fd);
5359 }
5360#endif
5361
5362 /* Check for pending read/write on the rest of the sockets.
5363 */
5364 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
5365 {
5366 if (sig_termfast == 1)
5367 break;
5368
5369 cx = &conns[i];
5370 if ( cx->state == CONN_READING &&
5371 FD_ISSET( cx->fd, &readset ) )
5372 {
5373 --num_sel;
5374 sh_forward_do_read ( cx );
5375 }
5376 else if ( cx->state == CONN_SENDING &&
5377 FD_ISSET( cx->fd, &writeset ) )
5378 {
5379 --num_sel;
5380 sh_forward_do_write ( cx );
5381 }
5382 }
[19]5383 /* continue */
[1]5384 }
5385 /* notreached */
5386}
5387
[170]5388void free_client_tree (void)
[1]5389{
5390 SL_ENTER(_("free_client_tree"));
5391 zAVLFreeTree (all_clients, free_client);
5392 SL_RET0(_("free_client_tree"));
5393}
5394
5395void sh_forward_free_all ()
5396{
5397 register int i;
5398
5399 SL_ENTER(_("sh_forward_free_all"));
5400
5401 if (conns != NULL)
5402 for (i = SH_MINSOCK; i < maxconn; ++i)
5403 {
5404 sh_forward_do_free ( &conns[i]);
5405 }
5406
5407
5408 free_client_tree ();
5409
5410 if (conns != NULL)
5411 SH_FREE (conns);
5412
5413 SL_RET0(_("sh_forward_free_all"));
5414}
5415
5416#ifdef INET_SYSLOG
5417
5418#ifdef HAVE_INET_ATON
5419static char * my_inet_ntoa(struct in_addr in)
5420{
5421 return inet_ntoa(in);
5422}
5423#else
5424static char * my_inet_ntoa(struct in_addr in)
5425{
5426 unsigned char a, b, c, d;
5427 static char foo[16];
5428 char bar[4];
5429 memcpy (bar, &(in.s_addr), 4); /* memory alignment (?) */
5430 memcpy (&a, &bar[0], 1);
5431 memcpy (&b, &bar[1], 1);
5432 memcpy (&c, &bar[2], 1);
5433 memcpy (&d, &bar[3], 1);
5434 sprintf(foo, "%d.%d.%d.%d", /* known to fit */
5435 (int) a, (int) b, (int) c, (int) d);
5436 return foo;
5437}
5438#endif
5439
5440
5441/* Unlike Linux / FreeBSD, most systems don't define the stuff below
5442 * in syslog.h
5443 */
5444
5445#ifndef LOG_FAC
5446#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
5447#endif
5448
5449#ifndef LOG_PRI
5450#define LOG_PRI(p) ((p) & LOG_PRIMASK)
5451#endif
5452
5453typedef struct sh_code {
5454 char *c_name;
5455 int c_val;
5456} SH_CODE;
5457
5458SH_CODE sh_facilitynames[] =
5459{
5460#ifdef LOG_AUTH
5461 { N_("auth"), LOG_AUTH },
5462#endif
5463#ifdef LOG_AUTHPRIV
5464 { N_("authpriv"), LOG_AUTHPRIV },
5465#endif
5466#ifdef LOG_CRON
5467 { N_("cron"), LOG_CRON },
5468#endif
5469#ifdef LOG_DAEMON
5470 { N_("daemon"), LOG_DAEMON },
5471#endif
5472#ifdef LOG_FTP
5473 { N_("ftp"), LOG_FTP },
5474#endif
5475#ifdef LOG_KERN
5476 { N_("kern"), LOG_KERN },
5477#endif
5478#ifdef LOG_LPR
5479 { N_("lpr"), LOG_LPR },
5480#endif
5481#ifdef LOG_MAIL
5482 { N_("mail"), LOG_MAIL },
5483#endif
5484#ifdef INTERNAL_MARK
5485 { N_("mark"), INTERNAL_MARK }, /* INTERNAL */
5486#endif
5487#ifdef LOG_NEWS
5488 { N_("news"), LOG_NEWS },
5489#endif
5490#ifdef LOG_AUTH
5491 { N_("security"), LOG_AUTH }, /* DEPRECATED */
5492#endif
5493#ifdef LOG_SYSLOG
5494 { N_("syslog"), LOG_SYSLOG },
5495#endif
5496#ifdef LOG_USER
5497 { N_("user"), LOG_USER },
5498#endif
5499#ifdef LOG_UUCP
5500 { N_("uucp"), LOG_UUCP },
5501#endif
5502#ifdef LOG_LOCAL0
5503 { N_("local0"), LOG_LOCAL0 },
5504#endif
5505#ifdef LOG_LOCAL1
5506 { N_("local1"), LOG_LOCAL1 },
5507#endif
5508#ifdef LOG_LOCAL2
5509 { N_("local2"), LOG_LOCAL2 },
5510#endif
5511#ifdef LOG_LOCAL3
5512 { N_("local3"), LOG_LOCAL3 },
5513#endif
5514#ifdef LOG_LOCAL4
5515 { N_("local4"), LOG_LOCAL4 },
5516#endif
5517#ifdef LOG_LOCAL5
5518 { N_("local5"), LOG_LOCAL5 },
5519#endif
5520#ifdef LOG_LOCAL6
5521 { N_("local6"), LOG_LOCAL6 },
5522#endif
5523#ifdef LOG_LOCAL7
5524 { N_("local7"), LOG_LOCAL7 },
5525#endif
5526 { NULL, -1 }
5527};
5528
5529
5530SH_CODE sh_prioritynames[] =
5531{
5532#ifdef LOG_ALERT
5533 { N_("alert"), LOG_ALERT },
5534#endif
5535#ifdef LOG_CRIT
5536 { N_("crit"), LOG_CRIT },
5537#endif
5538#ifdef LOG_DEBUG
5539 { N_("debug"), LOG_DEBUG },
5540#endif
5541#ifdef LOG_EMERG
5542 { N_("emerg"), LOG_EMERG },
5543#endif
5544#ifdef LOG_ERR
5545 { N_("err"), LOG_ERR },
5546#endif
5547#ifdef LOG_ERR
5548 { N_("error"), LOG_ERR }, /* DEPRECATED */
5549#endif
5550#ifdef LOG_INFO
5551 { N_("info"), LOG_INFO },
5552#endif
5553#ifdef INTERNAL_NOPRI
5554 { N_("none"), INTERNAL_NOPRI }, /* INTERNAL */
5555#endif
5556#ifdef LOG_NOTICE
5557 { N_("notice"), LOG_NOTICE },
5558#endif
5559#ifdef LOG_EMERG
5560 { N_("panic"), LOG_EMERG }, /* DEPRECATED */
5561#endif
5562#ifdef LOG_WARNING
5563 { N_("warn"), LOG_WARNING }, /* DEPRECATED */
5564#endif
5565#ifdef LOG_WARNING
5566 { N_("warning"), LOG_WARNING },
5567#endif
5568 { NULL, -1 }
5569};
5570
5571static int enable_syslog_socket = S_FALSE;
5572
5573static int recv_syslog_socket (int fd)
5574{
5575 static time_t return_next = 0;
5576 int priority = 0;
5577 int fac, pri;
5578 int i;
5579 char * cfac = NULL;
5580 char * cpri = NULL;
5581 int res;
5582 char * tmp;
5583 char * bptr;
5584 char * ptr = NULL;
5585 char buf[1048];
5586 struct sockaddr_in from;
[132]5587 char errbuf[SH_ERRBUF_SIZE];
[1]5588
5589 /* The 6th argument in recvfrom is *socklen_t in Linux and *BSD,
5590 * but *int everywhere else. Because socklen_t is unsigned int, there
5591 * should be no problem as long as sizeof(struct sockaddr_in) < INT_MAX ...
5592 */
5593 int fromlen = sizeof(from);
5594
5595 if (enable_syslog_socket == S_FALSE)
5596 return 0;
5597
5598 SL_ENTER(_("recv_syslog_socket"));
5599
5600 if (return_next > 0)
5601 {
5602 if ( (time(NULL) - return_next) < 2)
5603 SL_RETURN( 0, _("recv_syslog_socket"));
5604 else
5605 return_next = 0;
5606 }
5607
5608 res = recvfrom(fd, buf, 1047, 0, (struct sockaddr *) &from, &fromlen);
5609
5610 if (res > 0)
5611 {
5612 res = (res < 1047) ? res : 1047;
5613 buf[res] = '\0';
5614 if (res > 1 && buf[res-1] == '\n')
5615 buf[res-1] = '\0';
5616
5617 /* here we expect an xml formatted message, thus we don't
5618 escape xml special chars (flag == 0) */
5619 /* commented out to not escape twice */
5620 /* bptr = sh_tools_safe_name(buf, 0); */
5621 bptr = buf;
5622
5623 if (!bptr || !(*bptr))
5624 {
5625 res = errno;
5626 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5627 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
[132]5628 sh_error_message(res, errbuf, sizeof(errbuf)),
5629 my_inet_ntoa(from.sin_addr));
[1]5630 SL_RETURN( (-1), _("recv_syslog_socket"));
5631 }
5632
5633 TPT(( 0, FIL__, __LINE__, _("msg=<UDP message from %s>\n"),
5634 my_inet_ntoa(from.sin_addr)));
5635 ptr = bptr;
5636 i = 0;
5637 if (*ptr == '<')
5638 {
5639 ++ptr; ++i;
5640 while (i < res &&
5641 (unsigned char) *ptr > 47 && (unsigned char) *ptr < 58)
5642 {
5643 priority = 10 * priority + (*ptr - '0');
5644 ++ptr;
5645 ++i;
5646 }
5647 if (*ptr == '>')
5648 ++ptr;
5649 }
5650 fac = LOG_FAC(priority);
5651 i = 0;
5652 while (sh_facilitynames[i].c_name != NULL)
5653 {
5654 if (sh_facilitynames[i].c_val == (fac<<3))
5655 { cfac = sh_util_strdup(_(sh_facilitynames[i].c_name)); break; }
5656 ++i;
5657 }
5658 pri = LOG_PRI(priority);
5659 i = 0;
5660 while (sh_prioritynames[i].c_name != NULL)
5661 {
5662 if (sh_prioritynames[i].c_val == pri)
5663 { cpri = sh_util_strdup(_(sh_prioritynames[i].c_name)); break; }
5664 ++i;
5665 }
5666
5667 /* here we do not expect an xml formatted message, thus we escape
5668 xml special chars (flag == 1) */
5669 tmp = sh_tools_safe_name (ptr, 1);
5670 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_INET_SYSLOG,
5671 my_inet_ntoa(from.sin_addr),
5672 (cfac == NULL) ? _("none") : cfac,
5673 (cpri == NULL) ? _("none") : cpri,
5674 (ptr == NULL) ? _("none") : ptr);
5675 if (cfac != NULL)
5676 SH_FREE(cfac);
5677 if (cpri != NULL)
5678 SH_FREE(cpri);
5679 SH_FREE(tmp);
5680 /* SH_FREE(bptr); */
5681 }
5682
5683 else if (res < 0 && errno != EINTR)
5684 {
5685 res = errno;
5686 TPT(( 0, FIL__, __LINE__, _("msg=<UDP error: %d>\n"), res));
5687 sh_error_handle((-1), FIL__, __LINE__, res, MSG_ERR_SYSLOG,
[132]5688 sh_error_message(res, errbuf, sizeof(errbuf)),
5689 my_inet_ntoa(from.sin_addr));
[1]5690
5691 /* don't accept anything the next 2 seconds
5692 */
5693 return_next = time(NULL);
5694 SL_RETURN( (-1), _("recv_syslog_socket"));
5695 }
5696 SL_RETURN( (0), _("recv_syslog_socket"));
5697}
5698
[22]5699int set_syslog_active(const char * c)
[1]5700{
5701 return sh_util_flagval(c, &enable_syslog_socket);
5702}
5703
5704/* callerFlag == S_TRUE means override the enable_syslog_socket flag
5705 */
5706int create_syslog_socket (int callerFlag)
5707{
5708 int flag = 1; /* non-zero to enable an option */
5709 int sock;
5710 int errnum;
5711 int res;
5712 struct sockaddr_in addr;
5713 int addrlen = sizeof(addr);
5714
5715 SL_ENTER(_("create_syslog_socket"));
5716
5717 if (callerFlag == S_FALSE)
5718 {
5719 if (enable_syslog_socket == S_FALSE && syslog_sock >= 0)
5720 {
5721 /* user does not wish to use this facility
5722 */
5723 TPT(( 0, FIL__, __LINE__, _("msg=<close syslog socket>\n")));
5724 close(syslog_sock);
5725 syslog_sock = -1;
5726 }
5727 SL_RETURN((-1), _("create_syslog_socket"));
5728 }
5729
5730 sh_forward_printerr (NULL, 0, 514, __LINE__);
5731
5732 /* create the socket, bind() it and listen()
5733 */
5734 sock = socket(AF_INET, SOCK_DGRAM, 0);
5735
5736 if (sock < 0)
5737 {
5738 errnum = errno;
5739 sh_forward_printerr (_("syslog socket"), errnum, 514, __LINE__);
5740 SL_RETURN((-1), _("create_syslog_socket"));
5741 }
5742 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
5743
5744 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
5745 (void *) &flag, sizeof(flag)) < 0 )
5746 {
5747 errnum = errno;
5748 sh_forward_printerr (_("syslog setsockopt SO_REUSEADDR"),
5749 errnum, 514, __LINE__);
5750 SL_RETURN((-1), _("create_syslog_socket"));
5751 }
5752
5753#if defined(SO_BSDCOMPAT)
5754 if ( setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
5755 (void *) &flag, sizeof(flag)) < 0 )
5756 {
5757 errnum = errno;
5758 sh_forward_printerr (_("syslog setsockopt SO_BSDCOMPAT"),
5759 errnum, 514, __LINE__);
5760 SL_RETURN((-1), _("create_syslog_socket"));
5761 }
5762#endif
5763
5764 memset(&addr, 0, sizeof(addr));
5765 addr.sin_family = AF_INET;
5766 addr.sin_port = htons(514);
5767
5768 res = bind(sock, (struct sockaddr *) &addr, addrlen);
5769
5770 if ( res < 0)
5771 {
5772 errnum = errno;
5773 sh_forward_printerr (_("syslog bind"), errnum, 514, __LINE__);
5774 close(sock);
5775 SL_RETURN((-1), _("create_syslog_socket"));
5776 }
5777
5778 syslog_sock = sock;
5779
5780 SL_RETURN((sock), _("create_syslog_socket"));
5781}
5782/* #ifdef INET_SYSLOG */
5783#endif
5784
5785
5786
5787/* #ifdef SH_WITH_SERVER */
5788#endif
5789
5790
5791
5792
5793
5794
Note: See TracBrowser for help on using the repository browser.