source: trunk/src/sh_xfer_client.c@ 496

Last change on this file since 496 was 489, checked in by katerina, 9 years ago

Version 4.1.0 final.

File size: 39.9 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 if (S_TRUE == sl_ok_adds(strlen(errmsg), strlen(nclt)+2+KEY_LEN))
1544 {
1545 buffersize = strlen(nclt)+strlen(errmsg)+2;
1546
1547#if !defined(SH_ENCRYPT)
1548 buffersize += KEY_LEN;
1549#endif
1550 buffer = SH_ALLOC(buffersize);
1551
1552 sl_strlcpy(buffer, nclt, buffersize);
1553 sl_strlcat(buffer, errmsg, buffersize);
1554
1555#if !defined(SH_ENCRYPT)
1556 if (4 == sl_strlen(errmsg)) { /* backward compatibility */
1557 buffersize = sl_strlen(buffer);
1558 buffer[buffersize] = theProto; /* nctl//DATA//theProto */
1559 buffer[buffersize+1] = '\0';
1560 }
1561 sh_tools_hash_add(foo_M1, buffer, buffersize+1);
1562#endif
1563
1564 flag_err =
1565 xfer_send_crypt (sockfd, (char) theProto, _("NCLT"),
1566 buffer,
1567 (unsigned long) sl_strlen(buffer));
1568
1569 TPT(( 0, FIL__, __LINE__, _("msg=<Sent %s, status %d.>\n"),
1570 buffer, flag_err));
1571 SH_FREE (buffer);
1572 }
1573 else {
1574 flag_err = -1;
1575 }
1576 }
1577 }
1578
1579 if (flag_err == 0)
1580 {
1581 /* --- Receive the file. ---
1582 */
1583 SL_TICKET sfd = xfer_get_file(sockfd, answer, nclt, foo_M1, theProto);
1584 if (!SL_ISERROR(sfd))
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 = 1;
1591
1592 SL_RETURN( (sfd), _("xfer_try_report_int"));
1593 }
1594 }
1595
1596 (void) sl_close_fd (FIL__, __LINE__, sockfd);
1597 memset(answer, 0, TRANS_BYTES + 256);
1598 MUNLOCK(answer, TRANS_BYTES + 256);
1599 SH_FREE(answer);
1600 xfer_timeout_val *= 2;
1601
1602 SL_RETURN( (-1), _("xfer_try_report_int"));
1603 }
1604
1605 (void) sl_close_fd (FIL__, __LINE__, sockfd);
1606 memset(answer, 0, 512);
1607 MUNLOCK(answer, 512);
1608 SH_FREE(answer);
1609
1610#ifndef EIO
1611#define EIO 5
1612#endif
1613
1614
1615#ifdef SH_ERROR_H
1616 if (flag_err != 0)
1617 {
1618 char errbuf[SH_ERRBUF_SIZE];
1619 conn_state = S_FALSE;
1620 xfer_timeout_val *= 2;
1621 if (flag_err < 0 || NULL == sh_error_message(flag_err, errbuf, sizeof(errbuf)))
1622 flag_err = EIO;
1623 sh_error_handle((-1), FIL__, __LINE__, flag_err, MSG_TCP_ECONN,
1624 sh_error_message(flag_err, errbuf, sizeof(errbuf)));
1625 SL_RETURN( (-1), _("xfer_try_report_int"));
1626 }
1627#endif
1628 xfer_timeout_val = 1;
1629
1630 SL_RETURN( (0), _("xfer_try_report_int"));
1631}
1632
1633/* #ifdef SH_WITH_CLIENT */
1634#endif
1635
1636
1637
1638
Note: See TracBrowser for help on using the repository browser.