source: trunk/src/sh_xfer_client.c @ 481

Last change on this file since 481 was 481, checked in by katerina, 6 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

File size: 39.7 KB
Line 
1/* SAMHAIN file system integrity testing                                   */
2/* Copyright (C) 1999, 2000, 2015 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
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#ifdef HAVE_SYS_SELECT_H
73#include <sys/select.h>
74#endif
75
76#ifdef  HAVE_UNISTD_H
77#include <errno.h>
78#include <signal.h>
79#include <setjmp.h>
80#include <pwd.h>
81#include <grp.h>
82#include <sys/stat.h>
83#include <sys/resource.h>
84#include <fcntl.h>
85#include <sys/wait.h>
86#include <unistd.h>
87#endif
88
89#ifndef FD_SET
90#define NFDBITS         32
91#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
92#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
93#define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
94#endif /* !FD_SET */
95#ifndef FD_SETSIZE
96#define FD_SETSIZE      32
97#endif
98#ifndef FD_ZERO
99#define FD_ZERO(p)      memset((char *)(p), '\0', sizeof(*(p)))
100#endif
101
102#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
103#include <sys/mman.h>
104#endif
105
106
107#include <netdb.h> 
108#include <sys/types.h> 
109#include <netinet/in.h> 
110#include <sys/socket.h> 
111#ifndef S_SPLINT_S
112#include <arpa/inet.h>
113#endif
114
115#include "sh_ipvx.h"
116#include "samhain.h"
117#include "sh_tiger.h"
118#include "sh_utils.h"
119#include "sh_unix.h"
120#include "sh_xfer.h"
121#include "sh_srp.h"
122#include "sh_fifo.h"
123#include "sh_tools.h"
124#include "sh_entropy.h"
125#include "sh_html.h"
126#include "sh_nmail.h"
127#include "sh_socket.h"
128#define SH_NEED_GETHOSTBYXXX
129#include "sh_static.h"
130
131#ifdef SH_ENCRYPT
132#include "rijndael-api-fst.h"
133char * sh_tools_makePack (unsigned char * header, int flag,
134                          char * payload, unsigned long payload_size,
135                          keyInstance * keyInstE);
136char * sh_tools_revertPack (unsigned char * header, int flag, char * message,
137                            keyInstance * keyInstE, 
138                            unsigned long message_size);
139#endif
140
141/* define this if you want to debug the client/server communication */
142/* #define SH_DBG_PROT 1 */
143
144#ifdef  SH_DBG_PROT
145#define SH_SHOWPROT(c,d) sh_tools_show_header((c), (d))
146#else
147#define SH_SHOWPROT(c,d)
148#endif
149
150/* the port client will be connecting to
151 */
152#ifndef SH_DEFAULT_PORT
153#define SH_DEFAULT_PORT 49777   
154#endif
155
156#ifndef SH_SELECT_REPEAT
157#define SH_SELECT_REPEAT 60
158#endif
159
160#ifndef SH_HEADER_SIZE
161#define SH_HEADER_SIZE 7
162#endif
163
164#ifndef SH_CHALLENGE_SIZE
165#define SH_CHALLENGE_SIZE 9
166#endif
167
168#undef  FIL__
169#define FIL__  _("sh_xfer_client.c")
170
171extern int flag_err_debug;
172extern int flag_err_info;
173
174#ifndef SH_STANDALONE
175
176#if defined(WITH_TRACE) || defined(WITH_TPT)
177char * hu_trans(const char * ihu)
178{
179  static char ohu[17];
180  sprintf(ohu, _("%c%03o"), '\\',                   /* known to fit  */
181          (unsigned char) ihu[0]);
182  sprintf(&(ohu[4]), _("%c%03o"), '\\',             /* known to fit  */
183          (unsigned char) ihu[1]);
184  sprintf(&(ohu[8]), _("%c%03o"), '\\',             /* known to fit  */
185          (unsigned char) ihu[2]);
186  sprintf(&(ohu[12]), _("%c%03o"), '\\',            /* known to fit  */
187          (unsigned char) ihu[3]);
188  ohu[16] = '\0';
189  return ohu;
190}
191#endif
192/* #ifndef SH_STANDALONE */
193#endif
194
195#if !defined(USE_SRP_PROTOCOL)
196void sh_passwd (char * salt, char * password, char * nounce, char *hash)
197{
198
199  char           *combi;
200  size_t          len;
201  unsigned char * tmp = NULL;
202  char hashbuf[KEYBUF_SIZE];
203
204  if (password == NULL)
205    {
206      tmp = (unsigned char *) &(skey->pw[0]);
207      memcpy(skey->vernam, tmp, PW_LEN);
208      sl_strlcpy (skey->vernam,
209                  sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN,
210                                hashbuf, sizeof(hashbuf)), 
211                  KEY_LEN+1);
212    }
213  else if (sl_strlen(password) < PW_LEN)
214    {
215      fprintf(stderr, _("Password has less than %d chars !\n"),
216                   PW_LEN);
217      _exit(EXIT_FAILURE);
218    }
219  else
220    {
221      sl_strlcpy (skey->vernam, password, KEY_LEN+1);
222    }
223
224  len = sl_strlen(salt) + 1;
225  if (sl_ok_adds(len, sl_strlen(skey->vernam)))
226    len += sl_strlen(skey->vernam);
227  if (nounce != NULL && sl_ok_adds(len, sl_strlen(nounce))) 
228    len += sl_strlen(nounce);
229 
230  /* H(s,P)
231   */
232  combi = SH_ALLOC(len);
233  (void) sl_strlcpy (combi, salt, len);
234  (void) sl_strlcat (combi, skey->vernam, len);
235  if (nounce != NULL)
236    (void) sl_strlcat (combi, nounce, len);
237  (void) sl_strlcpy (hash, 
238                     sh_tiger_hash(combi, TIGER_DATA, 
239                                   (unsigned long) sl_strlen(combi),
240                                   hashbuf, sizeof(hashbuf)),
241                     KEY_LEN+1);
242  SH_FREE (combi);
243  hash[KEY_LEN] = '\0';
244  return;
245}
246#endif
247
248#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
249
250/* Server addresses in use
251 */
252static int count_dev_server = 0;
253
254void reset_count_dev_server(void)
255{
256  count_dev_server = 0;
257  return;
258}
259
260int sh_xfer_set_logserver (const char * address)
261{
262  SL_ENTER(_("sh_xfer_set_logserver"));
263
264  if (address != NULL && count_dev_server < 2 
265      && sl_strlen(address) < SH_PATHBUF && sl_strlen(address) > 0) 
266    {
267      if (count_dev_server == 0)
268        (void) sl_strlcpy (sh.srvexport.name, address, SH_PATHBUF);
269      else
270        (void) sl_strlcpy (sh.srvexport.alt,  address, SH_PATHBUF);
271
272      ++count_dev_server;
273      SL_RETURN (0, _("sh_xfer_set_logserver"));
274    }
275  SL_RETURN (-1, _("sh_xfer_set_logserver"));
276}
277
278static
279int xfer_send_intern (int mysocket, const int protocol, char * micro, 
280                      char * msgbuf, unsigned long length, int docrypt)
281{
282  unsigned long           numbytes, countbytes;
283  int                     flag_err = 0;
284  unsigned char           head[SH_HEADER_SIZE];
285  char                  * outbuf;
286#ifdef SH_ENCRYPT
287  char                  * msg2buf = NULL;
288#else
289  (void) docrypt;
290#endif
291
292  SL_ENTER(_("xfer_send_intern"));
293
294#ifdef SH_ENCRYPT
295  if  ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
296    {
297      put_header (head, protocol, &length, micro);
298      msg2buf  = sh_tools_makePack (head, 0, msgbuf, length, 
299                                    &(skey->keyInstE));
300      length   = (unsigned long) (256 * (unsigned int)head[1] + 
301                                  (unsigned int)head[2]);
302      outbuf   = msg2buf;
303    }
304  else
305    {
306      outbuf = msgbuf;
307      put_header (head, protocol, &length, micro);
308    }
309#else
310  outbuf = msgbuf;
311  put_header (head, protocol, &length, micro);
312#endif
313
314  SH_SHOWPROT(head,'>');
315 
316  numbytes     = SH_HEADER_SIZE;
317  countbytes   = write_port (mysocket, (char *)head, numbytes, &flag_err, 300);
318
319  if (countbytes == numbytes && outbuf != NULL)
320    {
321      numbytes     = length;
322      countbytes   = write_port (mysocket, outbuf, numbytes, &flag_err, 300);
323    }
324
325#ifdef SH_ENCRYPT
326  if (msg2buf != NULL)
327    SH_FREE(msg2buf);
328#endif
329
330  if (countbytes == numbytes)
331    SL_RETURN( 0, _("xfer_send_intern"));
332  else
333    SL_RETURN( flag_err, _("xfer_send_intern"));
334}
335
336static
337int xfer_send (int mysocket, const int protocol, char * micro, 
338                     char * msgbuf, unsigned long length)
339{
340  int i;
341  SL_ENTER(_("xfer_send"));
342  TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
343  i =  xfer_send_intern (mysocket, protocol, micro, 
344                               msgbuf, length, S_FALSE);
345  SL_RETURN(i, _("xfer_send"));
346}
347static
348int xfer_send_crypt (int mysocket, const int protocol, char * micro, 
349                           char * msgbuf, unsigned long length)
350{
351  int i;
352  SL_ENTER(_("xfer_send_crypt"));
353#ifdef SH_ENCRYPT
354  TPT(( 0, FIL__, __LINE__, _("msg=<Send encrypted.>\n")));
355#else
356  TPT(( 0, FIL__, __LINE__, _("msg=<Send.>\n")));
357#endif
358  i = xfer_send_intern (mysocket, protocol, micro, 
359                              msgbuf, length, S_TRUE);
360  SL_RETURN(i, _("xfer_send_crypt"));
361}
362
363
364/* receive answer, add a trailing NULL to terminate string
365 * decrypt answer
366 */
367static
368long xfer_receive_intern (int mysocket, const int protocol, char * micro,     
369                          char *  msgbuf, unsigned long length, 
370                          int docrypt)
371{
372  unsigned long numbytes, countbytes;
373  int           flag_err = -1;
374  unsigned char head[SH_HEADER_SIZE];
375#ifndef SH_ENCRYPT
376  (void) docrypt;
377#endif
378
379  SL_ENTER(_("xfer_receive_intern"));
380
381#ifdef SH_ENCRYPT
382  /* make sure length is not multiple of B_SIZ, see below
383   */
384  ASSERT_RET((length % B_SIZ != 0), _("length % 16 != 0"), flag_err);
385#endif
386
387  if (micro != NULL)
388    micro[4]     = '\0';
389  if (msgbuf != NULL)
390    msgbuf[0]     = '\0';
391
392  numbytes     = SH_HEADER_SIZE;
393  countbytes   = read_port (mysocket, (char *)head, numbytes, &flag_err, 300);
394
395  if (countbytes != numbytes)
396    {
397      TPT(( 0, FIL__, __LINE__, _("msg=<countbytes != numbytes>\n")));
398      SL_RETURN(flag_err, _("xfer_receive_intern"));
399    }
400  else if (msgbuf == NULL)
401    {
402      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
403                      _("msgbuf is NULL"), _("xfer_receive_intern"));
404      SL_RETURN((-1), _("xfer_receive_intern"));
405    }
406  else if (head[0] != protocol && (head[0] & SH_PROTO_SRP) == 0)
407    {
408      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_MISMATCH);
409      SL_RETURN((-1), _("xfer_receive_intern"));
410    }
411  else
412    {
413      get_header (head, &numbytes, micro);
414      SH_SHOWPROT(head, '<');
415
416      if (numbytes > 0)
417        {
418          numbytes = (numbytes > length ? length : numbytes);
419
420          countbytes = read_port (mysocket, msgbuf, numbytes, &flag_err, 300);
421
422          if (countbytes < length)
423            msgbuf[countbytes] = '\0';
424          else
425            msgbuf[length-1] = '\0';
426
427          if (flag_err != 0)
428            {
429              TPT(( 0, FIL__, __LINE__, _("msg=<read error>\n")));
430              SL_RETURN((-1), _("xfer_receive_intern"));
431            }
432        }
433    }
434
435#ifdef SH_ENCRYPT
436  if      ((S_TRUE == docrypt) && ((protocol & SH_PROTO_ENC) != 0))
437    {
438      unsigned long head_length;
439      char * tmp = SH_ALLOC((size_t)length);
440
441      memcpy(tmp, msgbuf, (size_t)length);
442      tmp = sh_tools_revertPack (head, 0, tmp, &(skey->keyInstD), countbytes);
443
444      head_length = (unsigned long) (256 * (unsigned int)head[1] + 
445                                     (unsigned int)head[2]);
446
447      /*
448       * revertPack returns header with length <= (original_length-16), so
449       * the following msgbuf[length] = '\0' is always safe.
450       * Nevertheless, check for proper length.
451       */
452      if (head_length <= (length-1))
453        length      = head_length;
454      else
455        --length;
456
457      memcpy(msgbuf, tmp, (size_t)length);
458      msgbuf[length] = '\0';
459      SH_FREE(tmp);
460      if (countbytes == numbytes) 
461        countbytes = length; /* to avoid error on return, see below */
462      numbytes = length;
463    }
464#endif
465
466  if (countbytes == numbytes)
467    SL_RETURN(((long)numbytes), _("xfer_receive_intern"));
468  else
469    {
470      TPT(( 0, FIL__, __LINE__, _("msg=<short read>\n")));
471      SL_RETURN(flag_err, _("xfer_receive_intern"));
472    }
473}
474
475static
476long xfer_receive (int mysocket, const int protocol, char * micro,     
477                   char * msgbuf, unsigned long length)
478{
479  long i;
480  SL_ENTER(_("xfer_receive"));
481  TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
482  i = xfer_receive_intern (mysocket, protocol, micro, 
483                           msgbuf, length, S_FALSE);
484  SL_RETURN(i, _("xfer_receive"));
485}
486
487static
488long xfer_receive_crypt (int mysocket, const int protocol, char * micro,     
489                         char * msgbuf, unsigned long length)
490{
491  long i;
492  SL_ENTER(_("xfer_receive_crypt"));
493#ifdef SH_ENCRYPT
494  TPT(( 0, FIL__, __LINE__, _("msg=<Receive encrypted.>\n")));
495#else
496  TPT(( 0, FIL__, __LINE__, _("msg=<Receive.>\n")));
497#endif
498  i = xfer_receive_intern (mysocket, protocol, micro, 
499                           msgbuf, length, S_TRUE);
500  SL_RETURN(i, _("xfer_receive_crypt"));
501}
502
503/**************************************************
504 *
505 *
506 *  C L I E N T 
507 *
508 *
509 ***************************************************/
510
511
512#include <time.h>
513
514static SH_FIFO * fifo = NULL;
515
516static long xfer_try_report (char * errmsg);
517
518unsigned int ServerPort = SH_DEFAULT_PORT;
519
520int sh_xfer_server_port (const char * str)
521{
522  unsigned long l;
523  char * endptr;
524
525  SL_ENTER(_("sh_xfer_server_port"));
526
527  l = strtoul (str, &endptr, 0);
528  if (l > 65535 || endptr == str)
529    {
530      SL_RETURN (-1, _("sh_xfer_server_port"));
531    }
532  ServerPort = (unsigned int) l;
533  SL_RETURN (0, _("sh_xfer_server_port"));
534}
535
536long sh_xfer_report (char * errmsg)
537{
538  static int have_server = S_TRUE;
539  long   status;
540  char * popmsg;
541  static int nofail = S_TRUE;
542
543  SL_ENTER(_("sh_xfer_report"));
544
545  /* --- No log server available. ---
546   */
547  if (have_server == S_TRUE && sh.srvexport.name[0] == '\0')
548    {
549      have_server = S_FALSE;
550      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NONAME);
551      SL_RETURN (-1, _("sh_xfer_report"));
552    }
553  else if (have_server == BAD)
554    {
555      SL_RETURN (-1, _("sh_xfer_report"));
556    }
557
558  /* --- Allocate fifo. ---
559   */
560  if (fifo == NULL)
561    {
562      fifo = SH_ALLOC(sizeof(SH_FIFO));
563      fifo_init(fifo);
564    }
565
566  /* --- Check for messages on the queue, and send them first. ---
567   */
568  while (NULL != (popmsg = pop_list(fifo)) )
569    {
570      status = xfer_try_report (popmsg);
571      if (status != 0)
572        {
573          (void) push_tail_list (fifo, popmsg, 0, NULL); 
574          SH_FREE(popmsg);
575          if (SH_FIFO_MAX == push_list (fifo, errmsg, 0,NULL))
576            SL_RETURN (-2, _("sh_xfer_report"));
577          SL_RETURN (-1, _("sh_xfer_report"));
578        }
579      SH_FREE(popmsg);
580    }
581
582  /* --- Now send the error message. ---
583   */ 
584  status = xfer_try_report (errmsg);
585  if (status != 0)
586    {
587      if (nofail == S_TRUE)
588        sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_SRV_FAIL,
589                         _("log server"), sh.srvexport.name);
590      nofail = S_FALSE;
591      if (SH_FIFO_MAX == push_list (fifo, errmsg, 0, NULL))
592        SL_RETURN (-2, _("sh_xfer_report"));
593      SL_RETURN (-1, _("sh_xfer_report"));
594    }
595
596  nofail = S_TRUE;
597  SL_RETURN (0, _("sh_xfer_report")); 
598}
599
600static long xfer_try_report_int (char * errmsg, const int what);
601
602static long xfer_try_report (char * errmsg)
603{
604  long i;
605  SL_ENTER(_("xfer_try_report"));
606  i = xfer_try_report_int (errmsg, SH_PROTO_MSG);
607  SL_RETURN(i, _("xfer_try_report")); 
608}
609
610long sh_xfer_request_file (const char * file)
611{
612  long i;
613  char tmp_file[64];
614  SL_ENTER(_("sh_xfer_request_file"));
615  sl_strlcpy(tmp_file, file, sizeof(tmp_file));
616  i = xfer_try_report_int (tmp_file, SH_PROTO_BIG);
617  SL_RETURN(i, _("sh_xfer_request_file")); 
618}
619
620static unsigned long sh_throttle_delay = 0;
621
622int sh_xfer_set_throttle_delay (const char * c)
623{
624  long val;
625
626  SL_ENTER(_("sh_xfer_set_throttle_delay"));
627  val = strtol (c, (char **)NULL, 10);
628  if (val < 0)
629    SL_RETURN( (-1), _("sh_xfer_set_throttle_delay"));
630
631  val = (val > 1000) ? 1000 : val;
632
633  sh_throttle_delay = (unsigned long) val;
634  SL_RETURN( (0), _("sh_xfer_set_throttle_delay"));
635}
636
637static time_t xfer_timeout_val =  1;
638
639static int xfer_conn_state(int initialized, int conn_state)
640{
641  static time_t time_now  = 1200;
642  static time_t time_last =    0;
643
644  if (initialized == S_FALSE || conn_state == S_FALSE)
645    {
646      xfer_timeout_val = 
647        ((xfer_timeout_val > TIMEOUT_CON) ? TIMEOUT_CON : xfer_timeout_val);
648
649      /* --- Retry bad attempt only after some time. ---
650       */
651      time_now  = time (NULL);
652      if ((time_now - time_last) < xfer_timeout_val) 
653        {
654          TPT(( 0, FIL__, __LINE__, _("msg=<Within deadtime, no retry.>\n")));
655          return -1;
656        }
657      TPT(( 0, FIL__, __LINE__, _("msg=<Retry.>\n")));
658    }
659  time_last  = time (NULL);
660  return 0;
661}
662
663static int xfer_connect(int * conn_state)
664{
665  char         error_msg[256];
666  char         error_call[SH_MINIBUF] = { 0 };
667  int          error_num = 0;
668
669  int sockfd = connect_port_2 (sh.srvexport.name, sh.srvexport.alt, ServerPort, 
670                               error_call, &error_num, error_msg, 256);
671
672  if (sockfd < 3)
673    {
674      *conn_state = S_FALSE;
675      xfer_timeout_val *= 2;
676      sh_error_handle ((-1), FIL__, __LINE__, error_num, 
677                       MSG_E_NET, error_msg, error_call,
678                       _("export"), sh.srvexport.name);
679      return -1;
680    }
681
682  *conn_state = S_TRUE;
683  return sockfd;
684}
685
686int xfer_greet_server(int sockfd, char * answer)
687{
688  int    flag_err;
689  char   head_u[5];
690  int    theProto = SH_PROTO_SRP;
691 
692  TPT(( 0, FIL__, __LINE__, _("msg=<c/r: entry>\n")));
693 
694  sl_strlcpy (answer, sh.host.name, 512);
695     
696  flag_err = xfer_send (sockfd, theProto, _("SALT"), 
697                        answer,  (unsigned long)sl_strlen(answer));
698     
699  TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent SALT, flag_err = %d>\n"), 
700        flag_err));
701     
702  /* get nonce from server
703   */
704  if (flag_err == 0)
705    {
706      flag_err = xfer_receive (sockfd, (char)theProto, head_u, 
707                                   answer,  511);
708      flag_err = (flag_err < 0) ? flag_err : 0;
709      TPT(( 0, FIL__, __LINE__, 
710            _("msg=<c/r: rcvt nonce, flag_err = %d>\n"), 
711            flag_err));
712    }
713 
714  if ( 0 != check_request (head_u, _("INIT")) )
715    {
716      TPT(( 0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), head_u[0], head_u[1], head_u[2], head_u[3]));
717      flag_err = -1;
718    }
719  return flag_err;
720}
721 
722
723#if !defined(USE_SRP_PROTOCOL)
724
725static int xfer_auth(int is_reinit, int * initialized, 
726                     int sockfd, char * answer)
727{
728  /**************************************************
729   *
730   * --- challenge/response authentication ---
731   *
732   **************************************************/
733
734  int                  flag_err = 0;
735  int                  theProto = 0;
736  char   nounce[KEY_LEN+1];
737  char   temp[2*KEY_LEN+1];
738  char   nonce_u[KEY_LEN+1];
739  UINT32 ticks;
740
741  char   head_u[5];
742  char   foo_M1[KEY_LEN+1];
743  char   hashbuf[KEYBUF_SIZE];
744#ifdef SH_ENCRYPT
745  int err_num;
746  char expbuf[SH_ERRBUF_SIZE];
747#endif
748
749  SL_REQUIRE((sockfd > 2), _("sockfd > 2"));
750
751  if (is_reinit == S_FALSE)
752    flag_err = xfer_greet_server(sockfd, answer);
753  else
754    sh_tools_probe_reset();
755
756  /* entry point for jump from message forward if session key must
757   * be re-initialized
758   */   
759
760  if ( flag_err == 0 && sl_strlen(answer) >  KEY_LEN )
761    (void) sl_strlcpy(nounce, &answer[KEY_LEN], KEY_LEN+1);
762  else
763    flag_err = (-1);
764 
765  TPT(( 0, FIL__, __LINE__, _("msg=<c/r: rcvt INIT, flag_err = %d>\n"), 
766        flag_err));
767 
768  /* verify random nonce v from server H(v, P)v
769   */
770  sh_passwd (nounce, NULL, NULL, temp);
771  if ( 0 != sl_strncmp(temp, answer, KEY_LEN))
772    flag_err = (-1);
773 
774  TPT(( 0, FIL__, __LINE__, _("msg=<c/r: vrfy nonce, flag_err = %d>\n"), 
775        flag_err));
776 
777 
778  /* --- Create own nonce. ---
779   */
780  ticks = (UINT32) taus_get ();
781 
782  (void) sl_strlcpy(nonce_u, 
783                    sh_tiger_hash((char *) &ticks, 
784                                  TIGER_DATA, 
785                                  (unsigned long)sizeof(UINT32), 
786                                  hashbuf, sizeof(hashbuf)),
787                    KEY_LEN+1);
788 
789  /* --- Form the message H(H(u,v),P)u ---
790   */
791  (void) sl_strlcpy(temp, nonce_u, 2*KEY_LEN+1); 
792  (void) sl_strlcat(temp,  nounce, 2*KEY_LEN+1); 
793  (void) sl_strlcpy(temp, 
794                    sh_tiger_hash(temp, 
795                                  TIGER_DATA, 
796                                  (unsigned long)sl_strlen(temp), 
797                                  hashbuf, sizeof(hashbuf)),
798                    KEY_LEN+1);
799  sh_passwd (temp, NULL, NULL, foo_M1);
800  (void) sl_strlcpy(temp, foo_M1, 2*KEY_LEN+1);
801  (void) sl_strlcat(temp, nonce_u, 2*KEY_LEN+1);
802 
803  /* --- Send it to server. ---
804   */
805  if (flag_err == 0)
806    {
807      flag_err = xfer_send (sockfd, 
808                            (theProto|SH_PROTO_SRP), 
809                            _("PASS"), temp, 
810                            (unsigned long)sl_strlen(temp));
811      TPT(( 0, FIL__, __LINE__, _("msg=<c/r: sent PASS, flag_err = %d>\n"),
812            flag_err));
813    }
814 
815  if (flag_err == 0)
816    {
817      flag_err = xfer_receive (sockfd,
818                               (theProto|SH_PROTO_SRP), 
819                               head_u, answer,  511); 
820      sh_passwd (nounce, NULL, nonce_u, foo_M1);
821      (void) sl_strlcpy (skey->session, foo_M1, KEY_LEN+1);
822#ifdef SH_ENCRYPT
823      err_num = rijndael_makeKey(&(skey->keyInstE), 
824                                 (BYTE)DIR_ENCRYPT, 192, skey->session);
825      if (err_num < 0)
826        sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
827                        errorExplain(err_num, expbuf, sizeof(expbuf)), 
828                        _("xfer_try_report_int: makeKey"));
829     
830      err_num = rijndael_makeKey(&(skey->keyInstD), 
831                                 (BYTE)DIR_DECRYPT, 192, skey->session);
832      if (err_num < 0)
833        sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
834                        errorExplain(err_num, expbuf, sizeof(expbuf)), 
835                        _("xfer_try_report_int: make_key"));
836#endif
837      *initialized = S_TRUE;
838    }
839 
840  if (*initialized == S_FALSE)
841    {
842      xfer_timeout_val *= 2;
843      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
844      memset(answer, 0, 512);
845      MUNLOCK(answer, 512);
846      SH_FREE(answer);
847      return -1;
848    }
849  else
850    {
851      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
852    }
853  return 0;
854}   
855#else
856
857static void noise()
858{
859  UINT32 n = taus_get();
860  retry_msleep(0, (n & 0x0000007F));
861  return;
862}
863 
864
865static int xfer_auth(int is_reinit, int * initialized, 
866                     int sockfd, char * answer)
867{
868  /* This is the SRP authenticated key exchange protocol.
869   * Produces a session key skey->session.
870   */
871 
872  int                  flag_err = 0;
873  int                  theProto = 0;
874
875  char   head_u[5];
876  char   u_real[SH_CHALLENGE_SIZE];
877  char * foo_A;
878  char * foo_Sc;
879  char * M;
880  char   foo_M1[KEY_LEN+1];
881  char   hashbuf[KEYBUF_SIZE];
882#ifdef SH_ENCRYPT
883  int err_num;
884  char expbuf[SH_ERRBUF_SIZE];
885#endif
886
887  SL_REQUIRE((sockfd > 2), _("sockfd > 2"));
888
889  if (is_reinit == S_FALSE)
890    flag_err = xfer_greet_server(sockfd, answer);
891  else
892    sh_tools_probe_reset();
893
894  /* Entry point for jump from message forward if session key must
895   * be re-initialized.
896   */   
897  TPT(( 0, FIL__, __LINE__, _("msg=<srp: INIT>\n")));
898 
899  if ( flag_err == 0 )
900    {
901      if (0 != sh_srp_init())
902        sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EBGN);
903      else 
904        {
905          TPT(( 0, FIL__, __LINE__, _("msg=<srp: bignum initialized>\n")));
906
907          sh_srp_x (answer, NULL);  /* x        password      */
908          sh_srp_make_a ();         /* a        random number */
909          foo_A = sh_srp_A();       /* g^a                    */
910
911          TPT(( 0, FIL__, __LINE__, _("msg=<srp: A = %s>\n"), foo_A));
912
913          if (foo_A == NULL)
914            flag_err = (-1);
915
916          noise();
917
918          if (flag_err == 0)
919            flag_err = xfer_send (sockfd, 
920                                  (theProto|SH_PROTO_SRP), 
921                                  _("PC01"),
922                                  foo_A, sl_strlen(foo_A)+1); 
923          if (flag_err == 0)
924            {
925              flag_err = xfer_receive (sockfd, 
926                                       (theProto|SH_PROTO_SRP),
927                                       head_u,
928                                       answer, 511);
929              flag_err = (flag_err < 0) ? flag_err : 0;
930              TPT(( 0, FIL__, __LINE__, _("msg=<srp: B = %s>\n"), answer));
931              TPT(( 0, FIL__, __LINE__, _("msg=<srp: u = %03o-%03o-%03o-%03o>\n"), head_u[0], head_u[1], head_u[2], head_u[3]));
932            }
933
934          /*                     u        nounce        */
935          /*                     B        answer        */
936          /*                     S = (B-g^x)^(a+ux)     */
937         
938   
939          if (flag_err == 0)
940            { 
941              noise();
942
943              if (0 != sh_srp_check_zero (answer))
944                sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_EZERO);
945              else 
946                {
947                  sl_strlcpy(u_real, sh_tiger_hash(head_u, TIGER_DATA, 4, 
948                                                   hashbuf, sizeof(hashbuf)), 
949                             SH_CHALLENGE_SIZE);
950                  foo_Sc = sh_srp_S_c (u_real, answer);
951                 
952                  TPT(( 0, FIL__, __LINE__, _("msg=<srp: U = %s>\n"), 
953                        u_real));
954                  TPT(( 0, FIL__, __LINE__, _("msg=<srp:Sc = %s>\n"), 
955                        foo_Sc));
956                 
957                  /* --- Now send H(A,B,H(Sc)) and check. ---
958                   */
959                  if (foo_Sc != NULL && 0 == sh_srp_check_zero (foo_Sc))
960                    {
961                      sh_srp_M(foo_A, 
962                               answer, 
963                               sh_tiger_hash(foo_Sc, 
964                                             TIGER_DATA, 
965                                             sl_strlen(foo_Sc), 
966                                             hashbuf, sizeof(hashbuf)),
967                               foo_M1, KEY_LEN+1);
968                     
969                     
970                      TPT(( 0, FIL__, __LINE__, _("msg=<srp:M1 = %s>\n"), 
971                            foo_M1));
972                     
973                      flag_err = xfer_send(sockfd, 
974                                           (theProto|SH_PROTO_SRP), 
975                                           _("PC02"),
976                                           foo_M1, KEY_LEN+1);
977                    }
978                  else
979                    flag_err = (-1);
980                 
981                  if (flag_err == 0)
982                    {
983                      flag_err = xfer_receive(sockfd, 
984                                              (theProto|SH_PROTO_SRP),
985                                              head_u, 
986                                              answer, 511);
987                      flag_err = (flag_err < 0) ? flag_err : 0;
988                      TPT(( 0, FIL__, __LINE__, _("msg=<srp: M = %s>\n"), 
989                            answer));
990                    }
991                 
992                  if (flag_err == 0   && 0 == check_request (head_u, _("PARP")) )
993                    {
994                      /* ------  verify M2 = H(A, M1, K) --------
995                       */
996                      char M_buf[KEY_LEN+1];
997                      M = sh_srp_M (foo_A, foo_M1,
998                                    sh_tiger_hash(foo_Sc,
999                                                  TIGER_DATA,
1000                                                  sl_strlen(foo_Sc), 
1001                                                  hashbuf, sizeof(hashbuf)),
1002                                    M_buf, sizeof(M_buf)
1003                                    );
1004                      if (M != NULL && 
1005                          0 == sl_strncmp (answer, M, KEY_LEN+1))
1006                        {
1007                          sl_strlcpy (skey->session, 
1008                                      sh_tiger_hash(foo_Sc, 
1009                                                    TIGER_DATA,
1010                                                    sl_strlen(foo_Sc), 
1011                                                    hashbuf, sizeof(hashbuf)),
1012                                      KEY_LEN+1);
1013                          TPT(( 0, FIL__, __LINE__, 
1014                                _("msg=<srp: Key = %s>\n"), 
1015                                skey->session));
1016
1017#ifdef SH_ENCRYPT
1018                          err_num = rijndael_makeKey(&(skey->keyInstE), 
1019                                                     DIR_ENCRYPT, 
1020                                                     192, skey->session);
1021                          if (err_num < 0)
1022                            sh_error_handle((-1), FIL__, __LINE__, -1, 
1023                                            MSG_E_SUBGEN,
1024                                            errorExplain(err_num, expbuf, sizeof(expbuf)), 
1025                                            _("xfer_try_report_int: makeKey"));
1026                          err_num = rijndael_makeKey(&(skey->keyInstD), 
1027                                                     DIR_DECRYPT, 
1028                                                     192, skey->session);
1029                          if (err_num < 0)
1030                            sh_error_handle((-1), FIL__, __LINE__, -1, 
1031                                            MSG_E_SUBGEN,
1032                                            errorExplain(err_num, expbuf, sizeof(expbuf)), 
1033                                            _("xfer_try_report_int: makeKey"));
1034#endif
1035                          *initialized = S_TRUE;
1036                          noise();
1037                        }
1038                    }
1039                  if (foo_Sc != NULL)
1040                    SH_FREE(foo_Sc);
1041                }
1042            }
1043          if (foo_A != NULL)
1044            SH_FREE(foo_A);
1045          sh_srp_exit();
1046        }
1047    }
1048
1049  if (*initialized == S_FALSE)
1050    {
1051      xfer_timeout_val *= 2;
1052      sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_NOAUTH);
1053      memset(answer, '\0', 512);
1054      MUNLOCK(answer, 512);
1055      SH_FREE(answer);
1056      return -1;
1057    }
1058  else
1059    {
1060      if (flag_err_info == S_TRUE)
1061        sh_error_handle((-1), FIL__, __LINE__, 0, MSG_TCP_AUTH);
1062    }
1063  return 0;
1064}
1065#endif
1066
1067int xfer_check_server_cmd(char * answer, char * buffer)
1068{
1069  int    flag_err;
1070  size_t pos;
1071  char   sigbuf[KEYBUF_SIZE];
1072
1073  /* --- SERVER CMD --- */
1074  if (answer[KEY_LEN] != '\0' && 
1075      sl_strlen(answer) > (2*KEY_LEN))
1076    {
1077      pos = sl_strlen(answer) - (2*KEY_LEN);
1078      /*
1079       * buffer is  >= 256
1080       * answer has <= 255 bytes
1081       */
1082      (void) sl_strlcpy(buffer, &answer[KEY_LEN], 
1083                        pos+1);
1084      flag_err = 
1085        sl_strncmp(&answer[KEY_LEN+pos],
1086                   sh_util_siggen(skey->session, 
1087                                  buffer,
1088                                  pos,
1089                                  sigbuf, sizeof(sigbuf)),
1090                   KEY_LEN);
1091     
1092      TPT((0, FIL__, __LINE__, 
1093           _("CONF RECV <%d> <%s>\n"),
1094           flag_err, &answer[KEY_LEN]));
1095     
1096      if (flag_err != 0) {
1097        sh_error_handle((-1), FIL__, __LINE__, 
1098                        flag_err,
1099                        MSG_TCP_NOCONF);
1100      } 
1101#ifdef SH_WITH_CLIENT
1102      else {
1103        sh_socket_server_cmd(buffer);
1104      }
1105#endif
1106      flag_err = 0;
1107     
1108    } else {
1109   
1110    TPT((0, FIL__, __LINE__, 
1111         _("CONF RECV <0> <[null]>\n")));
1112   
1113  }
1114  /* --- SERVER CMD END --- */
1115  return 0;
1116}
1117
1118
1119
1120int xfer_send_message(char * errmsg, int sockfd, char * answer)
1121{
1122  char   hash[KEY_LEN+1];
1123  size_t len;
1124  char * buffer;
1125  char   nsrv[KEY_LEN+1];
1126  char   sigbuf[KEYBUF_SIZE];
1127  char   head_u[5];
1128  int    flag_err;
1129
1130  SL_REQUIRE((sockfd > 2), _("sockfd > 2"));
1131
1132  /* --- Save the challenge. --- 
1133   */
1134  (void) sl_strlcpy(nsrv, answer, KEY_LEN + 1);
1135 
1136  /* --- Hash(msg,challenge,sessionkey). --- 
1137   */
1138  len    = sl_strlen(errmsg) + sl_strlen(answer) 
1139    + KEY_LEN + 1;
1140  len = (size_t)((len < 256) ? 256 : len);
1141  buffer = SH_ALLOC(len);
1142  MLOCK(buffer, len);
1143  (void) sl_strlcpy(buffer, errmsg, len);
1144  (void) sl_strlcat(buffer, answer, len);
1145  (void) sl_strlcpy(hash, 
1146                    sh_util_siggen (skey->session, 
1147                                    buffer, 
1148                                    sl_strlen(buffer),
1149                                    sigbuf, sizeof(sigbuf)), 
1150                    KEY_LEN+1);
1151  TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1152       sh_util_siggen(skey->session, buffer, 
1153                      sl_strlen(buffer), sigbuf, sizeof(sigbuf))));
1154 
1155  (void) sl_strlcpy(buffer, errmsg, len);
1156  (void) sl_strlcat(buffer, hash,   len);
1157 
1158  flag_err = 
1159    xfer_send_crypt (sockfd, 
1160#ifdef SH_ENCRYPT
1161                     (char)(SH_PROTO_MSG|SH_PROTO_ENC),
1162#else
1163                     (char)(SH_PROTO_MSG),
1164#endif
1165                     _("MESG"),
1166                     buffer, 
1167                     (unsigned long)(sl_strlen(buffer)+1));
1168  TPT(( 0, FIL__, __LINE__, 
1169        _("msg=<Sent %s, status %d.>\n"), 
1170        answer, flag_err));
1171
1172  /* --- Get confirmation. ---
1173   */
1174  if (flag_err == 0)
1175    {
1176      flag_err = (int)
1177        xfer_receive_crypt (sockfd, 
1178#ifdef SH_ENCRYPT
1179                            (char)(SH_PROTO_MSG|SH_PROTO_ENC|SH_PROTO_END),
1180#else
1181                            (char)(SH_PROTO_MSG|SH_PROTO_END),
1182#endif
1183                            head_u, 
1184                            answer, 255);   
1185      TPT(( 0, FIL__, __LINE__, 
1186            _("msg=<Rcvt %s, u %s, status %d.>\n"), 
1187            answer, hu_trans(head_u), flag_err));
1188      flag_err = (flag_err < 0) ? flag_err : 0;
1189    }
1190
1191 
1192  /* --- Check confirmation. ---
1193   */
1194  if (flag_err == 0)
1195    {
1196      /*   CLIENT CONF RECV
1197       *
1198       *   first KEY_LEN bytes must be
1199       *   sig(skey->session (errmsg nsrv))
1200       *
1201       */
1202      (void) sl_strlcpy(buffer, errmsg, len);
1203      (void) sl_strlcat(buffer, nsrv,   len);
1204      flag_err = sl_strncmp(answer,
1205                            sh_util_siggen(skey->session, 
1206                                           buffer,
1207                                           sl_strlen(buffer),
1208                                           sigbuf, sizeof(sigbuf)),
1209                            KEY_LEN);
1210      TPT((0, FIL__, __LINE__, _("msg=<sign %s.>\n"),
1211           sh_util_siggen(skey->session, buffer, 
1212                          sl_strlen(buffer), sigbuf, sizeof(sigbuf))));
1213     
1214      if (flag_err != 0)
1215        {
1216#ifdef ENOMSG
1217          flag_err = ENOMSG;
1218#else
1219          flag_err = EIO;
1220#endif
1221          sh_error_handle((-1), FIL__, __LINE__, flag_err,
1222                          MSG_TCP_NOCONF);
1223        }
1224      else
1225        {
1226#ifdef SH_ENCRYPT
1227          flag_err = xfer_check_server_cmd(answer, buffer);
1228#endif
1229          if (flag_err_debug == S_TRUE)
1230            sh_error_handle((-1), FIL__, __LINE__, 0,
1231                            MSG_TCP_CONF);
1232        }
1233    }
1234 
1235  memset(buffer, 0, len);
1236  MUNLOCK(buffer, len);
1237  SH_FREE(buffer);
1238
1239  if (flag_err != 0)
1240    return -1;
1241  return 0;
1242}
1243
1244
1245static SL_TICKET xfer_get_file(int sockfd, char * answer, 
1246                               char * nclt, char * foo_M1, const int theProto)
1247{
1248  /* --- Open a temporary file. ---
1249   */
1250  int flag_err = 0;
1251  SL_TICKET sfd;
1252
1253  SL_REQUIRE((sockfd > 2), _("sockfd > 2"));
1254
1255  if ( (sfd = open_tmp ()) < 0)
1256    {
1257      flag_err = (-1);
1258      sh_error_handle((-1), FIL__, __LINE__, flag_err, MSG_TCP_EFIL);
1259    }
1260  else
1261    {
1262      /* --- Read from socket into tmp file. ---
1263       */
1264      int    transfercount = 0;
1265      char   head_u[5];
1266
1267      do {
1268        flag_err = (int)
1269          xfer_receive_crypt (sockfd, 
1270#ifdef SH_ENCRYPT
1271                              (char)(SH_PROTO_BIG|SH_PROTO_ENC),
1272#else
1273                              (char)(SH_PROTO_BIG),
1274#endif
1275                              head_u, 
1276                              answer, 
1277                              TRANS_BYTES + 255);
1278       
1279        TPT(( 0, FIL__, __LINE__, 
1280              _("msg=<Received: %d bytes, marked %s.>\n"),
1281              flag_err, hu_trans(head_u)));
1282
1283        if (flag_err > 0 && 0 == check_request_nerr(head_u, _("FILE")))
1284          {
1285            if (0 == hash_check (foo_M1, answer, flag_err))
1286              {
1287                (void) sl_write(sfd, &answer[KEY_LEN], 
1288                                flag_err-KEY_LEN);
1289                ++transfercount;
1290
1291                /*  Delay for throughput throttling
1292                 */
1293                if (sh_throttle_delay > 0)
1294                  retry_msleep(sh_throttle_delay/1000, sh_throttle_delay % 1000);
1295
1296                flag_err = xfer_send_crypt (sockfd, theProto, 
1297                                            _("RECV"),
1298                                            nclt, 
1299                                            (unsigned long)sl_strlen(nclt));
1300               
1301              }
1302            else
1303              {
1304                TPT(( 0, FIL__, __LINE__, 
1305                      _("msg=<File transfer: Hash check failed.>\n")));
1306                break;
1307              }
1308          }
1309        else
1310          {
1311            TPT(( 0, FIL__, __LINE__, 
1312                  _("msg=<File transfer: No more data.>\n")));
1313            break;
1314          }
1315      } while (transfercount < 32000); /* 64 Mbyte */
1316     
1317      if (0 == check_request_nerr(head_u, _("EEOT")) &&
1318          0 <  flag_err                              &&
1319          0 == hash_check (foo_M1, answer, (int)sl_strlen(answer)))
1320        {
1321          flag_err = xfer_send_crypt (sockfd, theProto, 
1322                                      _("EOTE"),
1323                                      nclt, 
1324                                      (unsigned int) sl_strlen(nclt));
1325         
1326          (void) rewind_tmp (sfd);
1327          (void) sl_sync(sfd);
1328          if (flag_err_info == S_TRUE)
1329            sh_error_handle((-1), FIL__, __LINE__, flag_err, MSG_TCP_FOK);
1330        }
1331      else
1332        {
1333          (void) sl_close (sfd);
1334          sfd = (-1);
1335        }
1336    }
1337
1338  return sfd;
1339}
1340
1341static  long xfer_try_report_int (char * errmsg, const int what)
1342{
1343  static int           initialized = S_FALSE;
1344  static int           conn_state  = S_TRUE;
1345  int                  sockfd;
1346  int                  flag_err = 0;
1347  char               * answer;
1348  int                  theProto = 0;
1349
1350  UINT32 ticks;
1351  char   head_u[5];
1352  char * buffer;
1353  char   nsrv[KEY_LEN+1];
1354  char   nclt[KEY_LEN+1];
1355  char   foo_M1[KEY_LEN+1];
1356
1357  char hashbuf[KEYBUF_SIZE];
1358  char sigbuf[KEYBUF_SIZE];
1359
1360  SL_ENTER(_("xfer_try_report_int"));
1361
1362  /* --- No message to transmit. ---
1363   */
1364  if (errmsg == NULL && initialized == S_TRUE)
1365    SL_RETURN( 0, _("xfer_try_report_int"));
1366 
1367  /* --- Connection in bad state. ---
1368   */
1369  if (xfer_conn_state(initialized, conn_state) < 0)
1370    SL_RETURN( (-1), _("xfer_try_report_int"));
1371
1372  /* --- Try to connect to log server. ---
1373   */
1374  sockfd = xfer_connect(&conn_state);
1375  if (sockfd < 0)
1376    SL_RETURN( (-1), _("xfer_try_report_int"));
1377 
1378
1379  /*************************
1380   *
1381   *  initialization
1382   *
1383   */
1384  flag_err = 0;
1385  answer   = SH_ALLOC(512);
1386  MLOCK(answer, 512);
1387
1388  if (initialized == S_FALSE)
1389    {
1390      if (xfer_auth(S_FALSE, &initialized, sockfd, answer) < 0)
1391        SL_RETURN( (-1), _("xfer_try_report_int"));
1392    }
1393
1394 retry_send:
1395
1396  /* no message, just session key negotiated
1397   */
1398  if (errmsg == NULL)
1399    {
1400      xfer_timeout_val = 1;
1401      memset(answer, 0, 512);
1402      MUNLOCK(answer, 512);
1403      SH_FREE(answer);
1404      TPT(( 0, FIL__, __LINE__, _("msg=<No message.>\n")));
1405      SL_RETURN( (0), _("xfer_try_report_int"));
1406    }
1407  else if (what == SH_PROTO_BIG)
1408    {
1409      MUNLOCK(answer, 512);
1410      SH_FREE (answer);
1411      answer   = SH_ALLOC(TRANS_BYTES + 256);
1412      MLOCK(answer, TRANS_BYTES + 256);
1413      TPT(( 0, FIL__, __LINE__, _("msg=<File transfer.>\n")));
1414    }
1415
1416  sl_strlcpy (answer, 
1417              sh_util_siggen(skey->session,
1418                             sh.host.name,
1419                             sl_strlen(sh.host.name),
1420                             sigbuf, sizeof(sigbuf)), 
1421              KEY_LEN+1);
1422
1423  TPT((0, FIL__, __LINE__, _("msg=<host %s>\n"), sh.host.name));
1424  TPT((0, FIL__, __LINE__, _("msg=<ckey %s>\n"), skey->session));
1425  TPT((0, FIL__, __LINE__, _("msg=<sign %s>\n"), answer));
1426   
1427  sl_strlcat (answer, sh.host.name, 512);
1428
1429  TPT((0, FIL__, __LINE__, _("msg=<mesg %s>\n"), answer));
1430
1431  /***********************************************
1432   *
1433   * send the message
1434   *
1435   */
1436
1437  if (what == SH_PROTO_MSG)
1438    theProto = SH_PROTO_MSG;
1439  else if (what == SH_PROTO_BIG)
1440    theProto = SH_PROTO_BIG;
1441
1442  /* --- Say HELO  ---       
1443   */
1444  flag_err = xfer_send    (sockfd, theProto, _("HELO"),
1445                           answer, sl_strlen(answer));
1446  TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"), 
1447        answer, flag_err));
1448
1449  if (flag_err == 0)
1450    { 
1451      /* --- Get NSRV. --- 
1452       */
1453      flag_err = (int) xfer_receive (sockfd, theProto, head_u, answer, 255);
1454      TPT(( 0, FIL__, __LINE__, _("msg=<Rcvt %s, u %s, status %d.>\n"), 
1455            answer, hu_trans(head_u), flag_err));
1456      flag_err = (flag_err < 0) ? flag_err : 0;
1457    }   
1458
1459  if (what == SH_PROTO_MSG)
1460    {
1461      if (flag_err == 0)
1462        {
1463          /* --- Re-negotiate key. ---
1464           */
1465          if (0 == check_request_nerr(head_u, _("INIT")))
1466            {
1467              flag_err    = 0;
1468              initialized = S_FALSE;
1469              if (xfer_auth(S_TRUE, &initialized, sockfd, answer) == 0)
1470                goto retry_send;
1471            }
1472         
1473          else if (0 == check_request(head_u, _("TALK")))
1474            {
1475              flag_err = xfer_send_message(errmsg, sockfd, answer);
1476            }
1477
1478          else
1479            {
1480              /* --- Unexpected reply from server. ---
1481               */
1482              sh_error_handle((-1), FIL__, __LINE__, 0,
1483                              MSG_TCP_UNEXP);
1484              flag_err = (-1);
1485               
1486            }
1487        }
1488    }
1489
1490
1491  else if (what == SH_PROTO_BIG)
1492    {
1493      if (flag_err == 0)
1494        {
1495         
1496          /* --- Re-negotiate key. ---
1497           */
1498          if (0 == check_request_nerr(head_u, _("INIT")))
1499            {
1500              flag_err    = 0;
1501              initialized = BAD;
1502              if (xfer_auth(S_TRUE, &initialized, sockfd, answer) == 0)
1503                goto retry_send;
1504            }
1505         
1506 
1507          else if (0 == check_request(head_u, _("NSRV")))
1508            {
1509              size_t buffersize;
1510#ifdef SH_ENCRYPT
1511              /* --- Set encryption flag. ---
1512               */
1513              theProto = (SH_PROTO_BIG|SH_PROTO_ENC);
1514#endif
1515
1516              (void) sl_strlcpy(nsrv, answer, KEY_LEN+1);
1517             
1518              /* --- Generate a nonce. ---
1519               */
1520              ticks = (UINT32) taus_get ();
1521             
1522              (void) sl_strlcpy(nclt, 
1523                                sh_tiger_hash((char *) &ticks, 
1524                                              TIGER_DATA, 
1525                                              (unsigned long)sizeof(UINT32), 
1526                                              hashbuf, sizeof(hashbuf)),
1527                                KEY_LEN+1);
1528
1529              /* --- Compute H(nsrv, nclt, skey). ---
1530               */
1531              buffer = sh_util_strconcat (nsrv, nclt, 
1532                                          skey->session, NULL);
1533              (void)sl_strlcpy(foo_M1, 
1534                               sh_tiger_hash(buffer, TIGER_DATA,
1535                                             (unsigned long)sl_strlen(buffer), 
1536                                             hashbuf, sizeof(hashbuf)),
1537                               KEY_LEN+1);
1538              memset (buffer, 0, sl_strlen(buffer));
1539              SH_FREE(buffer);
1540
1541              /* --- Send (nclt, msg) ---
1542               */
1543              buffersize = strlen(nclt)+strlen(errmsg)+2;
1544              buffer = SH_ALLOC(buffersize);
1545
1546              sl_strlcpy(buffer, nclt,   buffersize);
1547              sl_strlcat(buffer, errmsg, buffersize);
1548
1549#if !defined(SH_ENCRYPT)
1550              if (4 == sl_strlen(errmsg)) {      /* backward compatibility */
1551                buffersize = sl_strlen(buffer);
1552                buffer[buffersize]   = theProto; /* nctl//DATA//theProto   */
1553                buffer[buffersize+1] = '\0';
1554              }
1555              sh_tools_hash_add(foo_M1, buffer, buffersize+1);
1556#endif
1557
1558              flag_err = 
1559                xfer_send_crypt (sockfd, (char) theProto, _("NCLT"),
1560                                 buffer, 
1561                                 (unsigned long) sl_strlen(buffer));
1562 
1563              TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"), 
1564                    buffer, flag_err));
1565              SH_FREE (buffer);
1566            }   
1567        }
1568
1569      if (flag_err == 0)
1570        {
1571          /* --- Receive the file. ---
1572           */
1573          SL_TICKET sfd = xfer_get_file(sockfd, answer, nclt, foo_M1, theProto);
1574          if (!SL_ISERROR(sfd))
1575            {
1576              (void) sl_close_fd (FIL__, __LINE__, sockfd);
1577              memset(answer, 0, TRANS_BYTES + 256);
1578              MUNLOCK(answer, TRANS_BYTES + 256);
1579              SH_FREE(answer);
1580              xfer_timeout_val = 1;
1581
1582              SL_RETURN( (sfd), _("xfer_try_report_int"));
1583            }
1584        }
1585
1586      (void) sl_close_fd (FIL__, __LINE__, sockfd);
1587      memset(answer, 0, TRANS_BYTES + 256);
1588      MUNLOCK(answer, TRANS_BYTES + 256);
1589      SH_FREE(answer);
1590      xfer_timeout_val *= 2;
1591
1592      SL_RETURN( (-1), _("xfer_try_report_int"));
1593    }
1594 
1595  (void) sl_close_fd (FIL__, __LINE__, sockfd);
1596  memset(answer, 0, 512);
1597  MUNLOCK(answer, 512);
1598  SH_FREE(answer);
1599
1600#ifndef EIO
1601#define EIO 5
1602#endif
1603 
1604
1605#ifdef SH_ERROR_H 
1606  if (flag_err != 0)
1607    {
1608      char errbuf[SH_ERRBUF_SIZE];
1609      conn_state = S_FALSE;
1610      xfer_timeout_val *= 2;
1611      if (flag_err < 0 || NULL == sh_error_message(flag_err, errbuf, sizeof(errbuf)))
1612        flag_err = EIO;
1613      sh_error_handle((-1), FIL__, __LINE__, flag_err, MSG_TCP_ECONN,
1614                      sh_error_message(flag_err, errbuf, sizeof(errbuf)));
1615      SL_RETURN( (-1), _("xfer_try_report_int"));
1616    }
1617#endif
1618  xfer_timeout_val = 1;
1619
1620  SL_RETURN( (0), _("xfer_try_report_int"));
1621}
1622
1623/* #ifdef SH_WITH_CLIENT */
1624#endif
1625
1626
1627
1628
Note: See TracBrowser for help on using the repository browser.