source: trunk/src/sh_xfer_server.c@ 590

Last change on this file since 590 was 590, checked in by katerina, 27 hours ago

Fix for ticket #478 (cppcheck warnings).

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