source: trunk/src/sh_xfer_server.c@ 583

Last change on this file since 583 was 583, checked in by katerina, 32 hours ago

Fix for ticket #471 (autoreconf throws warnings/errors).

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