source: trunk/src/sh_xfer_server.c@ 578

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

Implement ticket #465 (server option to register alias for hostname).

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