source: trunk/src/sh_xfer_server.c@ 575

Last change on this file since 575 was 575, checked in by katerina, 3 years ago

Fix for ticket #463 (gcc 11.2 compiler warnings).

File size: 92.8 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <string.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <ctype.h>
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
41#define TRANS_BYTES 65120
42#else
43#define TRANS_BYTES 65280
44#endif
45
46/* timeout for session key
47 */
48#define TIMEOUT_KEY 7200
49
50/* max time between connection attempts
51 */
52#define TIMEOUT_CON 2048
53
54/* #undef SRP_DEBUG */
55/* #define SRP_DEBUG */
56
57#ifdef HAVE_MEMORY_H
58#include <memory.h>
59#endif
60
61#if TIME_WITH_SYS_TIME
62#include <sys/time.h>
63#include <time.h>
64#else
65#if HAVE_SYS_TIME_H
66#include <sys/time.h>
67#else
68#include <time.h>
69#endif
70#endif
71
72/*
73#ifdef TM_IN_SYS_TIME
74#include <sys/time.h>
75#else
76#include <time.h>
77#endif
78*/
79
80#ifdef HAVE_SYS_SELECT_H
81#include <sys/select.h>
82#endif
83
84#ifdef HAVE_UNISTD_H
85#include <errno.h>
86#include <signal.h>
87#include <setjmp.h>
88#include <pwd.h>
89#include <grp.h>
90#include <sys/stat.h>
91#include <sys/resource.h>
92#include <fcntl.h>
93#include <sys/wait.h>
94#include <unistd.h>
95#endif
96
97#ifndef FD_SET
98#define NFDBITS 32
99#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
100#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
101#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
102#endif /* !FD_SET */
103#ifndef FD_SETSIZE
104#define FD_SETSIZE 32
105#endif
106#ifndef FD_ZERO
107#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p)))
108#endif
109
110#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
111#include <sys/mman.h>
112#endif
113
114
115#include <netdb.h>
116#include <sys/types.h>
117#include <netinet/in.h>
118#include <sys/socket.h>
119#ifndef S_SPLINT_S
120#include <arpa/inet.h>
121#endif
122
123#include "sh_ipvx.h"
124#include "samhain.h"
125#include "sh_tiger.h"
126#include "sh_utils.h"
127#include "sh_unix.h"
128#include "sh_xfer.h"
129#include "sh_srp.h"
130#include "sh_fifo.h"
131#include "sh_tools.h"
132#include "sh_entropy.h"
133#include "sh_html.h"
134#include "sh_nmail.h"
135#include "sh_socket.h"
136#define SH_NEED_GETHOSTBYXXX
137#include "sh_static.h"
138#include "sh_guid.h"
139
140#ifdef SH_ENCRYPT
141#include "rijndael-api-fst.h"
142char * sh_tools_makePack (unsigned char * header, int flag,
143 char * payload, unsigned long payload_size,
144 keyInstance * keyInstE);
145char * sh_tools_revertPack (unsigned char * header, int flag, char * message,
146 keyInstance * keyInstE,
147 unsigned long message_size);
148#endif
149
150/* define this if you want to debug the client/server communication */
151/* #define SH_DBG_PROT 1 */
152
153#ifdef SH_DBG_PROT
154#define SH_SHOWPROT(c,d) sh_tools_show_header((c), (d))
155#else
156#define SH_SHOWPROT(c,d)
157#endif
158
159/* the port client will be connecting to
160 */
161#ifndef SH_DEFAULT_PORT
162#define SH_DEFAULT_PORT 49777
163#endif
164
165#ifndef SH_SELECT_REPEAT
166#define SH_SELECT_REPEAT 60
167#endif
168
169#ifndef SH_HEADER_SIZE
170#define SH_HEADER_SIZE 7
171#endif
172
173#ifndef SH_CHALLENGE_SIZE
174#define SH_CHALLENGE_SIZE 9
175#endif
176
177#undef FIL__
178#define FIL__ _("sh_xfer_server.c")
179
180int clt_class = (-1);
181
182extern int flag_err_debug;
183extern int flag_err_info;
184
185
186#if defined (SH_WITH_SERVER)
187
188#if defined(WITH_TRACE) || defined(WITH_TPT)
189extern char * hu_trans(const char * ihu);
190#endif
191extern unsigned int ServerPort;
192#if !defined(USE_SRP_PROTOCOL)
193extern void sh_passwd (char * salt, char * password, char * nounce, char *hash);
194#endif
195
196static int StripDomain = S_TRUE;
197
198int sh_xfer_set_strip (const char * str)
199{
200 static int fromcl = 0;
201
202 if (fromcl == 1)
203 return 0;
204 else
205 return (sh_util_flagval(str, &StripDomain));
206}
207
208static char * sh_strip_domain (char *name)
209{
210 char * out = NULL;
211
212 SL_ENTER(_("sh_strip_domain"));
213
214 if (StripDomain == S_FALSE || strchr(name, '.') == NULL)
215 {
216 out = sh_util_strdup(name);
217 SL_RETURN( out, _("sh_strip_domain"));
218 }
219 else
220 {
221 /* check whether it is in dotted number format
222 * --> last part must be kept
223 */
224 if (0 != sh_ipvx_is_numeric(name))
225 {
226 out = sh_util_strdup(name);
227 SL_RETURN( out, _("sh_strip_domain"));
228 }
229 else
230 {
231 char * p;
232 out = sh_util_strdup(name);
233 p = strchr(out, '.');
234 if (p) *p = '\0';
235 SL_RETURN( out, _("sh_strip_domain"));
236 }
237 }
238
239 SL_RETURN( out, _("sh_strip_domain"));
240}
241
242#ifndef USE_SRP_PROTOCOL
243
244int sh_xfer_make_client (const char * str)
245{
246 /* char * safer; */
247 char key[KEY_LEN+1];
248 unsigned char in[PW_LEN+1];
249 int i = 0, j, k, l = 0;
250 char hashbuf[KEYBUF_SIZE];
251
252 if (sl_strlen(str) != (PW_LEN * 2))
253 {
254 fprintf(stderr,
255 _("Input must be a %d digit hexadecimal number"\
256 " (only 0-9, a-f, A-F allowed in input)\n"),
257 (PW_LEN * 2));
258 _exit(EXIT_FAILURE);
259 }
260
261 while (i < (PW_LEN * 2))
262 {
263 k = sh_util_hexchar(str[i]); j = sh_util_hexchar(str[i+1]);
264 if (k != -1 && j != -1)
265 {
266 in[l] = (k * 16 + j);
267 ++l; i+= 2;
268 }
269 else
270 {
271 fprintf(stderr, _("Invalid char %c\n"), str[i]);
272 _exit(EXIT_FAILURE);
273 }
274 }
275 in[PW_LEN] = '\0';
276
277 sl_strlcpy ((char *)key,
278 sh_tiger_hash ((char*)in, TIGER_DATA, PW_LEN,
279 hashbuf, sizeof(hashbuf)),
280 KEY_LEN+1);
281 key[KEY_LEN] = '\0';
282
283 fprintf(stdout, _("Client entry: Client=HOSTNAME@00000000@%s\n"),
284 key);
285 fflush(stdout);
286
287 _exit(EXIT_SUCCESS);
288 return 0;
289}
290
291#else
292
293int sh_xfer_make_client (const char * str)
294{
295 char * foo_v;
296
297 char salt[17];
298 char key[KEY_LEN+1];
299 char in[PW_LEN];
300 int i = 0, j, k, l = 0;
301 char hashbuf[KEYBUF_SIZE];
302
303 if (sl_strlen(str) != (PW_LEN*2))
304 {
305 fprintf(stderr,
306 _("Input must be a %d digit hexadecimal number"\
307 " (only 0-9, a-f, A-F allowed in input)\n"),
308 (PW_LEN*2));
309 _exit(EXIT_FAILURE);
310 }
311
312 while (i < (PW_LEN*2))
313 {
314 k = sh_util_hexchar(str[i]); j = sh_util_hexchar(str[i+1]);
315 if (k != -1 && j != -1)
316 {
317 in[l] = (k * 16 + j);
318 ++l; i+= 2;
319 }
320 else
321 {
322 fprintf(stderr, _("Invalid char %c\n"), str[i]);
323 _exit(EXIT_FAILURE);
324 }
325 }
326
327
328 if (0 == sh_srp_init())
329 {
330 sh_util_keyinit(key, KEY_LEN);
331 sl_strlcpy(salt, sh_tiger_hash(key, TIGER_DATA, KEY_LEN,
332 hashbuf, sizeof(hashbuf)),
333 17);
334 sh_srp_x (salt, in);
335 foo_v = sh_srp_verifier ();
336 fprintf(stdout, _("Client=HOSTNAME@%s@%s\n"),
337 salt, foo_v);
338 fflush(stdout);
339 SH_FREE(foo_v);
340 sh_srp_exit();
341 _exit(EXIT_SUCCESS);
342 }
343 fprintf(stdout, "%s",_("ERROR initializing BigNum library.\n"));
344 fflush (stdout);
345 _exit(EXIT_FAILURE);
346 return -1;
347}
348#endif
349
350
351int sh_xfer_create_password (const char * dummy)
352{
353 UINT32 val[2];
354 char output[KEY_LEN+1];
355 char hashbuf[KEYBUF_SIZE];
356
357 val[0] = taus_get ();
358 val[1] = taus_get ();
359
360 sl_strlcpy (output,
361 sh_tiger_hash((char *)(&val[0]), TIGER_DATA, 2*sizeof(UINT32),
362 hashbuf, sizeof(hashbuf)),
363 KEY_LEN);
364
365 output[16] = '\0';
366
367 fprintf(stdout, _("%s\n"), output);
368 fflush (stdout);
369
370 if (dummy)
371 _exit(EXIT_SUCCESS);
372 else
373 _exit(EXIT_SUCCESS);
374 return (0); /* avoid compiler warning */
375}
376
377/* #if defined (SH_WITH_SERVER) */
378#endif
379
380/**************************************************
381 *
382 *
383 * S E R V E R
384 *
385 *
386 ***************************************************/
387
388#ifdef SH_WITH_SERVER
389
390#include "sh_readconf.h"
391
392
393#define CONN_FREE 0
394#define CONN_READING 1
395#define CONN_SENDING 2
396#define CONN_PAUSE 3
397#define CONN_BUSY 4
398
399char * clt_stat[] = {
400 N_("Inactive"),
401 N_("Started"),
402 N_("ILLEGAL"),
403 N_("FAILED"),
404 N_("Exited"),
405 N_("PANIC"),
406 N_("POLICY"),
407 N_("File_transfer"),
408 N_("Message"),
409 N_("TIMEOUT_EXCEEDED"),
410 N_("Suspended"),
411 N_("Filecheck"),
412};
413
414#include <time.h>
415
416/* in sh_html.h:
417 * typedef struct client_entry {
418 * } client_t;
419 */
420
421#include "zAVLTree.h"
422
423static char * sh_tolower (char * s)
424{
425 char * ret = s;
426 if (s)
427 {
428 for (; *s; ++s)
429 {
430 *s = tolower((unsigned char) *s);
431 }
432 }
433 return ret;
434}
435
436/* Function to return the key for indexing
437 * the argument
438 */
439zAVLKey sh_avl_key (void const * arg)
440{
441 const client_t * sa = (const client_t *) arg;
442 return (zAVLKey) sa->hostname;
443}
444
445zAVLTree * all_clients = NULL;
446
447void sh_xfer_html_write()
448{
449 SL_ENTER(_("sh_xfer_html_write"));
450 sh_html_write(all_clients);
451 SL_RET0(_("sh_xfer_html_write"));
452}
453
454
455int sh_xfer_use_clt_class (const char * c)
456{
457 int i;
458 SL_ENTER(_("sh_xfer_use_clt_class"));
459 i = sh_util_flagval(c, &(sh.flag.client_class));
460 SL_RETURN(i, _("sh_xfer_use_clt_class"));
461}
462
463int sh_xfer_use_clt_sev (const char * c)
464{
465 int i;
466 SL_ENTER(_("sh_xfer_use_clt_sev"));
467 i = sh_util_flagval(c, &(sh.flag.client_severity));
468 SL_RETURN(i, _("sh_xfer_use_clt_sev"));
469}
470
471
472/* the destructor
473 */
474void free_client(void * inptr)
475{
476 client_t * here;
477
478 SL_ENTER(_("free_client"));
479 if (inptr == NULL)
480 SL_RET0(_("free_client"));
481 else
482 here = (client_t *) inptr;
483
484 if (here->hostname != NULL)
485 SH_FREE(here->hostname);
486 if (here->salt != NULL)
487 SH_FREE(here->salt);
488 if (here->verifier != NULL)
489 SH_FREE(here->verifier);
490 SH_FREE(here);
491 SL_RET0(_("free_client"));
492}
493
494
495int sh_xfer_register_client (const char * str)
496{
497 client_t * newclt;
498 client_t * testclt;
499
500 const char * ptr;
501 int sepnum = 0;
502 int sep[2];
503 register int i = 0;
504 int siz_str = 0;
505
506 SL_ENTER(_("sh_xfer_register_client"));
507
508 ptr = str;
509 while (*ptr) {
510 if (*ptr == '@' && sepnum < 2 )
511 {
512 sep[sepnum] = i;
513 ++sepnum;
514 }
515 ++ptr; ++i;
516 }
517
518 if (all_clients == NULL)
519 {
520 all_clients = zAVLAllocTree (sh_avl_key, zAVL_KEY_STRING);
521 if (all_clients == NULL)
522 {
523 (void) safe_logger (0, 0, NULL);
524 aud__exit(FIL__, __LINE__, EXIT_FAILURE);
525 }
526 }
527
528 if ((sepnum == 2) && (sep[0] > 0) && (sep[1] > sep[0]))
529 {
530 newclt = SH_ALLOC (sizeof(client_t));
531 newclt->hostname = SH_ALLOC (sep[0]+1);
532 newclt->salt = SH_ALLOC (sep[1]-sep[0]);
533 newclt->verifier = SH_ALLOC (sl_strlen(str)-sep[1]+1);
534 newclt->exit_flag = 0;
535 newclt->dead_flag = 0;
536#ifdef SH_ENCRYPT
537 newclt->encf_flag = SH_PROTO_ENC;
538 newclt->ency_flag = SH_PROTO_ENC;
539#else
540 newclt->encf_flag = 0;
541 newclt->ency_flag = 0;
542#endif
543 newclt->ivst_flag = 0;
544 newclt->session_key[0] = '\0';
545 newclt->last_connect = (time_t) 0;
546 newclt->session_key_timer = (time_t) 0;
547 newclt->status_now = CLT_INACTIVE;
548 for (i = 0; i < CLT_MAX; ++i)
549 newclt->status_arr[i] = CLT_INACTIVE;
550 (void) sh_unix_time(0, newclt->timestamp[CLT_INACTIVE], TIM_MAX);
551
552 /* truncate */
553 sl_strlcpy(newclt->hostname, &str[0], sep[0]+1);
554 sh_tolower(newclt->hostname);
555
556 /* truncate */
557 sl_strlcpy(newclt->salt, &str[sep[0]+1], sep[1]-sep[0]);
558 sl_strlcpy(newclt->verifier, &str[sep[1]+1], sl_strlen(str)-sep[1]+1);
559
560 testclt = (client_t *) zAVLSearch (all_clients, newclt->hostname);
561
562 if (testclt != NULL)
563 {
564 SH_FREE(testclt->verifier);
565 siz_str = strlen (newclt->verifier) + 1;
566 testclt->verifier = SH_ALLOC (siz_str);
567 sl_strlcpy(testclt->verifier, newclt->verifier, siz_str);
568
569 SH_FREE(testclt->salt);
570 siz_str = strlen (newclt->salt) + 1;
571 testclt->salt = SH_ALLOC (siz_str);
572 sl_strlcpy(testclt->salt, newclt->salt, siz_str);
573
574 testclt->dead_flag = 0;
575
576 free_client(newclt);
577 SL_RETURN( 0, _("sh_xfer_register_client"));
578 }
579 else
580 {
581 if (0 == zAVLInsert (all_clients, newclt))
582 {
583 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CREG,
584 newclt->hostname,
585 newclt->salt, newclt->verifier);
586 SL_RETURN( 0, _("sh_xfer_register_client"));
587 }
588 }
589 }
590 SL_RETURN (-1, _("sh_xfer_register_client"));
591}
592
593typedef struct {
594 int state;
595 int fd;
596 char * buf;
597 unsigned char head[SH_HEADER_SIZE];
598 char challenge[SH_CHALLENGE_SIZE];
599 char peer[SH_MINIBUF+1];
600 client_t * client_entry;
601 char * K;
602 char * M1;
603 char * A;
604 int headcount;
605 unsigned long bytecount;
606 unsigned long bytes_to_send;
607 unsigned long bytes_to_get;
608 int pass;
609 unsigned long timer;
610
611 char * FileName;
612 unsigned long FileLength;
613 unsigned long FileSent;
614 char FileType[5];
615
616 struct sh_sockaddr addr_peer;
617} sh_conn_t;
618
619
620static char zap_challenge[SH_CHALLENGE_SIZE] = { 0 };
621
622void sh_xfer_do_free (sh_conn_t * conn)
623{
624 SL_ENTER(_("sh_xfer_do_free"));
625
626 if (conn->K != NULL)
627 {
628 SH_FREE(conn->K);
629 conn->K = NULL;
630 }
631 if (conn->A != NULL)
632 {
633 SH_FREE(conn->A);
634 conn->A = NULL;
635 }
636 if (conn->M1 != NULL)
637 {
638 SH_FREE(conn->M1);
639 conn->M1 = NULL;
640 }
641 if (conn->buf != NULL)
642 {
643 SH_FREE(conn->buf);
644 conn->buf = NULL;
645 }
646 if (conn->fd != (-1))
647 {
648 sl_close_fd (FIL__, __LINE__, conn->fd);
649 conn->fd = -1;
650 }
651 memcpy(conn->challenge, zap_challenge, SH_CHALLENGE_SIZE);
652 conn->state = CONN_FREE;
653 conn->headcount = 0;
654 conn->bytecount = 0;
655 conn->bytes_to_send = 0;
656 conn->bytes_to_get = 0;
657 conn->pass = 0;
658 conn->timer = 0;
659 conn->client_entry = NULL;
660
661 if (conn->FileName != NULL)
662 {
663 SH_FREE(conn->FileName);
664 conn->FileName = NULL;
665 }
666 conn->FileLength = 0;
667 conn->FileSent = 0;
668 conn->FileType[0] = '\0';
669 conn->FileType[1] = '\0';
670 conn->FileType[2] = '\0';
671 conn->FileType[3] = '\0';
672 conn->FileType[4] = '\0';
673
674 --server_status.conn_open;
675
676 SL_RET0(_("sh_xfer_do_free"));
677}
678
679/****************************************
680 *
681 * -- Reconfiguration. --
682 *
683 * (1) Mark all clients as 'dead'.
684 * (2) Reload configuration - clients
685 * in config are non-dead now.
686 * (3) Remove all clients still
687 * marked as 'dead'.
688 */
689
690/* -- Mark all clients as dead.
691 */
692void sh_xfer_mark_dead (void)
693{
694 zAVLCursor avlcursor;
695 client_t * item;
696
697 SL_ENTER(_("sh_xfer_mark_dead"));
698
699 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
700 item = (client_t *) zAVLNext(&avlcursor))
701 {
702 item->dead_flag = 1;
703 }
704 SL_RET0(_("sh_xfer_mark_dead"));
705}
706
707
708/* -- Clean tree from dead clients.
709 */
710void sh_xfer_clean_tree (void)
711{
712 zAVLCursor avlcursor;
713 client_t * item;
714
715 SL_ENTER(_("sh_xfer_clean_tree"));
716
717 repeat_search:
718
719 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
720 item = (client_t *) zAVLNext(&avlcursor))
721 {
722 if (item->dead_flag == 1)
723 {
724 zAVLDelete (all_clients, item->hostname);
725 free_client (item);
726 goto repeat_search;
727 }
728 }
729 SL_RET0(_("sh_xfer_clean_tree"));
730}
731
732/*
733 *
734 **********************************************/
735
736
737
738/* -- SERVER SEND FUNCTION. --
739 */
740void sh_xfer_prep_send_int (sh_conn_t * conn,
741 char * msg, unsigned long length,
742 char * u, char protocol,
743 int docrypt)
744{
745 /* register unsigned long i; */
746 unsigned long length2;
747
748#if !defined(SH_ENCRYPT)
749 (void) docrypt;
750#endif
751
752 SL_ENTER(_("sh_xfer_prep_send_int"));
753
754 TPT((0, FIL__, __LINE__, _("msg=<%s>, docrypt=<%d>\n"), msg, docrypt ));
755
756 length2 = length;
757
758 conn->headcount = 0;
759 conn->bytecount = 0;
760 conn->bytes_to_send = 0;
761 conn->bytes_to_get = 0;
762
763 if (conn->buf != NULL)
764 {
765 SH_FREE(conn->buf);
766 conn->buf = NULL;
767 }
768
769 put_header (conn->head, protocol, &length2, u);
770 SH_SHOWPROT(conn->head,'>');
771
772 TPT((0, FIL__, __LINE__, _("msg=<put_header done>\n") ));
773
774 if (msg == NULL)
775 length2 = 0;
776
777#ifdef SH_ENCRYPT
778 if ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
779 {
780 TPT((0, FIL__, __LINE__, _("encrypting (version 2)\n")));
781
782 conn->buf = sh_tools_makePack (conn->head, conn->client_entry->ivst_flag,
783 msg, length2,
784 &(conn->client_entry->keyInstE));
785 }
786 else if (msg == NULL)
787 {
788 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
789 _("msg is NULL"),
790 _("sh_xfer_prep_send_int: cipherInit"));
791 }
792 else
793 {
794 if ((length2 + 1) < length2) --length2;
795 conn->buf = SH_ALLOC(length2 + 1);
796
797 memcpy(conn->buf, msg, length2);
798 conn->buf[length2] = '\0';
799 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
800 }
801#else
802 if ((length2 + 1) < length2) --length2;
803 conn->buf = SH_ALLOC(length2 + 1);
804
805 memcpy(conn->buf, msg, length2);
806 conn->buf[length2] = '\0';
807 TPT((0, FIL__, __LINE__, _("msg=<no encryption done>\n") ));
808#endif
809
810 conn->state = CONN_SENDING;
811 SL_RET0(_("sh_xfer_prep_send_int"));
812}
813
814/* -- Send/Receive. --
815 */
816void sh_xfer_prep_send (sh_conn_t * conn,
817 char * msg, unsigned long length,
818 char * u, char protocol)
819{
820 SL_ENTER(_("sh_xfer_prep_send"));
821 sh_xfer_prep_send_int (conn, msg, length, u, protocol, S_FALSE);
822 SL_RET0(_("sh_xfer_prep_send"));
823}
824
825void sh_xfer_send_crypt (sh_conn_t * conn,
826 char * msg, unsigned long length,
827 char * u, char protocol)
828{
829 SL_ENTER(_("sh_xfer_send_crypt"));
830 sh_xfer_prep_send_int (conn, msg, length, u, protocol, S_TRUE);
831 SL_RET0(_("sh_xfer_send_crypt"));
832}
833
834/* #include <sys/times.h> */
835
836#if defined(WITH_EXTERNAL)
837#include "sh_extern.h"
838#endif
839
840/* -- Update the client status. --
841 *
842 * Update the status array for the client,
843 * and eventually call external program.
844 */
845static void status_update (client_t * conn, int status)
846{
847#if defined(WITH_EXTERNAL)
848 char msg[2 * SH_MINIBUF + TIM_MAX + 3];
849#endif
850
851 SL_ENTER(_("status_update"));
852
853 if (conn == NULL ||
854 status < 0 || status >= CLT_MAX)
855 SL_RET0(_("status_update"));
856
857 conn->status_now = status;
858 conn->status_arr[status] = status;
859 (void) sh_unix_time(0, conn->timestamp[status], TIM_MAX);
860
861#if defined(WITH_EXTERNAL)
862 sl_snprintf(msg, sizeof(msg), _("%s %s %s"),
863 conn->hostname, conn->timestamp[status], _(clt_stat[status]));
864 sh_ext_execute('s', 'r', 'v', msg, 0);
865#endif
866
867 SL_RET0(_("status_update"));
868}
869
870static time_t time_client_limit = 86400;
871
872int sh_xfer_set_time_limit (const char * c)
873{
874 long val;
875
876 SL_ENTER(_("sh_xfer_set_time_limit"));
877
878 val = strtol (c, (char **)NULL, 10);
879 if (val <= 0)
880 SL_RETURN( (-1), _("sh_xfer_set_time_limit"));
881
882 time_client_limit = (time_t) val;
883 SL_RETURN( (0), _("sh_xfer_set_time_limit"));
884}
885
886
887/* -- Check for time limit exceeded. --
888 */
889static int client_time_check(void)
890{
891 zAVLCursor avlcursor;
892 client_t * item;
893
894 SL_ENTER(_("client_time_check"));
895
896 if (time_client_limit == (time_t) 0)
897 SL_RETURN( 0, _("client_time_check"));
898
899 for (item = (client_t *) zAVLFirst(&avlcursor, all_clients); item;
900 item = (client_t *) zAVLNext(&avlcursor))
901 {
902 if (item->exit_flag == 0 && item->last_connect != (time_t) 0)
903 {
904 if ( (time(NULL) - item->last_connect) > time_client_limit)
905 {
906 if (item->status_now != CLT_TOOLONG)
907 {
908 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMEXC,
909 item->hostname);
910 status_update (item, CLT_TOOLONG);
911 }
912 }
913 }
914 }
915 SL_RETURN( 0, _("client_time_check"));
916}
917
918static int lookup_err = SH_ERR_SEVERE;
919
920int sh_xfer_lookup_level (const char * c)
921{
922 int ci = sh_error_convert_level (c);
923
924 SL_ENTER(_("sh_xfer_lookup_level"));
925
926 if (ci >= 0)
927 {
928 lookup_err = ci;
929 SL_RETURN( 0, _("sh_xfer_lookup_level"));
930 }
931 else
932 SL_RETURN( (-1), _("sh_xfer_lookup_level"));
933}
934
935#ifndef MAXHOSTNAMELEN
936#define MAXHOSTNAMELEN 127
937#endif
938
939int check_addr (const char * claim, struct sh_sockaddr * addr_peer)
940{
941 char h_name[MAXHOSTNAMELEN + 1];
942 char h_peer[MAXHOSTNAMELEN + 1];
943 char h_peer_IP[SH_IP_BUF];
944 char tmp_peer_IP[SH_IP_BUF];
945 char * canonical;
946 char numeric[SH_IP_BUF];
947
948 SL_ENTER(_("check_addr"));
949
950 if (claim == NULL)
951 {
952 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
953 _("NULL input"), _("check_addr"));
954 SL_RETURN ((-1), _("check_addr"));
955 }
956
957 /* Make sure we have the canonical name for the client
958 */
959 canonical = sh_ipvx_canonical(claim, numeric, sizeof(numeric));
960
961 /* copy canonical name into h_name
962 */
963 if (canonical != NULL)
964 {
965 sl_strlcpy(h_name, canonical, MAXHOSTNAMELEN + 1);
966 SH_FREE(canonical);
967 }
968 else
969 {
970 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESCLT,
971 claim);
972 SL_RETURN ((0), _("check_addr"));
973 }
974
975
976 /* get canonical name of socket peer
977 */
978 canonical = sh_ipvx_addrtoname(addr_peer);
979
980 if (canonical)
981 {
982 if (0 == sl_strcmp(canonical, _("localhost")))
983 sl_strlcpy(h_peer, sh.host.name, MAXHOSTNAMELEN + 1);
984 else
985 sl_strlcpy(h_peer, canonical, MAXHOSTNAMELEN + 1);
986 SH_FREE(canonical);
987 }
988 else
989 {
990 sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
991 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_RESPEER,
992 claim, tmp_peer_IP);
993 SL_RETURN ((0), _("check_addr"));
994 }
995
996 sh_ipvx_ntoa (h_peer_IP, sizeof(h_peer_IP), addr_peer);
997
998 /* reverse lookup
999 */
1000 if (0 == sh_ipvx_reverse_check_ok (h_peer, ServerPort, addr_peer))
1001 {
1002 sh_ipvx_ntoa (tmp_peer_IP, sizeof(tmp_peer_IP), addr_peer);
1003
1004 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKERS,
1005 claim, h_peer, tmp_peer_IP);
1006 SL_RETURN ((0), _("check_addr"));
1007 }
1008
1009 /* Check whether claim and peer are identical
1010 */
1011 sh_tolower(h_peer); /* Canonical name of what the peer is */
1012 sh_tolower(h_name); /* Canonical name of what the peer claims */
1013
1014 if ((0 == sl_strcmp(h_peer, h_name)) || (0 == sl_strcmp(h_peer_IP, h_name)))
1015 {
1016 SL_RETURN ((0), _("check_addr"));
1017 }
1018#if !defined(USE_IPVX)
1019 else
1020 {
1021 struct hostent * he = sh_gethostbyname(h_peer);
1022 int i = 0;
1023 int flag = 0;
1024
1025 while (he->h_aliases[i] != NULL)
1026 {
1027 if (0 == sl_strcmp(sh_tolower(he->h_aliases[i]), h_name))
1028 {
1029 flag = 1;
1030 break;
1031 }
1032 ++i;
1033 }
1034 if (flag == 0)
1035 sh_error_handle(lookup_err, FIL__, __LINE__, 0, MSG_TCP_LOOKUP,
1036 claim, h_peer);
1037 }
1038#endif
1039
1040 SL_RETURN ((0), _("check_addr"));
1041}
1042
1043static int UseSocketPeer = S_FALSE;
1044
1045int set_socket_peer (const char * c)
1046{
1047 return sh_util_flagval(c, &UseSocketPeer);
1048}
1049
1050
1051/* -- Search register. --
1052 */
1053client_t * search_register(sh_conn_t * conn, int pos)
1054{
1055 client_t * this_client;
1056 char peer_ip[SH_IP_BUF];
1057 char numerical[SH_IP_BUF];
1058 char peer_name[MAXHOSTNAMELEN+1];
1059 char * search_string;
1060
1061 struct sh_sockaddr peer_addr;
1062 char * canonical;
1063
1064 SL_ENTER(_("search_register"));
1065
1066 if (UseSocketPeer == S_TRUE)
1067 {
1068 memcpy(&peer_addr, &(conn->addr_peer), sizeof(struct sh_sockaddr));
1069 sh_ipvx_ntoa (peer_ip, sizeof(peer_ip), &peer_addr);
1070 peer_name[0] = '\0';
1071
1072 /* get canonical name of socket peer
1073 */
1074 canonical = sh_ipvx_canonical(peer_ip, numerical, sizeof(numerical));
1075
1076 if (canonical != NULL)
1077 {
1078 if (0 == sl_strcmp(canonical, _("localhost")))
1079 sl_strlcpy(peer_name, sh.host.name, MAXHOSTNAMELEN + 1);
1080 else
1081 sl_strlcpy(peer_name, canonical, MAXHOSTNAMELEN + 1);
1082 SH_FREE(canonical);
1083 }
1084
1085 if (0 == sh_ipvx_reverse_check_ok (peer_name, ServerPort, &peer_addr))
1086 {
1087 sl_strlcpy(peer_name, peer_ip, MAXHOSTNAMELEN + 1);
1088 }
1089
1090 search_string = peer_name;
1091 }
1092 else
1093 {
1094 search_string = &(conn->buf[pos]);
1095
1096 if (0 != check_addr (search_string, &(conn->addr_peer)))
1097 {
1098 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
1099 _("Reverse lookup failed"), search_string);
1100 sh_xfer_do_free (conn);
1101 SL_RETURN( NULL, _("search_register"));
1102 }
1103 }
1104
1105 sh_tolower(search_string);
1106
1107 /* ---- search the register -----
1108 */
1109 this_client = zAVLSearch(all_clients, search_string);
1110
1111 if (this_client == NULL)
1112 {
1113 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
1114 _("Not in client list"), search_string);
1115 sh_xfer_do_free (conn);
1116 SL_RETURN( NULL, _("search_register"));
1117 }
1118 if (this_client->exit_flag == 1)
1119 {
1120 TPT((0, FIL__, __LINE__, _("msg=<this_client->exit_flag == 1>\n")));
1121 this_client->session_key_timer = (time_t) 0;
1122 this_client->session_key[0] = '\0';
1123 this_client->exit_flag = 0;
1124 }
1125 TPT((0, FIL__, __LINE__, _("msg=<search_register: client %s>\n"),
1126 this_client->hostname));
1127 TPT((0, FIL__, __LINE__, _("msg=<search_register: key %s>\n"),
1128 this_client->session_key));
1129 SL_RETURN( this_client, _("search_register"));
1130}
1131
1132client_t * do_check_client(sh_conn_t * conn, int * retval)
1133{
1134 client_t * this_client = NULL;
1135 char sigbuf[KEYBUF_SIZE];
1136
1137 *retval = 0;
1138
1139 TPT(( 0, FIL__, __LINE__, _("msg=<Client connect - HELO (1).>\n")));
1140
1141 if (conn->buf == NULL || sl_strlen(conn->buf) <= KEY_LEN)
1142 {
1143 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
1144 sh_xfer_do_free (conn);
1145 return NULL;
1146 }
1147
1148 /* ---- search the register -----
1149 */
1150
1151 this_client = search_register (conn, KEY_LEN);
1152 if (this_client == NULL)
1153 return NULL;
1154
1155 /* ---- force authentication -----
1156 */
1157
1158 if (this_client->session_key[0] == '\0' ||
1159 (time(NULL) - this_client->session_key_timer)
1160 > (time_t) TIMEOUT_KEY )
1161 {
1162 size_t len;
1163
1164 /* fake an auth request and jump there
1165 */
1166 conn->head[0] = (conn->head[0] | SH_PROTO_SRP);
1167 conn->head[3] = 'S';
1168 conn->head[4] = 'A';
1169 conn->head[5] = 'L';
1170 conn->head[6] = 'T';
1171 if (flag_err_info == S_TRUE)
1172 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FAUTH,
1173 &(conn->buf[KEY_LEN]));
1174 len = sl_strlen(&(conn->buf[KEY_LEN])) + 1;
1175 /* may overlap, thus only memmove is correct */
1176 memmove(conn->buf, &(conn->buf[KEY_LEN]), len);
1177 this_client->session_key[0] = '\0';
1178 this_client->session_key_timer = (time_t) 1;
1179 *retval = -1;
1180 return NULL;
1181 }
1182
1183 /* --- check whether hostname is properly signed ---
1184 */
1185 if (conn->K != NULL)
1186 {
1187 SH_FREE(conn->K);
1188 conn->K = NULL;
1189 }
1190
1191 conn->K = SH_ALLOC(KEY_LEN+1);
1192
1193 sl_strlcpy (conn->K,
1194 sh_util_siggen(this_client->session_key,
1195 &(conn->buf[KEY_LEN]),
1196 sl_strlen(&(conn->buf[KEY_LEN])),
1197 sigbuf, sizeof(sigbuf)),
1198 KEY_LEN+1);
1199
1200 if (0 != sl_ts_strncmp(conn->K, conn->buf, KEY_LEN))
1201 {
1202 TPT((0, FIL__, __LINE__, _("msg=<clt %s>\n"), conn->buf));
1203 TPT((0, FIL__, __LINE__, _("msg=<srv %s>\n"), conn->K));
1204 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
1205 _("Signature mismatch"),
1206 &(conn->buf[KEY_LEN]));
1207
1208 this_client->session_key_timer =
1209 time(NULL) - (2*TIMEOUT_KEY);
1210
1211 sh_xfer_do_free (conn);
1212 return NULL;
1213 }
1214 SH_FREE(conn->K);
1215 conn->K = NULL;
1216
1217 return this_client;
1218}
1219
1220/* ------------------------------------------------------
1221 *
1222 * FILE TRANSFER
1223 *
1224 * ------------------------------------------------------ */
1225
1226static void do_file_send_data(sh_conn_t * conn)
1227{
1228 char * read_buf = 0;
1229 char * send_buf;
1230 int bytes;
1231 SL_TICKET sfd = -1;
1232
1233 if (conn == NULL || conn->FileName == NULL)
1234 {
1235 sh_error_handle((-1), FIL__, __LINE__, sfd, MSG_TCP_NFILE,
1236 conn->peer,
1237 (conn->FileName == NULL) ?
1238 _("(NULL)") : conn->FileName);
1239 status_update (conn->client_entry, CLT_FAILED);
1240 sh_xfer_do_free (conn);
1241 return;
1242 }
1243
1244 if (conn->FileSent == conn->FileLength)
1245 {
1246 send_buf = hash_me(conn->K, conn->peer, sl_strlen(conn->peer));
1247#ifdef SH_ENCRYPT
1248 sh_xfer_send_crypt (conn, send_buf, sl_strlen(conn->peer)+KEY_LEN,
1249 _("EEOT"), SH_PROTO_BIG|conn->client_entry->encf_flag);
1250#else
1251 sh_xfer_send_crypt (conn, send_buf, sl_strlen(conn->peer)+KEY_LEN,
1252 _("EEOT"), SH_PROTO_BIG);
1253#endif
1254 SH_FREE(send_buf);
1255 }
1256 else
1257 {
1258 bytes = -1;
1259
1260 sfd = sl_open_read(FIL__, __LINE__, conn->FileName, SL_YESPRIV);
1261
1262 if (!SL_ISERROR(sfd))
1263 {
1264 read_buf = SH_ALLOC(TRANS_BYTES);
1265 if (conn->FileSent > 0)
1266 sl_seek (sfd, (off_t) conn->FileSent);
1267 bytes = sl_read (sfd, read_buf, TRANS_BYTES);
1268 sl_close(sfd);
1269 }
1270 else
1271 {
1272 sh_error_handle((-1), FIL__, __LINE__, sfd,
1273 MSG_E_ACCESS, (long) geteuid(), conn->FileName);
1274 }
1275
1276 if (bytes >= 0)
1277 {
1278 send_buf = hash_me(conn->K, read_buf, bytes);
1279#ifdef SH_ENCRYPT
1280 sh_xfer_send_crypt (conn, send_buf, bytes+KEY_LEN, _("FILE"),
1281 SH_PROTO_BIG|conn->client_entry->encf_flag);
1282#else
1283 sh_xfer_send_crypt (conn, send_buf, bytes+KEY_LEN, _("FILE"),
1284 SH_PROTO_BIG);
1285#endif
1286 conn->FileSent += bytes;
1287 if (send_buf) /* hash_me() *may* return NULL */
1288 SH_FREE(send_buf);
1289 SH_FREE(read_buf);
1290 }
1291 else
1292 {
1293 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NFILE, conn->peer,
1294 (conn->FileName == NULL) ? _("(NULL)") : conn->FileName);
1295 status_update (conn->client_entry, CLT_FAILED);
1296 sh_xfer_do_free (conn);
1297 }
1298 }
1299 return;
1300}
1301
1302static void do_file_initial(sh_conn_t * conn)
1303{
1304 char * ptok;
1305 char hashbuf[KEYBUF_SIZE];
1306
1307 /* --- get client nonce and compute hash ---
1308 *
1309 * K = H(NSRV, NCLT, session_key)
1310 */
1311 if (conn->A != NULL)
1312 {
1313 SH_FREE(conn->A);
1314 conn->A = NULL;
1315 }
1316 conn->A = SH_ALLOC(3*KEY_LEN+1);
1317 sl_strlcpy (conn->A, conn->K, KEY_LEN+1);
1318 sl_strlcat(conn->A, conn->buf, /* truncate */
1319 2*KEY_LEN+1);
1320 sl_strlcat(conn->A, conn->client_entry->session_key,
1321 3*KEY_LEN+1);
1322 sl_strlcpy (conn->K, sh_tiger_hash(conn->A,TIGER_DATA,3*KEY_LEN,
1323 hashbuf, sizeof(hashbuf)),
1324 KEY_LEN+1);
1325 SH_FREE(conn->A);
1326 conn->A = NULL;
1327
1328
1329 /* Warn about encryption mismatch
1330 */
1331#ifdef SH_ENCRYPT
1332 if ((conn->client_entry->encf_flag != 0) && /* server */
1333 ((conn->head[0] & SH_PROTO_ENC) == 0)) /* client */
1334 {
1335 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
1336 _("file download"), _("version2"), _("none"));
1337 }
1338
1339 else if ((conn->client_entry->encf_flag != 0) && /* server */
1340 ((conn->head[0] & SH_MASK_ENC) != /* client */
1341 conn->client_entry->encf_flag))
1342 {
1343 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
1344 _("file download"), _("version2"),
1345 ((conn->head[0] & SH_PROTO_ENC) == SH_PROTO_ENC) ?
1346 _("version2") : _("invalid"));
1347 conn->client_entry->encf_flag = (conn->head[0] & SH_MASK_ENC);
1348 }
1349#else
1350 if ((conn->head[0] & SH_PROTO_ENC) != 0)
1351 {
1352 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
1353 _("file download"), _("none"),
1354 ((conn->head[0] & SH_PROTO_ENC) == SH_PROTO_ENC) ?
1355 _("version2") : _("invalid"));
1356 }
1357#endif
1358
1359
1360 if (conn->FileName != NULL)
1361 {
1362 SH_FREE(conn->FileName);
1363 conn->FileName = NULL;
1364 }
1365
1366 /* Determine what to send
1367 */
1368 if (0 == sl_strncmp (_("CONF"), &(conn->buf[KEY_LEN]), 4))
1369 {
1370 strcpy(conn->FileType, _("CONF")); /* known to fit */
1371 conn->FileName = get_client_conf_file(conn->peer, &(conn->FileLength));
1372 conn->FileSent = 0;
1373 }
1374 else if (0 == sl_strncmp (_("DATA"), &(conn->buf[KEY_LEN]), 4))
1375 {
1376 strcpy(conn->FileType, _("DATA")); /* known to fit */
1377 conn->FileName = get_client_data_file(conn->peer, &(conn->FileLength));
1378 conn->FileSent = 0;
1379 }
1380 else if (0 == sh_uuid_check(&(conn->buf[KEY_LEN])))
1381 {
1382 char * uuid = &(conn->buf[KEY_LEN]);
1383 strcpy(conn->FileType, _("UUID")); /* known to fit */
1384 conn->FileName = get_client_uuid_file(conn->peer, &(conn->FileLength), uuid);
1385 conn->FileSent = 0;
1386 }
1387 else
1388 {
1389 ptok = sh_util_safe_name(&(conn->buf[KEY_LEN]));
1390 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FFILE,
1391 conn->peer,
1392 ptok);
1393 SH_FREE(ptok);
1394 status_update (conn->client_entry, CLT_FAILED);
1395 sh_xfer_do_free (conn);
1396 }
1397
1398 return;
1399}
1400
1401
1402static int do_file_transfer(sh_conn_t * conn, int state)
1403{
1404 client_t * this_client;
1405 UINT32 ticks;
1406 char hashbuf[KEYBUF_SIZE];
1407
1408 SL_ENTER(_("do_file_transfer"));
1409
1410 if (state == SH_DO_READ) /* finished reading */
1411 {
1412 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
1413
1414 /* -- Client requests challenge. --
1415 */
1416 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
1417 {
1418 int client_state;
1419
1420 this_client = do_check_client(conn, &client_state);
1421 if (!this_client)
1422 SL_RETURN(client_state, _("do_file_transfer"));
1423
1424 /* --- create and send a nonce ---
1425 */
1426
1427 conn->client_entry = this_client;
1428 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
1429
1430 ticks = (UINT32) taus_get ();
1431
1432 if (conn->K != NULL)
1433 {
1434 SH_FREE(conn->K);
1435 conn->K = NULL;
1436 }
1437 conn->K = SH_ALLOC(KEY_LEN+1);
1438 sl_strlcpy (conn->K,
1439 sh_tiger_hash ((char *) &ticks,
1440 TIGER_DATA, sizeof(UINT32),
1441 hashbuf, sizeof(hashbuf)),
1442 KEY_LEN+1);
1443
1444 TPT((0, FIL__, __LINE__, _("msg=<send nonce>\n")));
1445 sh_xfer_prep_send (conn, conn->K, KEY_LEN+1, _("NSRV"),
1446 SH_PROTO_BIG);
1447 }
1448
1449 /* --- Client has send a message. Check state and message. ---
1450 */
1451 else if (0 == check_request_nerr((char *)&(conn->head[3]), _("NCLT")) &&
1452 conn->client_entry != NULL &&
1453 sl_strlen(conn->buf) > KEY_LEN &&
1454 conn->K != NULL)
1455 {
1456
1457 TPT(( 0, FIL__, __LINE__,
1458 _("msg=<File transfer - NCLT (3).>\n")));
1459
1460 do_file_initial(conn);
1461 do_file_send_data(conn);
1462 }
1463
1464 else if (0 == check_request_nerr((char *)&(conn->head[3]),
1465 _("RECV")) &&
1466 conn->client_entry != NULL &&
1467 conn->K != NULL &&
1468 conn->FileName != NULL)
1469 {
1470
1471 TPT(( 0, FIL__, __LINE__,
1472 _("msg=<File transfer - RCVT (5+).>\n")));
1473
1474 do_file_send_data(conn);
1475 }
1476
1477
1478 else if (0 == check_request_nerr((char *)&(conn->head[3]),
1479 _("EOTE")) &&
1480 conn->client_entry != NULL)
1481 {
1482
1483 TPT(( 0, FIL__, __LINE__,
1484 _("msg=<File transfer - EOTE (7).>\n")));
1485
1486 if (flag_err_info == S_TRUE)
1487 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKFILE,
1488 conn->peer);
1489
1490 if ((conn->client_entry->status_now != CLT_SUSPEND) &&
1491 (conn->client_entry->status_now != CLT_TOOLONG))
1492 { status_update (conn->client_entry, CLT_FILE); }
1493 else
1494 { conn->client_entry->session_key[0] = '\0'; }
1495 conn->client_entry->last_connect = time (NULL);
1496 sh_xfer_do_free (conn);
1497 }
1498
1499
1500 /* client does something unexpected
1501 */
1502 else /* ---- ??? ----- */
1503 {
1504 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
1505 1, conn->pass, conn->peer,
1506 '\\', conn->head[3], '\\',conn->head[4],
1507 '\\', conn->head[5], '\\',conn->head[6]);
1508 status_update (conn->client_entry, CLT_FAILED);
1509 sh_xfer_do_free (conn);
1510 }
1511 }
1512
1513 else if (state == SH_DO_WRITE) /* finished writing */
1514 {
1515 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - (wait).>\n")));
1516
1517 /* challenge is sent, now wait for message from client
1518 */
1519 conn->headcount = 0;
1520 conn->bytecount = 0;
1521 conn->bytes_to_send = 0;
1522 conn->bytes_to_get = 0;
1523 if (conn->buf != NULL)
1524 {
1525 SH_FREE(conn->buf);
1526 conn->buf = NULL;
1527 }
1528 conn->state = CONN_READING;
1529 }
1530 SL_RETURN(0, _("do_file_transfer"));
1531}
1532
1533/* ------------------------------------------------------
1534 *
1535 * MESSAGE TRANSFER
1536 *
1537 * ------------------------------------------------------ */
1538static int do_message_transfer(sh_conn_t * conn, int state)
1539{
1540 client_t * this_client;
1541 char * cmd;
1542 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
1543 char * buffer;
1544 int clt_sev;
1545 char * ptok;
1546 UINT32 ticks;
1547 size_t len;
1548 int i;
1549 char * test;
1550 char sigbuf[KEYBUF_SIZE];
1551
1552 SL_ENTER(_("do_message_transfer"));
1553
1554 if (state == SH_DO_READ) /* finished reading */
1555 {
1556 TPT(( 0, FIL__, __LINE__, _("msg=<File transfer - entry.>\n")));
1557
1558 /* -- Client requests challenge. --
1559 */
1560 if (0 == check_request_nerr ((char *) &(conn->head[3]), _("HELO")))
1561 {
1562 int client_state;
1563
1564 this_client = do_check_client(conn, &client_state);
1565 if (!this_client)
1566 SL_RETURN(client_state, _("do_message_transfer"));
1567
1568
1569 /* -- create a nonce and send it --
1570 */
1571 conn->client_entry = this_client;
1572 sl_strlcpy (conn->peer, &(conn->buf[KEY_LEN]), SH_MINIBUF+1);
1573
1574 ticks = (UINT32) taus_get ();
1575
1576 test = (char *) &ticks;
1577 sh_util_cpylong (conn->challenge, test, 4);
1578 conn->challenge[4] = '\0';
1579 for (i = 0; i < 4; ++i)
1580 if (conn->challenge[i] == '\0')
1581 conn->challenge[i] = 0x01;
1582
1583 sh_xfer_prep_send (conn, conn->challenge, 5, _("TALK"),
1584 SH_PROTO_MSG);
1585 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s.>\n"),
1586 hu_trans(conn->challenge)));
1587 }
1588
1589 /* Client has send a message. Check whether we are in proper
1590 * state, and verify message.
1591 */
1592 else if (0 ==
1593 check_request_nerr((char *)&(conn->head[3]), _("MESG")) &&
1594 conn->client_entry != NULL &&
1595 conn->client_entry->session_key[0] != '\0' &&
1596 (len = sl_strlen(conn->buf) - KEY_LEN) > 0 &&
1597 sl_strlen(conn->challenge) == 4)
1598 {
1599 TPT(( 0, FIL__, __LINE__,
1600 _("msg=<Message transfer - MESG (3).>\n")));
1601
1602#ifdef SH_ENCRYPT
1603 if (conn->client_entry->encf_flag == 0) {
1604 conn->client_entry->ency_flag = 0;
1605 }
1606 if ((conn->client_entry->ency_flag != 0) &&
1607 ((conn->head[0] & SH_PROTO_ENC) == 0))
1608 {
1609 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISENC,
1610 _("message transfer"),
1611 _("version2"),
1612 _("none"));
1613 }
1614 else if ((conn->client_entry->ency_flag != 0) &&
1615 ((conn->head[0] & SH_MASK_ENC) !=
1616 conn->client_entry->ency_flag))
1617 {
1618 sh_error_handle(SH_ERR_NOTICE, FIL__, __LINE__, 0,
1619 MSG_TCP_MISENC,
1620 _("message transfer"),
1621 _("version2"),
1622 ((conn->head[0] & SH_PROTO_ENC) == SH_PROTO_ENC) ? _("version2") : _("invalid"));
1623 conn->client_entry->ency_flag =
1624 (conn->head[0] & SH_MASK_ENC);
1625 }
1626#else
1627 if ((conn->head[0] & SH_PROTO_ENC) != 0)
1628 {
1629 sh_error_handle((-1), FIL__, __LINE__, 0,
1630 MSG_TCP_MISENC,
1631 _("message transfer"),
1632 _("none"),
1633 ((conn->head[0] & SH_PROTO_ENC) == SH_PROTO_ENC) ? _("version2") : _("invalid"));
1634 }
1635#endif
1636
1637 TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s.>\n"), conn->buf));
1638 /* get hash from message end, truncate message
1639 */
1640 sl_strlcpy(hash, &(conn->buf[len]), KEY_LEN+1);
1641 conn->buf[len] = '\0';
1642
1643 /* verify hash
1644 */
1645 buffer = sh_util_strconcat(conn->buf, conn->challenge, NULL);
1646 i = sl_ts_strncmp(hash,
1647 sh_util_siggen(conn->client_entry->session_key,
1648 buffer,
1649 sl_strlen(buffer),
1650 sigbuf, sizeof(sigbuf)),
1651 KEY_LEN);
1652 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1653 sh_util_siggen(conn->client_entry->session_key,
1654 buffer,
1655 sl_strlen(buffer),
1656 sigbuf, sizeof(sigbuf))));
1657
1658
1659 if (0 != i)
1660 {
1661 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1662 status_update (conn->client_entry, CLT_FAILED);
1663 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
1664 _("Msg signature mismatch"), conn->peer);
1665 conn->client_entry->session_key_timer =
1666 time(NULL) - (2*TIMEOUT_KEY);
1667 sh_xfer_do_free (conn);
1668 SL_RETURN(0, _("do_message_transfer"));
1669 }
1670 else
1671 {
1672 conn->client_entry->last_connect = time (NULL);
1673
1674 if (NULL != sl_strstr(conn->buf, _("EXIT")))
1675 {
1676 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1677 conn->client_entry->exit_flag = 1;
1678 status_update (conn->client_entry, CLT_EXITED);
1679 }
1680 else if (NULL != sl_strstr(conn->buf, _("PANIC")))
1681 {
1682 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1683 status_update (conn->client_entry, CLT_PANIC);
1684 }
1685 else if (NULL != sl_strstr(conn->buf, _("SUSPEND")))
1686 {
1687 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1688 status_update (conn->client_entry, CLT_SUSPEND);
1689 }
1690 else if (NULL != sl_strstr(conn->buf, _("POLICY")))
1691 {
1692 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1693 status_update (conn->client_entry, CLT_POLICY);
1694 }
1695 else if (NULL != sl_strstr(conn->buf,
1696 _("File check completed")))
1697 {
1698 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1699 status_update (conn->client_entry, CLT_CHECK);
1700 }
1701 else if (NULL != sl_strstr(conn->buf, _("START")))
1702 {
1703 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1704 sh_socket_add2reload (conn->client_entry->hostname);
1705 if (conn->client_entry->status_now == CLT_SUSPEND) {
1706 status_update (conn->client_entry, CLT_ILLEGAL);
1707 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
1708 conn->peer);
1709 }
1710 else
1711 status_update (conn->client_entry, CLT_STARTED);
1712 }
1713 else
1714 {
1715 TPT((0, FIL__, __LINE__, _("msg=<update status>\n")));
1716 if (NULL != sl_strstr(conn->buf,
1717 _("Runtime configuration reloaded")))
1718 {
1719 sh_socket_add2reload (conn->client_entry->hostname);
1720 }
1721 status_update (conn->client_entry, CLT_MSG);
1722 }
1723
1724 TPT((0, FIL__, __LINE__, _("msg=<status updated>\n")));
1725 clt_sev = atoi(conn->buf);
1726 clt_class = (-1);
1727 ptok = strchr(conn->buf, '?');
1728 if (ptok != NULL)
1729 {
1730 ++ptok;
1731 if (ptok != NULL && sh.flag.client_class == S_TRUE)
1732 clt_class = atoi(ptok); /* is a global */
1733 ptok = strchr(ptok, '?');
1734 if (ptok != NULL)
1735 ++ptok;
1736 }
1737 if (sh.flag.client_severity == S_FALSE)
1738 clt_sev = (-1);
1739
1740 /* here we expect an xml formatted message, thus we don't
1741 escape xml special chars (flag == 0) */
1742 ptok =
1743 sh_tools_safe_name ((ptok!=NULL) ? ptok : conn->buf, 0);
1744
1745 /* push client name to error routine
1746 */
1747#if defined(SH_WITH_SERVER) && defined(HAVE_LIBPRELUDE)
1748 {
1749 char peer_ip[SH_IP_BUF];
1750 sh_ipvx_ntoa(peer_ip, sizeof(peer_ip), &(conn->addr_peer));
1751 sh_error_set_peer_ip( peer_ip );
1752 }
1753#endif
1754 {
1755 char * pstrip = sh_strip_domain (conn->peer);
1756 sh_error_set_peer(pstrip);
1757 sh_error_handle(clt_sev, FIL__, __LINE__, 0, MSG_TCP_MSG,
1758 pstrip,
1759 ptok);
1760 SH_FREE(pstrip);
1761 sh_error_set_peer(NULL);
1762 }
1763#if defined(SH_WITH_SERVER) && defined(HAVE_LIBPRELUDE)
1764 sh_error_set_peer_ip(NULL);
1765#endif
1766
1767 TPT((0, FIL__, __LINE__, _("msg=<%s>\n"), ptok));
1768 SH_FREE(ptok);
1769 clt_class = (-1);
1770 }
1771 memset(buffer, 0, sl_strlen(buffer));
1772 SH_FREE(buffer);
1773
1774 /* SERVER CONF SEND
1775 */
1776 buffer = sh_util_strconcat(conn->buf,
1777 conn->challenge,
1778 NULL);
1779 sl_strlcpy(hash,
1780 sh_util_siggen ( conn->client_entry->session_key,
1781 buffer,
1782 sl_strlen(buffer),
1783 sigbuf, sizeof(sigbuf)),
1784 KEY_LEN+1);
1785
1786 /* --- SERVER CMD --- */
1787 cmd = sh_socket_check (conn->peer);
1788
1789 if (cmd != NULL)
1790 {
1791 /* max cmd size is SH_MAXMSGLEN bytes
1792 */
1793 sl_strlcpy(&hash[KEY_LEN], cmd, SH_MAXMSGLEN);
1794 sl_strlcat(&hash[KEY_LEN],
1795 sh_util_siggen ( conn->client_entry->session_key,
1796 &hash[KEY_LEN],
1797 sl_strlen(&hash[KEY_LEN]),
1798 sigbuf, sizeof(sigbuf)),
1799 SH_MAXMSGLEN+KEY_LEN+1);
1800
1801 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <%s>\n"),
1802 &hash[KEY_LEN]));
1803
1804 } else {
1805
1806 TPT((0, FIL__, __LINE__, _("CONF SEND <0> <[NULL]>\n")));
1807
1808 }
1809 /* --- SERVER CMD END --- */
1810
1811 TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1812 sh_util_siggen(conn->client_entry->session_key,
1813 buffer,
1814 sl_strlen(buffer),
1815 sigbuf, sizeof(sigbuf))));
1816
1817#ifdef SH_ENCRYPT
1818 sh_xfer_send_crypt (conn, hash,
1819 sl_strlen(hash) /* KEY_LEN */,
1820 _("CONF"),
1821 SH_PROTO_MSG|SH_PROTO_END|conn->client_entry->ency_flag);
1822#else
1823 sh_xfer_send_crypt (conn, hash,
1824 sl_strlen(hash) /* KEY_LEN */,
1825 _("CONF"),
1826 SH_PROTO_MSG|SH_PROTO_END);
1827#endif
1828
1829 memset(buffer, 0, sl_strlen(buffer));
1830 SH_FREE(buffer);
1831
1832 /* sh_xfer_do_free (conn); */
1833 }
1834
1835 /* client does something unexpected
1836 */
1837 else /* ---- ??? ----- */
1838 {
1839 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
1840 2, conn->pass, conn->peer,
1841 '\\', conn->head[3], '\\',conn->head[4],
1842 '\\', conn->head[5], '\\',conn->head[6]);
1843 status_update (conn->client_entry, CLT_FAILED);
1844 conn->client_entry->session_key_timer =
1845 time(NULL) - (2*TIMEOUT_KEY);
1846 sh_xfer_do_free (conn);
1847 }
1848 }
1849
1850 else if (state == SH_DO_WRITE) /* finished writing */
1851 {
1852 if (0 != (conn->head[0] & SH_PROTO_END))
1853 {
1854 if (flag_err_debug == S_TRUE)
1855 {
1856 char * pstrip = sh_strip_domain (conn->peer);
1857 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_OKMSG,
1858 pstrip);
1859 SH_FREE(pstrip);
1860 }
1861 sh_xfer_do_free (conn);
1862 SL_RETURN(0, _("do_message_transfer"));
1863 }
1864
1865 TPT(( 0, FIL__, __LINE__, _("msg=<Msg transfer - (wait).>\n")));
1866
1867 /* challenge is sent, now wait for message from client
1868 */
1869 conn->headcount = 0;
1870 conn->bytecount = 0;
1871 conn->bytes_to_send = 0;
1872 conn->bytes_to_get = 0;
1873 if (conn->buf != NULL)
1874 {
1875 SH_FREE(conn->buf);
1876 conn->buf = NULL;
1877 }
1878 conn->state = CONN_READING;
1879 }
1880 TPT((0, FIL__, __LINE__, _("msg=<return>\n") ));
1881 SL_RETURN(0, _("do_message_transfer"));
1882}
1883
1884/* ------------------------------------------------------
1885 *
1886 * AUTHENTICATION
1887 *
1888 * ------------------------------------------------------ */
1889
1890static void check_probe(sh_conn_t * conn)
1891{
1892 if (conn && conn->client_entry)
1893 {
1894 /* If client has sent probe, change ivst_flag and clear probe in head[0].
1895 */
1896 conn->head[0] = sh_tools_probe_store(conn->head[0],
1897 &(conn->client_entry->ivst_flag));
1898 }
1899}
1900
1901client_t * do_auth_start(sh_conn_t * conn)
1902{
1903 client_t * this_client;
1904
1905 TPT((0, FIL__, __LINE__,
1906 _("msg=<Authentication - SALT (1).>\n")));
1907
1908 if (conn->buf == NULL || sl_strlen(conn->buf) == 0)
1909 {
1910 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOCLT);
1911 sh_xfer_do_free (conn);
1912 return NULL;
1913 }
1914
1915 /* search the register
1916 */
1917
1918 this_client = search_register (conn, 0);
1919 if (NULL == this_client)
1920 return NULL;
1921
1922 conn->client_entry = this_client;
1923 sl_strlcpy (conn->peer, conn->buf, SH_MINIBUF+1);
1924
1925 if (0 != check_request_s((char *)&(conn->head[3]),
1926 _("SALT"),conn->peer))
1927 {
1928 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
1929 _("No salt requested"), conn->peer);
1930 status_update (conn->client_entry, CLT_FAILED);
1931 conn->client_entry->session_key_timer =
1932 time(NULL) - (2*TIMEOUT_KEY);
1933 sh_xfer_do_free (conn);
1934 return NULL;
1935 }
1936
1937 check_probe(conn);
1938 return this_client;
1939}
1940
1941#if !defined(USE_SRP_PROTOCOL)
1942
1943int do_auth(sh_conn_t * conn)
1944{
1945 client_t * this_client;
1946 UINT32 ticks;
1947 char u[5] = "OOOO";
1948#ifdef SH_ENCRYPT
1949 int err_num;
1950 char expbuf[SH_ERRBUF_SIZE];
1951#endif
1952 char hash[SH_MAXMSGLEN + KEY_LEN + KEY_LEN + 1];
1953 char hashbuf[KEYBUF_SIZE];
1954
1955 /* first pass -- client request salt
1956 */
1957 if (conn->pass == 1)
1958 {
1959 this_client = do_auth_start(conn);
1960
1961 if (!this_client)
1962 return -1;
1963
1964 /* -- create server nounce v --
1965 */
1966 ticks = (UINT32) taus_get ();
1967
1968 if (conn->A != NULL)
1969 {
1970 SH_FREE(conn->A);
1971 conn->A = NULL;
1972 }
1973 conn->A = SH_ALLOC(KEY_LEN+1);
1974
1975 sl_strlcpy(conn->A,
1976 sh_tiger_hash((char *) &ticks,
1977 TIGER_DATA, sizeof(UINT32),
1978 hashbuf, sizeof(hashbuf)),
1979 KEY_LEN+1);
1980 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
1981
1982 if (conn->M1 != NULL)
1983 {
1984 SH_FREE(conn->M1);
1985 conn->M1 = NULL;
1986 }
1987 conn->M1 = SH_ALLOC(2*KEY_LEN+1);
1988
1989 /* compute hash key H(v(server), P)v(server)
1990 */
1991 sh_passwd (conn->A, conn->client_entry->verifier,
1992 NULL, conn->M1);
1993
1994 sl_strlcat(conn->M1, conn->A, 2*KEY_LEN+1);
1995
1996
1997 /* --- send H(v(server), P)v(server) ----
1998 */
1999 sh_xfer_prep_send (conn,
2000 conn->M1,
2001 sl_strlen(conn->M1),
2002 u,
2003 (conn->head[0]|SH_PROTO_SRP));
2004
2005 SH_FREE(conn->M1);
2006 conn->M1 = NULL;
2007 }
2008
2009 /* client -- third pass
2010 * Message is H(H(u,v),P)u
2011 *
2012 * A := v, verifier := H(password),
2013 */
2014 else if (conn->pass == 3 &&
2015 conn->client_entry != NULL)
2016 {
2017
2018 TPT((0, FIL__, __LINE__,
2019 _("msg=<Authentication - PASS (3).>\n")));
2020
2021 if (0 != check_request_s((char *) &(conn->head[3]), _("PASS"),
2022 conn->peer) ||
2023 sl_strlen(conn->buf) <= KEY_LEN ||
2024 conn->A == NULL)
2025 {
2026 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2027 _("Invalid client request"), conn->peer);
2028 status_update (conn->client_entry, CLT_FAILED);
2029 conn->client_entry->session_key_timer =
2030 time(NULL) - (2*TIMEOUT_KEY);
2031 sh_xfer_do_free (conn);
2032 return -1;
2033 }
2034
2035 check_probe(conn);
2036
2037 /* store random nonce u from client
2038 */
2039 if (conn->K != NULL)
2040 {
2041 SH_FREE(conn->K);
2042 conn->K = NULL;
2043 }
2044 conn->K = SH_ALLOC(KEY_LEN+1);
2045 sl_strlcpy(conn->K, &(conn->buf[KEY_LEN]), KEY_LEN+1);
2046
2047 /* verify random nonce u from client
2048 */
2049 if (conn->M1 != NULL)
2050 {
2051 SH_FREE(conn->M1);
2052 conn->M1 = NULL;
2053 }
2054 conn->M1 = sh_util_strconcat(conn->K, conn->A, NULL);
2055
2056 TPT((0, FIL__, __LINE__, _("msg=<c/r: K = %s>\n"), conn->K));
2057 TPT((0, FIL__, __LINE__, _("msg=<c/r: A = %s>\n"), conn->A));
2058 TPT((0, FIL__, __LINE__, _("msg=<c/r: M = %s>\n"), conn->M1));
2059
2060 sl_strlcpy(hash, sh_tiger_hash (conn->M1,
2061 TIGER_DATA,
2062 sl_strlen(conn->M1),
2063 hashbuf, sizeof(hashbuf)),
2064 KEY_LEN+1);
2065 sh_passwd (hash, conn->client_entry->verifier, NULL, conn->M1);
2066
2067 TPT((0, FIL__, __LINE__, _("msg=<c/r: H = %s>\n"), hash));
2068 TPT((0, FIL__, __LINE__, _("msg=<c/r: P = %s>\n"), conn->M1));
2069
2070 if ( 0 != sl_ts_strncmp(conn->M1, conn->buf, KEY_LEN))
2071 {
2072 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2073 _("Session key mismatch"), conn->peer);
2074 status_update (conn->client_entry, CLT_FAILED);
2075 conn->client_entry->session_key_timer =
2076 time(NULL) - (2*TIMEOUT_KEY);
2077 sh_xfer_do_free (conn);
2078 return -1;
2079 }
2080
2081 /* ---- compute hash key H(v, P, u) ----
2082 */
2083 sh_passwd (conn->A, conn->client_entry->verifier, conn->K,
2084 conn->M1);
2085
2086 sl_strlcpy(conn->client_entry->session_key,
2087 conn->M1, KEY_LEN+1);
2088 TPT((0, FIL__, __LINE__, _("msg=<c/r: Key = %s>\n"),
2089 conn->client_entry->session_key));
2090
2091#ifdef SH_ENCRYPT
2092 err_num = rijndael_makeKey(&(conn->client_entry->keyInstE),
2093 DIR_ENCRYPT, 192,
2094 conn->client_entry->session_key);
2095 if (err_num < 0)
2096 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2097 errorExplain(err_num, expbuf, sizeof(expbuf)),
2098 _("check_protocol: makeKey"));
2099 err_num = rijndael_makeKey(&(conn->client_entry->keyInstD),
2100 DIR_DECRYPT, 192,
2101 conn->client_entry->session_key);
2102 if (err_num < 0)
2103 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2104 errorExplain(err_num, expbuf, sizeof(expbuf)),
2105 _("check_protocol: makeKey"));
2106#endif
2107
2108 if (conn->K != NULL) SH_FREE (conn->K);
2109 conn->K = NULL;
2110 if (conn->A != NULL) SH_FREE (conn->A);
2111 conn->A = NULL;
2112 if (conn->M1 != NULL) SH_FREE (conn->M1);
2113 conn->M1 = NULL;
2114
2115 /* if (conn->client_entry->status_now == CLT_STARTED */
2116 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
2117 (conn->client_entry->status_now != CLT_EXITED) &&
2118 (conn->client_entry->status_now != CLT_SUSPEND))
2119 && conn->client_entry->session_key_timer > (time_t) 1)
2120 {
2121 status_update (conn->client_entry, CLT_ILLEGAL);
2122 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_ILL,
2123 conn->peer);
2124 }
2125 else if (conn->client_entry->session_key_timer == (time_t) 0)
2126 {
2127 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NEW,
2128 conn->peer);
2129 if (conn->client_entry->status_now != CLT_SUSPEND)
2130 status_update (conn->client_entry, CLT_STARTED);
2131 }
2132
2133 conn->client_entry->session_key_timer = time (NULL);
2134 conn->client_entry->last_connect = time (NULL);
2135
2136 /* put in read state
2137 */
2138 sh_xfer_prep_send (conn,
2139 _("AUTH"),
2140 5,
2141 _("AUTH"),
2142 (conn->head[0]|SH_PROTO_SRP));
2143
2144 }
2145 else
2146 {
2147 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
2148 3, conn->pass, conn->peer,
2149 '\\', conn->head[3], '\\', conn->head[4],
2150 '\\', conn->head[5], '\\', conn->head[6]);
2151 sh_xfer_do_free (conn);
2152 }
2153 return 0;
2154}
2155
2156#else
2157
2158static void noise()
2159{
2160 UINT32 n = taus_get();
2161 retry_msleep(0, (n & 0x0000007F));
2162 return;
2163}
2164
2165/* use SRP */
2166
2167int do_auth(sh_conn_t * conn)
2168{
2169 client_t * this_client;
2170 UINT32 ticks;
2171 char u[5] = "OOOO";
2172#ifdef SH_ENCRYPT
2173 int err_num;
2174 char expbuf[SH_ERRBUF_SIZE];
2175#endif
2176 size_t len;
2177 char * test;
2178 char * foo_B;
2179 char * foo_Ss;
2180 char hashbuf[KEYBUF_SIZE];
2181
2182 /* use SRP
2183 */
2184 if (conn->pass == 1)
2185 {
2186 this_client = do_auth_start(conn);
2187 if (!this_client)
2188 return -1;
2189
2190 u[0] = 'I'; u[1] = 'N'; u[2] = 'I'; u[3] = 'T'; u[4] = '\0';
2191 sh_xfer_prep_send (conn,
2192 conn->client_entry->salt,
2193 sl_strlen(conn->client_entry->salt),
2194 u,
2195 (conn->head[0]|SH_PROTO_SRP));
2196 }
2197
2198 /* client has sent A -- third pass
2199 */
2200 else if (conn->pass == 3 &&
2201 conn->client_entry != NULL)
2202 {
2203
2204 TPT((0, FIL__, __LINE__,
2205 _("msg=<Authentication - PC01 (3).>\n")));
2206
2207 if (0 != check_request_s((char *)&(conn->head[3]),_("PC01"),conn->peer)||
2208 conn->buf == NULL
2209 )
2210 {
2211 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2212 _("Invalid client request"), conn->peer);
2213 status_update (conn->client_entry, CLT_FAILED);
2214 conn->client_entry->session_key_timer =
2215 time(NULL) - (2*TIMEOUT_KEY);
2216 sh_xfer_do_free (conn);
2217 return -1;
2218 }
2219
2220 check_probe(conn); noise();
2221
2222 if (0 != sh_srp_init())
2223 {
2224 status_update (conn->client_entry, CLT_FAILED);
2225 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
2226 MSG_TCP_EBGN);
2227 sh_xfer_do_free (conn);
2228 return -1;
2229 }
2230
2231
2232 /* check A, only send B if correct
2233 */
2234 if ( sl_strlen(conn->buf) < SH_BUFSIZE &&
2235 0 == sh_srp_check_zero (conn->buf) )
2236 {
2237 len = sl_strlen(conn->buf)+1;
2238
2239 if (conn->A != NULL)
2240 {
2241 SH_FREE(conn->A);
2242 conn->A = NULL;
2243 }
2244 conn->A = SH_ALLOC(len);
2245 sl_strlcpy (conn->A, conn->buf, len);
2246
2247 /*
2248 * compute B
2249 */
2250 if (0 != sh_srp_make_a ()) /* b random number */
2251 {
2252 status_update (conn->client_entry, CLT_FAILED);
2253
2254 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
2255 MSG_TCP_EBGN);
2256 sh_srp_exit();
2257 sh_xfer_do_free (conn);
2258 return -1;
2259 }
2260
2261 foo_B = sh_srp_B /* B = v + g^b */
2262 (conn->client_entry->verifier);
2263
2264 if (foo_B == NULL)
2265 {
2266 status_update (conn->client_entry, CLT_FAILED);
2267
2268 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
2269 MSG_TCP_EBGN);
2270 sh_srp_exit();
2271 sh_xfer_do_free (conn);
2272 return -1;
2273 }
2274
2275 TPT((0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), conn->A));
2276 TPT((0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), foo_B));
2277
2278 /*
2279 * create nonce u
2280 */
2281 ticks = (UINT32) taus_get ();
2282
2283 test = (char *) &ticks;
2284 sh_util_cpylong (u, test, 4); /* u nounce */
2285 u[4] = '\0';
2286 sl_strlcpy(conn->challenge,
2287 sh_tiger_hash(u, TIGER_DATA, 4, hashbuf, sizeof(hashbuf)),
2288 SH_CHALLENGE_SIZE);
2289
2290 TPT((0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), u[0], u[1], u[2], u[3]));
2291 TPT((0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"),
2292 conn->challenge));
2293
2294 /*
2295 * compute the session key K and M1 = Hash(A,B,K)
2296 */
2297 foo_Ss = sh_srp_S_s (conn->challenge,
2298 conn->A,
2299 conn->client_entry->verifier);
2300
2301 if (foo_Ss == NULL || 0 != sh_srp_check_zero (foo_Ss))
2302 {
2303 status_update (conn->client_entry, CLT_FAILED);
2304
2305 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
2306 MSG_TCP_EBGN);
2307 sh_srp_exit();
2308 sh_xfer_do_free (conn);
2309 return -1;
2310 }
2311
2312 if (conn->K != NULL)
2313 {
2314 SH_FREE(conn->K);
2315 conn->K = NULL;
2316 }
2317 conn->K = SH_ALLOC(KEY_LEN+1);
2318 sl_strlcpy(conn->K,
2319 sh_tiger_hash(foo_Ss, TIGER_DATA,
2320 sl_strlen(foo_Ss),
2321 hashbuf, sizeof(hashbuf)),
2322 KEY_LEN+1);
2323
2324 if (conn->M1 != NULL)
2325 {
2326 SH_FREE(conn->M1);
2327 conn->M1 = NULL;
2328 }
2329 conn->M1 = SH_ALLOC(KEY_LEN+1);
2330 sh_srp_M (conn->A, foo_B, conn->K, conn->M1, KEY_LEN+1);
2331
2332 TPT((0, FIL__, __LINE__, _("msg=<srp:Ss = %s>\n"), foo_Ss));
2333 TPT((0, FIL__, __LINE__, _("msg=<srp: K = %s>\n"), conn->K));
2334 TPT((0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"),conn->M1));
2335
2336 /*
2337 * send B
2338 */
2339 sh_xfer_prep_send (conn,
2340 foo_B,
2341 sl_strlen(foo_B)+1,
2342 u,
2343 (conn->head[0]|SH_PROTO_SRP));
2344 if (foo_Ss != NULL)
2345 {
2346 SH_FREE(foo_Ss);
2347 foo_Ss = NULL;
2348 }
2349 if (foo_B != NULL)
2350 {
2351 SH_FREE(foo_B);
2352 foo_B = NULL;
2353 }
2354 }
2355 else
2356 {
2357 status_update (conn->client_entry, CLT_FAILED);
2358
2359 sh_error_handle(SH_ERR_SEVERE, FIL__, __LINE__, 0,
2360 MSG_TCP_EZERO);
2361 sh_xfer_do_free (conn);
2362 }
2363
2364 sh_srp_exit();
2365 }
2366
2367 /* client has sent M1 -- fifth pass
2368 */
2369 else if (conn->pass == 5 &&
2370 conn->client_entry != NULL)
2371 {
2372 TPT((0, FIL__, __LINE__,
2373 _("msg=<Authentication - PC02 (5).>\n")));
2374
2375 /* check that the state is valid
2376 */
2377 if (0 != check_request_s((char *)&(conn->head[3]), _("PC02"),
2378 conn->peer) ||
2379 conn->A == NULL || conn->K == NULL || conn->M1 == NULL)
2380 {
2381 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2382 _("Invalid client request"), conn->peer);
2383 status_update (conn->client_entry, CLT_FAILED);
2384 conn->client_entry->session_key_timer =
2385 time(NULL) - (2*TIMEOUT_KEY);
2386 sh_xfer_do_free (conn);
2387 return -1;
2388 }
2389
2390 check_probe(conn); noise();
2391
2392 /* ------ verify M1 = H(A, B, K) -------
2393 * ----- send M2 = H(A, M1, K) -------
2394 */
2395 if (conn->buf != NULL &&
2396 sl_ts_strncmp(conn->buf, conn->M1, KEY_LEN) == 0)
2397 {
2398 /*
2399 * send M2
2400 */
2401 char M_buf[KEY_LEN+1];
2402 sh_xfer_prep_send (conn,
2403 sh_srp_M (conn->A, conn->M1, conn->K,
2404 M_buf, sizeof(M_buf)),
2405 KEY_LEN+1,
2406 _("PARP"),
2407 (conn->head[0]|SH_PROTO_SRP));
2408
2409 if (conn->A != NULL)
2410 SH_FREE(conn->A);
2411 conn->A = NULL;
2412 if (conn->M1 != NULL)
2413 SH_FREE(conn->M1);
2414 conn->M1 = NULL;
2415 sl_strlcpy(conn->client_entry->session_key,
2416 conn->K, KEY_LEN+1);
2417 TPT((0, FIL__, __LINE__, _("msg=<key %s>\n"),
2418 conn->client_entry->session_key));
2419
2420#ifdef SH_ENCRYPT
2421 err_num = rijndael_makeKey(&(conn->client_entry->keyInstE),
2422 DIR_ENCRYPT, 192,
2423 conn->client_entry->session_key);
2424 if (err_num < 0)
2425 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2426 errorExplain(err_num, expbuf, sizeof(expbuf)),
2427 _("sh_xfer_prep_send_int: makeKey"));
2428 err_num = rijndael_makeKey(&(conn->client_entry->keyInstD),
2429 DIR_DECRYPT, 192,
2430 conn->client_entry->session_key);
2431 if (err_num < 0)
2432 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
2433 errorExplain(err_num, expbuf, sizeof(expbuf)),
2434 _("sh_xfer_prep_send_int: makeKey"));
2435#endif
2436
2437 if (conn->K != NULL)
2438 SH_FREE(conn->K);
2439 conn->K = NULL;
2440
2441 conn->client_entry->last_connect = time (NULL);
2442
2443 if (((conn->client_entry->status_now != CLT_INACTIVE) &&
2444 (conn->client_entry->status_now != CLT_EXITED) &&
2445 (conn->client_entry->status_now != CLT_SUSPEND))
2446 && conn->client_entry->session_key_timer > (time_t) 1)
2447 {
2448 status_update (conn->client_entry, CLT_ILLEGAL);
2449
2450 sh_error_handle((-1), FIL__, __LINE__, 0,
2451 MSG_TCP_ILL,
2452 conn->peer);
2453 }
2454 else if (conn->client_entry->session_key_timer == (time_t) 0)
2455 {
2456 sh_error_handle((-1), FIL__, __LINE__, 0,
2457 MSG_TCP_NEW,
2458 conn->peer);
2459 if (conn->client_entry->status_now != CLT_SUSPEND)
2460 status_update (conn->client_entry, CLT_STARTED);
2461 }
2462 conn->client_entry->session_key_timer = time (NULL);
2463
2464 }
2465 else
2466 {
2467 status_update (conn->client_entry, CLT_FAILED);
2468 conn->client_entry->session_key_timer =
2469 time(NULL) - (2*TIMEOUT_KEY);
2470
2471 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_BADCONN,
2472 _("Session key mismatch"), conn->peer);
2473 sh_xfer_do_free (conn);
2474 }
2475 }
2476
2477 else
2478 {
2479 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_FINV,
2480 4, conn->pass, conn->peer,
2481 '\\', conn->head[3], '\\', conn->head[4],
2482 '\\', conn->head[5], '\\', conn->head[6]);
2483 sh_xfer_do_free (conn);
2484 }
2485 return 0;
2486}
2487#endif
2488
2489/************************************************************************
2490 *
2491 * Here we check the message received, and decide on the answer to send
2492 * (if any). The connection is in CONN_PAUSED state, thus we must:
2493 * (i) define the proper reaction
2494 * (ii) reset to CONN_READING or CONN_WRITING or CONN_FREE
2495 * (iii) eventually reset the connection entry
2496 *
2497 *************************************************************************/
2498static
2499void check_protocol(sh_conn_t * conn, int state)
2500{
2501 SL_ENTER(_("check_protocol"));
2502
2503 /* seed / re-seed the PRNG if required
2504 */
2505 (void) taus_seed();
2506
2507 /* protocols:
2508 * -- (iii) file transfer
2509 * -- (ii) authenticated message transfer
2510 * -- (i) SRP key exchange
2511 */
2512
2513 /* --------- FILE TRANSFER -----------
2514 */
2515 if ( (conn->head[0] & SH_PROTO_SRP) == 0 &&
2516 (conn->head[0] & SH_PROTO_BIG) != 0 /* is set */ )
2517 {
2518 /* nonzero means re-authentication is required
2519 */
2520 if (0 == do_file_transfer(conn, state))
2521 SL_RET0(_("check_protocol"));
2522 }
2523 /* --------- END FILE TRANSFER ----------- */
2524
2525
2526 /* --------- message exchange -----------
2527 */
2528 else if ((conn->head[0] & SH_PROTO_SRP) == 0 &&
2529 (conn->head[0] & SH_PROTO_MSG) != 0 /* is set */ )
2530 {
2531 /* nonzero means re-authentication is required
2532 */
2533 if (0 == do_message_transfer(conn, state))
2534 SL_RET0(_("check_protocol"));
2535 }
2536 /* --------- END MESSAGE TRANSFER ------ */
2537
2538 /* --------- authentication -----------
2539 */
2540 if ( (conn->head[0] & SH_PROTO_SRP) != 0 /* is set */ )
2541 {
2542 if (state == SH_DO_READ) /* finished reading */
2543 {
2544 do_auth(conn);
2545 }
2546
2547 else if (state == SH_DO_WRITE) /* finished writing */
2548 {
2549 TPT((0, FIL__, __LINE__, _("msg=<Authentication -- (wait).>\n")));
2550
2551 conn->headcount = 0;
2552 conn->bytecount = 0;
2553 conn->bytes_to_send = 0;
2554 conn->bytes_to_get = 0;
2555 if (conn->buf != NULL)
2556 {
2557 SH_FREE(conn->buf);
2558 conn->buf = NULL;
2559 }
2560 conn->state = CONN_READING;
2561 }
2562 }
2563 SL_RET0(_("check_protocol"));
2564}
2565
2566
2567/***********************************************************
2568 *
2569 * SERVER RECEIVE FUNCTION
2570 *
2571 ***********************************************************
2572 */
2573int sh_xfer_do_read (sh_conn_t * conn)
2574{
2575 unsigned long byteread; /* bytes read */
2576
2577 SL_ENTER(_("sh_xfer_do_read"));
2578
2579 if (conn->state == CONN_SENDING)
2580 {
2581 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
2582 conn->peer);
2583 SL_RETURN( (-1), _("sh_xfer_do_read"));
2584 }
2585
2586 if (conn->headcount < SH_HEADER_SIZE)
2587 {
2588 conn->bytes_to_get = SH_HEADER_SIZE - conn->headcount;
2589 byteread = read (conn->fd, &(conn->head[conn->headcount]),
2590 conn->bytes_to_get);
2591 if (byteread > 0 || errno == EINTR)
2592 {
2593 if (byteread > 0)
2594 conn->headcount += byteread;
2595 if (conn->headcount == SH_HEADER_SIZE)
2596 {
2597 conn->bytes_to_get = (256 * (unsigned int)conn->head[1] +
2598 (unsigned int)conn->head[2]);
2599 SH_SHOWPROT(conn->head, '<');
2600 conn->bytecount = 0;
2601 }
2602 }
2603 else
2604 goto conn_reset;
2605 SL_RETURN( (0), _("sh_xfer_do_read"));
2606 }
2607
2608 /* limit message size
2609 */
2610 conn->bytes_to_get = (conn->bytes_to_get > TRANS_BYTES) ?
2611 TRANS_BYTES : conn->bytes_to_get;
2612
2613 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get > 0)
2614 {
2615 if ( conn->bytecount == 0)
2616 {
2617 if (conn->buf != NULL)
2618 SH_FREE (conn->buf);
2619 conn->buf = SH_ALLOC(conn->bytes_to_get + 1); /* <= TRANS_BYTES+1 */
2620 }
2621
2622 byteread = read (conn->fd, &(conn->buf[conn->bytecount]),
2623 conn->bytes_to_get - conn->bytecount);
2624 if (byteread > 0 || errno == EINTR)
2625 {
2626 if (byteread > 0)
2627 conn->bytecount += byteread;
2628 if (conn->bytecount == conn->bytes_to_get)
2629 {
2630 ++conn->pass;
2631 /* always terminate with NULL - we might use sl_strcmp() */
2632 conn->buf[conn->bytecount] = '\0';
2633 conn->state = CONN_PAUSE;
2634
2635#ifdef SH_ENCRYPT
2636 if ((conn->head[0] & SH_PROTO_ENC) != 0)
2637 {
2638 conn->buf = sh_tools_revertPack (conn->head,
2639 conn->client_entry->ivst_flag,
2640 conn->buf,
2641 &(conn->client_entry->keyInstD),
2642 conn->bytecount);
2643 }
2644#endif
2645 /* ------ HERE CALL check_protocol(conn) ------- */
2646 check_protocol(conn, SH_DO_READ);
2647 }
2648 }
2649 else
2650 goto conn_reset;
2651 }
2652
2653 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_get == 0)
2654 {
2655 if (conn->buf != NULL)
2656 SH_FREE (conn->buf);
2657 conn->buf = NULL;
2658 conn->bytecount = 0;
2659 ++conn->pass;
2660 conn->state = CONN_PAUSE;
2661 /* ------ HERE CALL check_protocol(conn) ------- */
2662 check_protocol(conn, SH_DO_READ);
2663 }
2664
2665 SL_RETURN( (0), _("sh_xfer_do_read"));
2666
2667 conn_reset:
2668 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
2669 conn->peer);
2670 sh_xfer_do_free ( conn );
2671 SL_RETURN( (-1), _("sh_xfer_do_read"));
2672}
2673
2674#if !defined(O_NONBLOCK)
2675#if defined(O_NDELAY)
2676#define O_NONBLOCK O_NDELAY
2677#else
2678#define O_NONBLOCK 0
2679#endif
2680#endif
2681
2682/* send to the client
2683 */
2684int sh_xfer_do_write (sh_conn_t * conn)
2685{
2686 int flags;
2687 long arg = 0;
2688 long bytesent; /* bytes read */
2689
2690 SL_ENTER(_("sh_xfer_do_write"));
2691
2692 /* ---- consistency check ------
2693 */
2694 if (conn->state == CONN_READING)
2695 {
2696 sh_error_handle( (-1), FIL__, __LINE__, 0, MSG_TCP_SYNC,
2697 conn->peer);
2698 SL_RETURN( (-1), _("sh_xfer_do_write"));
2699 }
2700
2701 flags = retry_fcntl (FIL__, __LINE__, conn->fd, F_GETFL, arg);
2702 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags|O_NONBLOCK);
2703
2704 /* ---- send the header ------
2705 */
2706 if (conn->headcount < SH_HEADER_SIZE)
2707 {
2708 conn->bytes_to_send = SH_HEADER_SIZE - conn->headcount;
2709 bytesent = write (conn->fd, &(conn->head[conn->headcount]),
2710 conn->bytes_to_send);
2711 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
2712 {
2713 if (bytesent > 0)
2714 conn->headcount += bytesent;
2715 if (conn->headcount == SH_HEADER_SIZE)
2716 conn->bytes_to_send =
2717 (256 * (int)conn->head[1] + (int)conn->head[2]);
2718 }
2719 else
2720 goto conn_reset_w;
2721
2722 if (conn->fd >= 0)
2723 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
2724 SL_RETURN( (0), _("sh_xfer_do_write"));
2725 }
2726
2727 /* ---- send the body ------
2728 */
2729
2730 if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send > 0 &&
2731 conn->buf != NULL)
2732 {
2733 bytesent = write (conn->fd, &(conn->buf[conn->bytecount]),
2734 conn->bytes_to_send - conn->bytecount);
2735 if (bytesent >= 0 || errno == EINTR || errno == EAGAIN)
2736 {
2737 if (bytesent > 0)
2738 conn->bytecount += bytesent;
2739 if (conn->bytecount == conn->bytes_to_send)
2740 {
2741 ++conn->pass;
2742 conn->state = CONN_PAUSE;
2743 /* ------ HERE CALL check_protocol(conn) ------- */
2744 check_protocol(conn, SH_DO_WRITE);
2745 }
2746 }
2747 else
2748 goto conn_reset_w;
2749 }
2750
2751 else if (conn->headcount == SH_HEADER_SIZE && conn->bytes_to_send == 0)
2752 {
2753 ++conn->pass;
2754 conn->state = CONN_PAUSE;
2755 /* ------ HERE CALL check_protocol(conn) ------- */
2756 check_protocol(conn, SH_DO_WRITE);
2757 }
2758
2759 if (conn->fd >= 0)
2760 retry_fcntl (FIL__, __LINE__, conn->fd, F_SETFL, flags);
2761 SL_RETURN( (0), _("sh_xfer_do_write"));
2762
2763 conn_reset_w:
2764 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_RESET,
2765 conn->peer);
2766 sh_xfer_do_free ( conn );
2767 SL_RETURN( (-1), _("sh_xfer_do_write"));
2768}
2769
2770/* accept a connection from a client
2771 */
2772#include <syslog.h>
2773#ifdef SH_USE_LIBWRAP
2774#include <tcpd.h>
2775
2776#ifndef ALLOW_SEVERITY
2777#define ALLOW_SEVERITY LOG_INFO
2778#define DENY_SEVERITY LOG_WARNING
2779#endif
2780
2781int allow_severity;
2782int deny_severity;
2783#endif
2784
2785#ifdef SH_USE_LIBWRAP
2786static int check_libwrap(int rc, sh_conn_t * newconn)
2787{
2788 struct request_info request;
2789 char errbuf[128];
2790 char daemon[128];
2791
2792 sl_strlcpy(daemon, SH_INSTALL_NAME, sizeof(daemon));
2793 request_init(&request, RQ_DAEMON, daemon, RQ_FILE, rc, 0);
2794 fromhost(&request);
2795 if (!hosts_access(&request))
2796 {
2797 sl_strlcpy(errbuf, _("Refused connection from "), sizeof(errbuf));
2798 sl_strlcat(errbuf, eval_client(&request), sizeof(errbuf));
2799
2800 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2801 errbuf, _("libwrap"));
2802 newconn->fd = -1;
2803 newconn->state = CONN_FREE;
2804 sl_close_fd(FIL__, __LINE__, rc);
2805 return -1;
2806 }
2807 return 0;
2808}
2809#endif
2810
2811int sh_xfer_accept (int sock, sh_conn_t * newconn)
2812{
2813 int errflag;
2814 int rc;
2815 struct sh_sockaddr addr;
2816
2817 /* handle AIX (size_t addrlen) in wrapper
2818 */
2819 int addrlen = sizeof(addr);
2820
2821 SL_ENTER(_("sh_xfer_accept"));
2822
2823 rc = retry_accept(FIL__, __LINE__, sock, &addr, &addrlen);
2824
2825 if (rc < 0)
2826 {
2827 char err_buf[SH_ERRBUF_SIZE];
2828 errflag = errno;
2829 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2830 sh_error_message(errflag,err_buf, sizeof(err_buf)), _("accept"));
2831 newconn->fd = -1;
2832 newconn->state = CONN_FREE;
2833 SL_RETURN( (-1), _("sh_xfer_accept"));
2834 }
2835
2836 if (addrlen == 0)
2837 {
2838 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
2839 _("Connecting entity unknown"), _("accept"));
2840 newconn->fd = -1;
2841 newconn->state = CONN_FREE;
2842 sl_close_fd(FIL__, __LINE__, rc);
2843 SL_RETURN( (-1), _("sh_xfer_accept"));
2844 }
2845
2846#ifdef SH_USE_LIBWRAP
2847 if (check_libwrap(rc, newconn) < 0)
2848 SL_RETURN( (-1), _("sh_xfer_accept"));
2849#endif
2850
2851 memcpy (&(newconn->addr_peer), &addr, sizeof(struct sh_sockaddr));
2852
2853 /* prepare for usage of connection
2854 */
2855 (void) retry_fcntl( FIL__, __LINE__, rc, F_SETFD, 1 );
2856 newconn->fd = rc;
2857 newconn->state = CONN_READING;
2858 newconn->timer = (unsigned long) time (NULL);
2859
2860 if (flag_err_info == S_TRUE)
2861 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_CNEW, newconn->fd);
2862
2863 SL_RETURN( (0), _("sh_xfer_accept"));
2864}
2865
2866extern char sh_sig_msg[64]; /* defined in sh_unix.c */
2867
2868/* ------------ port and interface -------
2869 */
2870static unsigned int server_port = SH_DEFAULT_PORT;
2871
2872int sh_xfer_set_port (const char * str)
2873{
2874 int retval = 0;
2875 unsigned long i;
2876 char * endptr;
2877
2878 SL_ENTER(_("sh_xfer_set_port"));
2879 i = strtoul (str, &endptr, 0);
2880 if (endptr == str) {
2881 retval = -1;
2882 } else if (i > 65535) {
2883 retval = -1;
2884 } else {
2885 server_port = i;
2886 }
2887 SL_RETURN( (retval), _("sh_xfer_set_port"));
2888}
2889
2890static struct sh_sockaddr server_interface;
2891static int use_server_interface = 0;
2892
2893int sh_xfer_set_interface (const char * str)
2894{
2895 if (0 == strcmp(str, _("INADDR_ANY")))
2896 {
2897 use_server_interface = 0;
2898 return 0;
2899 }
2900
2901 if (0 == sh_ipvx_aton(str, &server_interface))
2902 {
2903 use_server_interface = 0;
2904 return -1;
2905 }
2906
2907 use_server_interface = 1;
2908 return 0;
2909}
2910
2911/* ------------ print error --------------
2912 */
2913struct sock_err_st {
2914 char msg[128];
2915 int errnum;
2916 int port;
2917 int line;
2918 int euid;
2919};
2920
2921static struct sock_err_st sock_err[2];
2922
2923void sh_xfer_printerr(char * str, int errnum, unsigned int port, int line)
2924{
2925 int slot = 0;
2926
2927 if (port != server_port)
2928 slot = 1;
2929 if (str == NULL)
2930 sock_err[slot].msg[0] = '\0';
2931 else
2932 sl_strlcpy(sock_err[slot].msg, str, 128);
2933 sock_err[slot].errnum = errnum;
2934 sock_err[slot].port = port;
2935 sock_err[slot].line = line;
2936 sock_err[slot].euid = (int) geteuid();
2937}
2938
2939int sh_xfer_printerr_final(int slot)
2940{
2941 char errbuf[SH_ERRBUF_SIZE];
2942
2943 SL_ENTER(_("sh_xfer_printerr_final"));
2944 if (sock_err[slot].msg[0] != '\0')
2945 {
2946 dlog(1, FIL__, __LINE__,
2947 _("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"),
2948 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
2949 sock_err[slot].euid,
2950 sock_err[slot].port);
2951 sh_error_handle((-1), FIL__, sock_err[slot].line,
2952 sock_err[slot].errnum, MSG_EXIT_ABORTS,
2953 sh_error_message(sock_err[slot].errnum, errbuf, sizeof(errbuf)),
2954 sh.prg_name,
2955 sock_err[slot].msg);
2956 SL_RETURN((-1), _("sh_xfer_printerr_final"));
2957 }
2958 SL_RETURN(0, _("sh_xfer_printerr_final"));
2959}
2960
2961#define TIME_OUT_DEF 900
2962static unsigned long time_out_val = TIME_OUT_DEF;
2963
2964int sh_xfer_set_timeout (const char * c)
2965{
2966 long val;
2967
2968 SL_ENTER(_("sh_xfer_set_time_out"));
2969
2970 val = strtol (c, (char **)NULL, 10);
2971
2972 if (val == 0)
2973 {
2974 val = TIME_OUT_DEF;
2975 }
2976 else if (val < 0)
2977 {
2978 time_out_val = TIME_OUT_DEF;
2979 SL_RETURN( (-1), _("sh_xfer_set_time_out"));
2980 }
2981
2982 time_out_val = (unsigned long) val;
2983 SL_RETURN( (0), _("sh_xfer_set_time_out"));
2984}
2985
2986
2987static sh_conn_t * conns = NULL;
2988static int maxconn = 0; /* maximum number of simultaneous connections */
2989
2990
2991#ifdef INET_SYSLOG
2992#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
2993#define SH_MINSOCK_DEFAULT 3
2994int sh_xfer_syslog_sock[SH_SOCKMAX] = { -1 };
2995extern int sh_xfer_recv_syslog_socket (int fd);
2996int sh_xfer_syslog_sock_n = 0;
2997#else
2998#define SH_MINSOCK_DEFAULT 2
2999#endif
3000
3001int SH_MINSOCK = SH_MINSOCK_DEFAULT;
3002
3003extern int pf_unix_fd;
3004
3005/* the tcp socket, and the function to establish it
3006 */
3007static int sh_tcp_sock[SH_SOCKMAX] = { -1 };
3008static int sh_tcp_sock_n = 0;
3009
3010static int do_socket(int domain, int type, int protocol,
3011 struct sockaddr * sa, int salen)
3012{
3013 int sock = -1;
3014 int errnum = 0;
3015 int flag = 1; /* non-zero to enable an option */
3016
3017 /* create the socket, bind() it and listen()
3018 */
3019 if ((sock = socket(domain, type, protocol)) < 0 )
3020 {
3021 errnum = errno;
3022 sh_xfer_printerr (_("socket"), errnum, server_port, __LINE__);
3023 return -1;
3024 }
3025 (void) retry_fcntl( FIL__, __LINE__, sock, F_SETFD, 1 );
3026
3027 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
3028 (void *) &flag, sizeof(flag)) < 0 )
3029 {
3030 errnum = errno;
3031 sh_xfer_printerr (_("setsockopt"), errnum, server_port, __LINE__);
3032 sl_close_fd (FIL__, __LINE__, sock);
3033 return -1;
3034 }
3035
3036 if ( bind(sock, (struct sockaddr *) sa, salen) < 0)
3037 {
3038 if (errno != EADDRINUSE)
3039 {
3040 errnum = errno;
3041 sh_xfer_printerr (_("bind"), errnum, server_port, __LINE__);
3042 sl_close_fd (FIL__, __LINE__, sock);
3043 return -1;
3044 }
3045 else
3046 {
3047 sl_close_fd (FIL__, __LINE__, sock);
3048 return -2;
3049 }
3050 }
3051
3052 if ( retry_fcntl( FIL__, __LINE__, sock, F_SETFL, O_NONBLOCK ) < 0 )
3053 {
3054 errnum = errno;
3055 sh_xfer_printerr (_("fcntl"), errnum, server_port, __LINE__);
3056 sl_close_fd (FIL__, __LINE__, sock);
3057 return -1;
3058 }
3059
3060 if ( listen(sock, 64) < 0)
3061 {
3062 errnum = errno;
3063 sh_xfer_printerr (_("listen"), errnum, server_port, __LINE__);
3064 sl_close_fd (FIL__, __LINE__, sock);
3065 return -1;
3066 }
3067
3068 return sock;
3069}
3070
3071int sh_create_tcp_socket (void)
3072{
3073#if defined(USE_IPVX)
3074 struct addrinfo *ai;
3075 struct addrinfo *p;
3076 struct addrinfo hints;
3077 char port[32];
3078#else
3079 struct sockaddr_in addr;
3080 int addrlen = sizeof(addr);
3081#endif
3082
3083 int sock = -1;
3084
3085 SL_ENTER(_("sh_create_tcp_socket"));
3086
3087 sh_xfer_printerr (NULL, 0, server_port, __LINE__);
3088
3089#if defined(USE_IPVX)
3090 if (use_server_interface == 0) /* INADDR_ANY, listen on all interfaces */
3091 {
3092 memset (&hints, 0, sizeof (hints));
3093 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
3094 hints.ai_socktype = SOCK_STREAM;
3095 hints.ai_family = AF_UNSPEC;
3096 sl_snprintf(port, sizeof(port), "%d", server_port);
3097
3098 if (getaddrinfo (NULL, port, &hints, &ai) != 0)
3099 {
3100 int errnum = errno;
3101 sh_xfer_printerr (_("getaddrinfo"), errnum, server_port, __LINE__);
3102 sl_close_fd (FIL__, __LINE__, sock);
3103 SL_RETURN((-1), _("sl_create_tcp_socket"));
3104 }
3105
3106 p = ai;
3107
3108 while (p != NULL && sh_tcp_sock_n < SH_SOCKMAX)
3109 {
3110 sock = do_socket(p->ai_family, p->ai_socktype, p->ai_protocol,
3111 p->ai_addr, p->ai_addrlen);
3112
3113 if (sock >= 0) {
3114 if (sh_tcp_sock_n < SH_SOCKMAX) {
3115 sh_tcp_sock[sh_tcp_sock_n] = sock;
3116 ++sh_tcp_sock_n;
3117 }
3118 else {
3119 sl_close_fd (FIL__, __LINE__, sock);
3120 }
3121 } else if (sock == -1) {
3122 freeaddrinfo (ai);
3123 goto end;
3124 }
3125 p = p->ai_next;
3126 }
3127
3128 freeaddrinfo (ai);
3129 }
3130 else
3131 {
3132 sh_ipvx_set_port(&server_interface, server_port);
3133
3134 sock = do_socket(server_interface.ss_family, SOCK_STREAM, 0,
3135 sh_ipvx_sockaddr_cast(&server_interface),
3136 SH_SS_LEN(server_interface));
3137
3138 if (sock >= 0) {
3139 sh_tcp_sock[0] = sock;
3140 sh_tcp_sock_n = 1;
3141 }
3142 }
3143#else
3144 if (use_server_interface == 0)
3145 addr.sin_addr.s_addr = INADDR_ANY;
3146 else
3147 memcpy(&addr, sh_ipvx_sockaddr_cast(&server_interface), addrlen);
3148 addr.sin_family = AF_INET;
3149 addr.sin_port = htons(server_port);
3150
3151 sock = do_socket(AF_INET, SOCK_STREAM, 0, (struct sockaddr *) &addr, addrlen);
3152
3153 if (sock >= 0) {
3154 sh_tcp_sock[0] = sock;
3155 sh_tcp_sock_n = 1;
3156 }
3157
3158#endif
3159
3160#if defined(USE_IPVX)
3161 end:
3162#endif
3163 if (sh_tcp_sock_n > 1)
3164 SH_MINSOCK += (sh_tcp_sock_n - 1);
3165
3166 SL_RETURN((sh_tcp_sock_n), _("sl_create_tcp_socket"));
3167}
3168
3169/*****************************************
3170 *
3171 * This is the server main loop.
3172 *
3173 * The server is set up for listening, and
3174 * and starts a select() loop.
3175 *
3176 *****************************************/
3177
3178void sh_xfer_start_server()
3179{
3180#ifdef SH_USE_XML
3181 extern int sh_log_file (char * message, char * inet_peer);
3182#endif
3183
3184 /* Use volatile to circumvent a gcc4 problem on RH/CentOS 4.8 (?) */
3185 volatile int sock = -1;
3186 sh_conn_t * cx;
3187 fd_set readset;
3188 fd_set writeset;
3189 struct timeval tv;
3190 int num_sel;
3191 int errnum;
3192 int nowconn;
3193 int status;
3194 int high_fd = -1;
3195 register int i;
3196 long dummy = 0;
3197 unsigned long time_now;
3198 unsigned long time_last = 0;
3199 unsigned long time_out = time_out_val;
3200
3201 time_t told;
3202 time_t tcurrent;
3203
3204 unsigned long tchkold;
3205
3206 int setsize_fd;
3207
3208 int sock_tcp[2];
3209 int sock_unix;
3210#ifdef INET_SYSLOG
3211 int sock_log[2];
3212#endif
3213
3214 SL_ENTER(_("sh_xfer_start_server"));
3215
3216 if ( sh_xfer_printerr_final(0) < 0)
3217 {
3218 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
3219 }
3220
3221 sock = sh_tcp_sock[0];
3222
3223 /* ****************************************************************
3224 *
3225 * This is a non-forking server. We use select() on the listen()
3226 * socket to watch for new connections. For new connections, accept()
3227 * will return a new socket that is put in the read/write filesets.
3228 * Data about active connections are kept in the 'conns' table.
3229 *
3230 ******************************************************************/
3231
3232 /* The table to hold info on sockets.
3233 * We reserve 6 file descriptors for misc. use.
3234 * The POSIX lower limit on open files seems to be eight.
3235 */
3236 maxconn = get_open_max() - 6;
3237
3238 /* ugly fix for FreeBSD compiler warning; casting FD_SETSIZE in the
3239 * conditional expression does not suppress the warning... */
3240 setsize_fd = (int)FD_SETSIZE;
3241 maxconn = (setsize_fd < maxconn) ? setsize_fd : maxconn;
3242
3243 if (maxconn < 0 || !sl_ok_muls(maxconn, sizeof(sh_conn_t)))
3244 {
3245 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
3246 0, sock);
3247 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
3248 }
3249 conns = SH_ALLOC (sizeof(sh_conn_t) * maxconn);
3250
3251 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_START_SRV,
3252 (maxconn-1), sock);
3253
3254 /* timer
3255 */
3256 tcurrent = (unsigned long) time (NULL);
3257 told = tcurrent;
3258
3259 tchkold = tcurrent;
3260
3261 for (i = SH_MINSOCK; i < maxconn; ++i)
3262 {
3263 conns[i].buf = NULL;
3264 conns[i].K = NULL;
3265 conns[i].A = NULL;
3266 conns[i].M1 = NULL;
3267 conns[i].FileName = NULL;
3268 conns[i].fd = -1;
3269 sh_xfer_do_free ( &conns[i]);
3270 }
3271
3272 /* status init
3273 */
3274 server_status.conn_open = 0;
3275 server_status.conn_total = 0;
3276 server_status.conn_max = maxconn-1;
3277 server_status.start = time (NULL);
3278 server_status.last = (time_t) 0;
3279
3280 nowconn = 1;
3281 tv.tv_sec = 5;
3282 tv.tv_usec = 0;
3283
3284 /* conns[0] is the listen() socket. Always in read mode.
3285 */
3286 sock = 0;
3287
3288 sock_tcp[0] = 0;
3289 while (sock < sh_tcp_sock_n)
3290 {
3291 conns[sock].fd = sh_tcp_sock[sock];
3292 conns[sock].state = CONN_READING;
3293 /* high_fd = (sh_tcp_sock[sock] > high_fd) ? sh_tcp_sock[sock] : high_fd; */
3294 ++sock;
3295 }
3296 sock_tcp[1] = sock;
3297
3298 conns[sock].fd = pf_unix_fd;
3299 conns[sock].state = CONN_READING;
3300 /* high_fd = (pf_unix_fd > high_fd) ? pf_unix_fd : high_fd; */
3301
3302 sock_unix = sock;
3303
3304 ++sock;
3305
3306#ifdef INET_SYSLOG
3307 conns[sock].fd = -1;
3308
3309 if ( sh_xfer_printerr_final(1) < 0)
3310 {
3311 SH_FREE(conns);
3312 conns = NULL;
3313 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
3314 }
3315
3316 sock_log[0] = sock;
3317 sock_log[1] = sock;
3318
3319 if (sh_xfer_syslog_sock_n > 0)
3320 {
3321 int s2;
3322 for (s2 = 0; s2 < sh_xfer_syslog_sock_n; ++s2)
3323 {
3324 conns[sock].fd = sh_xfer_syslog_sock[s2];
3325 conns[sock].state = CONN_READING;
3326 /* high_fd = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd; */
3327 ++sock;
3328 }
3329 sock_log[1] = sock;
3330
3331 }
3332#endif
3333
3334 sh_html_write(all_clients);
3335
3336 /* This is the select() loop.
3337 */
3338 while (1 == 1)
3339 {
3340
3341 if (sig_raised > 0)
3342 {
3343 TPT((0, FIL__, __LINE__, _("msg=<Process a signal.>\n")))
3344
3345 if (sig_termfast == 1) /* SIGTERM */
3346 {
3347 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
3348 strncpy (sh_sig_msg, _("SIGTERM"), 20);
3349 --sig_raised; --sig_urgent;
3350 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
3351 }
3352
3353 if (sig_config_read_again == 1)
3354 {
3355 TPT((0, FIL__, __LINE__, _("msg=<Re-read configuration.>\n")));
3356 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_RECONF);
3357
3358
3359 /* -- Delete the name server cache. --
3360 */
3361
3362 delete_cache();
3363#if defined(WITH_EXTERNAL)
3364 /* -- Delete list of external tasks. --
3365 */
3366 (void) sh_ext_cleanup();
3367#endif
3368#if defined(SH_WITH_MAIL)
3369 sh_nmail_free();
3370#endif
3371 /* - mark all clients dead
3372 * - read configuration file
3373 * - remove clients still dead
3374 */
3375 sh_xfer_mark_dead ();
3376
3377 reset_count_dev_console();
3378 reset_count_dev_time();
3379 sl_trust_purge_user();
3380
3381 (void) sh_readconf_read ();
3382
3383 for (i = SH_MINSOCK; i < maxconn; ++i)
3384 if (conns[i].state != CONN_FREE &&
3385 conns[i].client_entry != NULL &&
3386 conns[i].client_entry->dead_flag == 1)
3387 sh_xfer_do_free ( &conns[i]);
3388 sh_xfer_clean_tree ();
3389
3390 sig_config_read_again = 0;
3391 --sig_raised;
3392 }
3393
3394 if (sig_fresh_trail == 1) /* SIGIOT */
3395 {
3396 /* Logfile access
3397 */
3398#ifdef SH_USE_XML
3399 sh_log_file (NULL, NULL);
3400#endif
3401 TPT((0, FIL__, __LINE__, _("msg=<Logfile stop/restart.>\n")));
3402 sh_error_only_stderr (S_TRUE);
3403 sh_unix_rm_lock_file(sh.srvlog.name);
3404 retry_msleep(3, 0);
3405 sh.flag.log_start = S_TRUE;
3406 sh_error_only_stderr (S_FALSE);
3407 sig_fresh_trail = 0;
3408 --sig_raised;
3409 }
3410
3411
3412 if (sig_terminate == 1 && nowconn < 2) /* SIGQUIT */
3413 {
3414 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
3415 strncpy (sh_sig_msg, _("SIGQUIT"), 20);
3416 --sig_raised; --sig_urgent;
3417 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
3418 }
3419
3420
3421 if (sig_debug_switch == 1) /* SIGUSR1 */
3422 {
3423 TPT((0, FIL__, __LINE__, _("msg=<Debug switch.>\n")));
3424 sh_error_dbg_switch();
3425 sig_debug_switch = 0;
3426 --sig_raised;
3427 }
3428
3429 if (sig_suspend_switch > 0) /* SIGUSR2 */
3430 {
3431 TPT((0, FIL__, __LINE__, _("msg=<Suspend switch.>\n")));
3432 if (sh_global_suspend_flag == 1) {
3433 sh_global_suspend_flag = 0;
3434 } else {
3435 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_SUSPEND,
3436 sh.prg_name);
3437 sh_global_suspend_flag = 1;
3438 }
3439 --sig_suspend_switch;
3440 --sig_raised; --sig_urgent;
3441 }
3442
3443 sig_raised = (sig_raised < 0) ? 0 : sig_raised;
3444 sig_urgent = (sig_urgent < 0) ? 0 : sig_urgent;
3445 TPT((0, FIL__, __LINE__, _("msg=<End signal processing.>\n")));
3446 }
3447
3448 if (sh_global_suspend_flag == 1)
3449 {
3450 (void) retry_msleep (1, 0);
3451 continue;
3452 }
3453
3454 /* Recompute the descriptor set. select() modifies it,
3455 * thus we update it using the info from the connection table.
3456 * Also recompute the number of open connections.
3457 */
3458 FD_ZERO( &readset );
3459 FD_ZERO( &writeset );
3460 high_fd = conns[0].fd;
3461
3462 for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
3463 {
3464 FD_SET(conns[sock].fd, &readset );
3465 high_fd = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
3466 }
3467
3468 if (conns[sock_unix].fd > -1)
3469 {
3470 FD_SET(conns[sock_unix].fd, &readset );
3471 high_fd = (high_fd > conns[sock_unix].fd) ? high_fd : conns[sock_unix].fd;
3472 }
3473
3474#ifdef INET_SYSLOG
3475 for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
3476 {
3477 if (conns[sock].fd > -1)
3478 {
3479 FD_SET(conns[sock].fd, &readset );
3480 high_fd = (high_fd > conns[sock].fd) ? high_fd : conns[sock].fd;
3481 }
3482 }
3483#endif
3484
3485 time_now = (unsigned long) time (NULL);
3486 nowconn = 1;
3487
3488 for (i = SH_MINSOCK; i < maxconn; ++i)
3489 {
3490 /* eliminate timed out connections
3491 */
3492 if (conns[i].state != CONN_FREE)
3493 {
3494 if (time_now-conns[i].timer > time_out)
3495 {
3496 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_TIMOUT,
3497 conns[i].peer);
3498 sh_xfer_do_free ( &conns[i]);
3499 }
3500 else
3501 ++nowconn;
3502 }
3503
3504
3505 if (conns[i].state == CONN_READING)
3506 {
3507 FD_SET(conns[i].fd, &readset);
3508 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
3509 }
3510 else if (conns[i].state == CONN_SENDING)
3511 {
3512 FD_SET(conns[i].fd, &writeset);
3513 high_fd = (high_fd < conns[i].fd ? conns[i].fd : high_fd);
3514 }
3515 }
3516
3517 /* -- Exponentially reduce timeout limit if more than 1/2 full. --
3518 */
3519 /* Eliminate this, will cause problems when too much clients are
3520 * starting up. */
3521#if 0
3522 if (nowconn > (maxconn/2))
3523 time_out = ( (time_out/2) > 1) ? (time_out/2) : 1;
3524 else
3525 time_out = time_out_val;
3526#endif
3527
3528
3529 /* -- Do the select(). --
3530 */
3531 num_sel = select(high_fd+1, &readset, &writeset, NULL, &tv);
3532 errnum = errno;
3533
3534 /* reset timeout - modified by select() on some systems
3535 */
3536 tv.tv_sec = 5;
3537 tv.tv_usec = 0;
3538
3539
3540 if ( (time_now - time_last) > 2L)
3541 {
3542 time_last = time_now;
3543 if (sh_html_write(all_clients) < 0)
3544 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
3545 }
3546
3547
3548 /* Error handling.
3549 */
3550 if ( num_sel < 0 ) /* some error */
3551 {
3552 char errbuf[SH_ERRBUF_SIZE];
3553
3554 if (sig_raised == 1)
3555 {
3556 sig_raised = 2;
3557 continue;
3558 }
3559
3560 if ( errnum == EINTR)
3561 continue; /* try again */
3562
3563 if ( errnum == EBADF)
3564 {
3565 /* seek and destroy the bad fd
3566 */
3567 for (i = SH_MINSOCK; i < high_fd; ++i)
3568 {
3569 if ((conns[i].state == CONN_READING) ||
3570 (conns[i].state == CONN_SENDING))
3571 {
3572 if (-1 == retry_fcntl(FIL__, __LINE__,
3573 conns[i].fd, F_GETFL, dummy))
3574 sh_xfer_do_free ( &conns[i]);
3575 }
3576 }
3577 continue;
3578 }
3579
3580 sh_error_handle((-1), FIL__, __LINE__, errnum, MSG_EXIT_ABORTS,
3581 sh_error_message(errnum, errbuf, sizeof(errbuf)),
3582 sh.prg_name,
3583 _("select"));
3584 aud_exit(FIL__, __LINE__, EXIT_FAILURE );
3585 }
3586
3587
3588 /* log the timestamp
3589 */
3590 if ((tcurrent - told) > sh.looptime )
3591 {
3592 told = tcurrent;
3593#ifdef MEM_DEBUG
3594 sh_mem_check();
3595 sh_unix_count_mlock();
3596#else
3597 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_STAMP);
3598#endif
3599 }
3600
3601#if defined(SH_WITH_MAIL)
3602 /*
3603 * flush the mail queue
3604 */
3605 if (tcurrent - sh.mailTime.alarm_last > sh.mailTime.alarm_interval)
3606 {
3607 TPT((0, FIL__, __LINE__, _("msg=<Flush mail queue.>\n")))
3608 (void) sh_nmail_flush ();
3609 sh.mailTime.alarm_last = tcurrent;
3610 }
3611#endif
3612#ifdef MEM_DEBUG
3613 sh_mem_dump();
3614#endif
3615
3616 tcurrent = (unsigned long) time (NULL);
3617
3618 /* check for time limit exceeded
3619 */
3620 if ((tcurrent - tchkold) > (unsigned int) 3 )
3621 {
3622 tchkold = tcurrent;
3623 client_time_check(/* all_clients */);
3624 /* reset cache */
3625 sh_userid_destroy();
3626 }
3627
3628 /* seed / re-seed the PRNG if required
3629 */
3630 (void) taus_seed();
3631
3632 /* select() timeout handling.
3633 */
3634 if ( num_sel == 0 ) /* timeout - no connection */
3635 {
3636 if (sh_html_write(all_clients) < 0)
3637 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_HTML);
3638 continue;
3639 }
3640
3641 /* New connection.
3642 */
3643 for (sock = sock_tcp[0]; sock < sock_tcp[1]; ++sock)
3644 {
3645 if ( FD_ISSET(conns[sock].fd , &readset )) /* a new connection */
3646 {
3647 --num_sel;
3648 status = 0;
3649 if (nowconn < maxconn && sig_terminate == 0 && sig_termfast == 0)
3650 {
3651 /* Find a free slot to accept the connection
3652 */
3653 i = SH_MINSOCK;
3654 while (i < maxconn)
3655 {
3656 if (conns[i].state == CONN_FREE)
3657 {
3658 /* Here we run the accept() and copy the peer to
3659 * the free slot.
3660 */
3661 status = sh_xfer_accept(conns[sock].fd, &conns[i]);
3662
3663 if (status == 0)
3664 {
3665 high_fd =
3666 (high_fd > conns[i].fd ? high_fd : conns[i].fd);
3667 ++server_status.conn_open;
3668 ++server_status.conn_total;
3669 server_status.last = time (NULL);
3670 }
3671 break;
3672 }
3673 ++i;
3674 }
3675 }
3676 /* This re-runs select to accept data on the new
3677 * connection, rather than first dealing with old
3678 * connections.
3679 */
3680 if (status == 0)
3681 continue;
3682 }
3683 }
3684
3685 /* check for commands on the socket
3686 */
3687 if (conns[sock_unix].fd > (-1) && FD_ISSET(conns[sock_unix].fd , &readset ))
3688 {
3689 sh_socket_poll();
3690 }
3691
3692#ifdef INET_SYSLOG
3693 for (sock = sock_log[0]; sock < sock_log[1]; ++sock)
3694 {
3695 if (conns[sock].fd > (-1) && FD_ISSET(conns[sock].fd , &readset ))
3696 {
3697 sh_xfer_recv_syslog_socket (conns[sock].fd);
3698 }
3699 }
3700#endif
3701
3702 /* Check for pending read/write on the rest of the sockets.
3703 */
3704 for ( i = SH_MINSOCK; num_sel > 0 && i < maxconn; ++i )
3705 {
3706 if (sig_termfast == 1)
3707 break;
3708
3709 cx = &conns[i];
3710 if ( cx->state == CONN_READING &&
3711 FD_ISSET( cx->fd, &readset ) )
3712 {
3713 --num_sel;
3714 sh_xfer_do_read ( cx );
3715 }
3716 else if ( cx->state == CONN_SENDING &&
3717 FD_ISSET( cx->fd, &writeset ) )
3718 {
3719 --num_sel;
3720 sh_xfer_do_write ( cx );
3721 }
3722 }
3723 /* continue */
3724 }
3725 /* notreached */
3726}
3727
3728void free_client_tree (void)
3729{
3730 SL_ENTER(_("free_client_tree"));
3731 zAVLFreeTree (all_clients, free_client);
3732 SL_RET0(_("free_client_tree"));
3733}
3734
3735void sh_xfer_free_all ()
3736{
3737 register int i;
3738
3739 SL_ENTER(_("sh_xfer_free_all"));
3740
3741 if (conns != NULL)
3742 for (i = SH_MINSOCK; i < maxconn; ++i)
3743 {
3744 sh_xfer_do_free ( &conns[i]);
3745 }
3746
3747
3748 free_client_tree ();
3749
3750 if (conns != NULL)
3751 SH_FREE (conns);
3752
3753 SL_RET0(_("sh_xfer_free_all"));
3754}
3755
3756
3757
3758/* #ifdef SH_WITH_SERVER */
3759#endif
3760
3761
3762
3763
3764
3765
Note: See TracBrowser for help on using the repository browser.