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