source: trunk/src/sh_xfer_client.c@ 583

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

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

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