source: trunk/third/ssh/packet.c @ 12648

Revision 12648, 24.8 KB checked in by danw, 26 years ago (diff)
merge changes
Line 
1/*
2
3packet.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8                   All rights reserved
9
10Created: Sat Mar 18 02:40:40 1995 ylo
11
12This file contains code implementing the packet protocol and communication
13with the other side.  This same code is used both on client and server side.
14
15*/
16
17/*
18 * $Id: packet.c,v 1.3 1999-03-08 18:20:07 danw Exp $
19 * $Log: not supported by cvs2svn $
20 * Revision 1.2  1998/06/17 17:29:40  ghudson
21 * Add code from a CORE SDI advisory to prevent connection hijacking.
22 *
23 * Revision 1.1.1.3  1999/03/08 17:43:13  danw
24 * Import of ssh 1.2.26
25 *
26 * Revision 1.1.1.2  1998/05/13 19:11:18  danw
27 * Import of ssh 1.2.23
28 *
29 * Revision 1.11  1998/06/11 00:08:44  kivinen
30 *      Crc fixing detection code.
31 *
32 * Revision 1.10  1998/05/23  20:22:50  kivinen
33 *      Changed () -> (void).
34 *
35 * Revision 1.9  1998/04/30  01:54:30  kivinen
36 *      Fixed SSH_MSG_IGNORE handling. Now it will skip the string
37 *      argument also.
38 *
39 * Revision 1.8  1998/03/27 16:59:02  kivinen
40 *      Added ENABLE_TCP_NODELAY support.
41 *
42 * Revision 1.7  1997/04/05 17:29:21  ylo
43 *      Added packet_get_len (returns the remaining length of incoming
44 *      packet).
45 *
46 * Revision 1.6  1997/03/19 19:26:58  kivinen
47 *      Added packet_get_all function. Added checks to
48 *      packet_read_poll that previous packet buffer must be empty
49 *      before starting to put new packet in.
50 *
51 * Revision 1.5  1996/11/24 08:23:46  kivinen
52 *      Changed all code that checked EAGAIN to check EWOULDBLOCK too.
53 *      Added support for debug messages that are printed always (if
54 *      the first character of debug message is * it is printed with
55 *      error function instead of debug).
56 *
57 * Revision 1.4  1996/10/07 11:53:24  ttsalo
58 *      From "Charles M. Hannum" <mycroft@gnu.ai.mit.edu>:
59 *      Made the use of TCP_NODELAY conditional.
60 *
61 * Revision 1.3  1996/09/22 21:58:38  ylo
62 *      Added code to clear keepalives properly when requested.
63 *
64 * Revision 1.2  1996/05/28 16:42:13  ylo
65 *      Workaround for Solaris select() bug while reading version id.
66 *
67 * Revision 1.1.1.1  1996/02/18 21:38:12  ylo
68 *      Imported ssh-1.2.13.
69 *
70 * Revision 1.6  1995/09/24  23:59:12  ylo
71 *      Added packet_get_protocol_flags.
72 *
73 * Revision 1.5  1995/09/09  21:26:43  ylo
74 * /m/shadows/u2/users/ylo/ssh/README
75 *
76 * Revision 1.4  1995/07/27  03:59:37  ylo
77 *      Fixed a bug in new arcfour keying.
78 *
79 * Revision 1.3  1995/07/27  02:17:11  ylo
80 *      Changed keying for arcfour to avoid using the same key for both
81 *      directions.
82 *
83 * Revision 1.2  1995/07/13  01:27:33  ylo
84 *      Removed "Last modified" header.
85 *      Added cvs log.
86 *
87 * $Endlog$
88 */
89
90#include "includes.h"
91#include "xmalloc.h"
92#include "randoms.h"
93#include "buffer.h"
94#include "packet.h"
95#include "bufaux.h"
96#include "ssh.h"
97#include "crc32.h"
98#include "cipher.h"
99#include "getput.h"
100#include "compress.h"
101#include "deattack.h"
102
103/* This variable contains the file descriptors used for communicating with
104   the other side.  connection_in is used for reading; connection_out
105   for writing.  These can be the same descriptor, in which case it is
106   assumed to be a socket. */
107static int connection_in = -1;
108static int connection_out = -1;
109
110/* Cipher type.  This value is only used to determine whether to pad the
111   packets with zeroes or random data. */
112static int cipher_type = SSH_CIPHER_NONE;
113
114/* Protocol flags for the remote side. */
115static unsigned int remote_protocol_flags = 0;
116
117/* Encryption context for receiving data.  This is only used for decryption. */
118static CipherContext receive_context;
119/* Encryption coontext for sending data.  This is only used for encryption. */
120static CipherContext send_context;
121
122/* Buffer for raw input data from the socket. */
123static Buffer input;
124
125/* Buffer for raw output data going to the socket. */
126static Buffer output;
127
128/* Buffer for the partial outgoing packet being constructed. */
129static Buffer outgoing_packet;
130
131/* Buffer for the incoming packet currently being processed. */
132static Buffer incoming_packet;
133
134/* Scratch buffer for packet compression/decompression. */
135static Buffer compression_buffer;
136
137/* Flag indicating whether packet compression/decompression is enabled. */
138static int packet_compression = 0;
139
140/* Pointer to the random number generator state. */
141static RandomState *random_state;
142
143/* Flag indicating whether this module has been initialized. */
144static int initialized = 0;
145
146/* Set to true if the connection is interactive. */
147static int interactive_mode = 0;
148
149/* Maximum size of a packet. */
150static unsigned int max_packet_size = (sizeof(int) < 4) ? 32000 : 256000;
151
152/* Sets the descriptors used for communication.  Disables encryption until
153   packet_set_encryption_key is called. */
154
155void packet_set_connection(int fd_in, int fd_out, RandomState *state)
156{
157  connection_in = fd_in;
158  connection_out = fd_out;
159  random_state = state;
160  cipher_type = SSH_CIPHER_NONE;
161  cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 1);
162  cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 0);
163  if (!initialized)
164    {
165      initialized = 1;
166      buffer_init(&input);
167      buffer_init(&output);
168      buffer_init(&outgoing_packet);
169      buffer_init(&incoming_packet);
170    }
171
172  /* Kludge: arrange the close function to be called from fatal(). */
173  fatal_add_cleanup((void (*)(void *))packet_close, NULL);
174
175  /* Initially set the connection interactive and enable keepalives.  The
176     values will be reset to their final values later (after
177     authentication). */
178  packet_set_interactive(1, 1);
179}
180
181/* Sets the connection into non-blocking mode. */
182
183void packet_set_nonblocking(void)
184{
185  /* Set the socket into non-blocking mode. */
186#if defined(O_NONBLOCK) && !defined(O_NONBLOCK_BROKEN)
187  if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
188    error("fcntl O_NONBLOCK: %.100s", strerror(errno));
189#else /* O_NONBLOCK && !O_NONBLOCK_BROKEN */
190  if (fcntl(connection_in, F_SETFL, O_NDELAY) < 0)
191    error("fcntl O_NDELAY: %.100s", strerror(errno));
192#endif /* O_NONBLOCK && !O_NONBLOCK_BROKEN */
193
194  if (connection_out != connection_in)
195    {
196#if defined(O_NONBLOCK) && !defined(O_NONBLOCK_BROKEN)
197      if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0)
198        error("fcntl O_NONBLOCK: %.100s", strerror(errno));
199#else /* O_NONBLOCK && !O_NONBLOCK_BROKEN */ 
200      if (fcntl(connection_out, F_SETFL, O_NDELAY) < 0)
201        error("fcntl O_NDELAY: %.100s", strerror(errno));
202#endif /* O_NONBLOCK && !O_NONBLOCK_BROKEN */
203    }
204}
205
206/* Returns the socket used for reading. */
207
208int packet_get_connection_in(void)
209{
210  return connection_in;
211}
212
213/* Returns the descriptor used for writing. */
214
215int packet_get_connection_out(void)
216{
217  return connection_out;
218}
219
220/* Closes the connection and clears and frees internal data structures. */
221
222void packet_close(void)
223{
224  if (!initialized)
225    return;
226  initialized = 0;
227  if (connection_in == connection_out)
228    {
229      shutdown(connection_out, 2);
230      close(connection_out);
231    }
232  else
233    {
234      close(connection_in);
235      close(connection_out);
236    }
237  buffer_free(&input);
238  buffer_free(&output);
239  buffer_free(&outgoing_packet);
240  buffer_free(&incoming_packet);
241  if (packet_compression)
242    {
243      buffer_free(&compression_buffer);
244      buffer_compress_uninit();
245    }
246}
247
248/* Sets remote side protocol flags. */
249
250void packet_set_protocol_flags(unsigned int protocol_flags)
251{
252  remote_protocol_flags = protocol_flags;
253  channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0);
254}
255
256/* Returns the remote protocol flags set earlier by the above function. */
257
258unsigned int packet_get_protocol_flags(void)
259{
260  return remote_protocol_flags;
261}
262
263/* Starts packet compression from the next packet on in both directions.
264   Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */
265
266void packet_start_compression(int level)
267{
268  if (packet_compression)
269    fatal("Compression already enabled.");
270  packet_compression = 1;
271  buffer_init(&compression_buffer);
272  buffer_compress_init(level);
273}
274
275/* Encrypts the given number of bytes, copying from src to dest.
276   bytes is known to be a multiple of 8. */
277
278void packet_encrypt(CipherContext *cc, void *dest, void *src,
279                    unsigned int bytes)
280{
281  assert((bytes % 8) == 0);
282  cipher_encrypt(cc, dest, src, bytes);
283}
284
285/* Decrypts the given number of bytes, copying from src to dest.
286   bytes is known to be a multiple of 8. */
287
288void packet_decrypt(CipherContext *cc, void *dest, void *src,
289                    unsigned int bytes)
290{
291  int i;
292 
293  assert((bytes % 8) == 0);
294 
295  /* $Id: packet.c,v 1.3 1999-03-08 18:20:07 danw Exp $
296   * Cryptographic attack detector for ssh - Modifications for packet.c
297   * (C)1998 CORE-SDI, Buenos Aires Argentina
298   * Ariel Futoransky(futo@core-sdi.com)
299   */
300 
301  switch (cc->type)
302    {
303#ifndef WITHOUT_IDEA
304    case SSH_CIPHER_IDEA :
305      i = detect_attack(src, bytes, cc->u.idea.iv);
306      break;
307#endif
308    case SSH_CIPHER_NONE :
309      i = DEATTACK_OK;
310      break;
311    default:
312      i = detect_attack(src, bytes, NULL);
313      break;
314    }
315 
316  if (i == DEATTACK_DETECTED)
317    packet_disconnect("crc32 compensation attack: network attack detected");
318 
319  cipher_decrypt(cc, dest, src, bytes);
320}
321
322/* Causes any further packets to be encrypted using the given key.  The same
323   key is used for both sending and reception.  However, both directions
324   are encrypted independently of each other. */
325
326void packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
327                               int cipher, int is_client)
328{
329  cipher_type = cipher;
330  if (cipher == SSH_CIPHER_ARCFOUR)
331    {
332      if (is_client)
333        { /* In client: use first half for receiving, second for sending. */
334          cipher_set_key(&receive_context, cipher, key, keylen / 2, 0);
335          cipher_set_key(&send_context, cipher, key + keylen / 2,
336                         keylen / 2, 1);
337        }
338      else
339        { /* In server: use first half for sending, second for receiving. */
340          cipher_set_key(&receive_context, cipher, key + keylen / 2,
341                         keylen / 2, 0);
342          cipher_set_key(&send_context, cipher, key, keylen / 2, 1);
343        }
344    }
345  else
346    {
347      /* All other ciphers use the same key in both directions for now. */
348      cipher_set_key(&receive_context, cipher, key, keylen, 0);
349      cipher_set_key(&send_context, cipher, key, keylen, 1);
350    }
351}
352
353/* Starts constructing a packet to send. */
354
355void packet_start(int type)
356{
357  char buf[9];
358
359  buffer_clear(&outgoing_packet);
360  memset(buf, 0, 8);
361  buf[8] = type;
362  buffer_append(&outgoing_packet, buf, 9);
363}
364
365/* Appends a character to the packet data. */
366
367void packet_put_char(int value)
368{
369  char ch = value;
370  buffer_append(&outgoing_packet, &ch, 1);
371}
372
373/* Appends an integer to the packet data. */
374
375void packet_put_int(unsigned int value)
376{
377  buffer_put_int(&outgoing_packet, value);
378}
379
380/* Appends a string to packet data. */
381
382void packet_put_string(const char *buf, unsigned int len)
383{
384  buffer_put_string(&outgoing_packet, buf, len);
385}
386
387/* Appends an arbitrary precision integer to packet data. */
388
389void packet_put_mp_int(MP_INT *value)
390{
391  buffer_put_mp_int(&outgoing_packet, value);
392}
393
394/* Finalizes and sends the packet.  If the encryption key has been set,
395   encrypts the packet before sending. */
396 
397void packet_send(void)
398{
399  char buf[8], *cp;
400  int i, padding, len;
401  unsigned long checksum;
402
403  if (buffer_len(&outgoing_packet) >= max_packet_size - 30)
404    fatal("packet_send: sending too big a packet: size %u, limit %u.",
405          buffer_len(&outgoing_packet), max_packet_size);
406
407  /* If using packet compression, compress the payload of the outgoing
408     packet. */
409  if (packet_compression)
410    {
411      buffer_clear(&compression_buffer);
412      buffer_consume(&outgoing_packet, 8); /* Skip padding. */
413      buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); /* padding */
414      buffer_compress(&outgoing_packet, &compression_buffer);
415      buffer_clear(&outgoing_packet);
416      buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
417                    buffer_len(&compression_buffer));
418    }
419
420  /* Compute packet length without padding (add checksum, remove padding). */
421  len = buffer_len(&outgoing_packet) + 4 - 8;
422 
423  /* Insert padding. */
424  padding = 8 - len % 8;
425  if (cipher_type != SSH_CIPHER_NONE)
426    {
427      cp = buffer_ptr(&outgoing_packet);
428      for (i = 0; i < padding; i++)
429        cp[7 - i] = random_get_byte(random_state);
430    }
431  buffer_consume(&outgoing_packet, 8 - padding);
432 
433  /* Add check bytes. */
434  checksum = crc32((unsigned char *)buffer_ptr(&outgoing_packet),
435                   buffer_len(&outgoing_packet));
436  PUT_32BIT(buf, checksum);
437  buffer_append(&outgoing_packet, buf, 4);
438
439#ifdef PACKET_DEBUG
440  fprintf(stderr, "packet_send plain: ");
441  buffer_dump(&outgoing_packet);
442#endif
443
444  /* Append to output. */
445  PUT_32BIT(buf, len);
446  buffer_append(&output, buf, 4);
447  buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
448  packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
449                 buffer_len(&outgoing_packet));
450 
451#ifdef PACKET_DEBUG
452  fprintf(stderr, "encrypted: "); buffer_dump(&output);
453#endif
454
455  buffer_clear(&outgoing_packet);
456
457  /* Note that the packet is now only buffered in output.  It won\'t be
458     actually sent until packet_write_wait or packet_write_poll is called. */
459}
460
461/* Waits until a packet has been received, and returns its type.  Note that
462   no other data is processed until this returns, so this function should
463   not be used during the interactive session. */
464
465int packet_read(void)
466{
467  int type, len;
468  fd_set set;
469  char buf[8192];
470
471  /* Since we are blocking, ensure that all written packets have been sent. */
472  packet_write_wait();
473
474  /* Stay in the loop until we have received a complete packet. */
475  for (;;)
476    {
477      /* Try to read a packet from the buffer. */
478      type = packet_read_poll();
479      /* If we got a packet, return it. */
480      if (type != SSH_MSG_NONE)
481        return type;
482      /* Otherwise, wait for some data to arrive, add it to the buffer,
483         and try again. */
484      FD_ZERO(&set);
485      FD_SET(connection_in, &set);
486      /* Wait for some data to arrive. */
487      select(connection_in + 1, &set, NULL, NULL, NULL);
488      /* Read data from the socket. */
489      len = read(connection_in, buf, sizeof(buf));
490      if (len == 0)
491        fatal_severity(SYSLOG_SEVERITY_INFO,
492                       "Connection closed by remote host.");
493      if (len < 0)
494        {
495          if (errno == EAGAIN || errno == EWOULDBLOCK)
496            continue;
497          fatal_severity(SYSLOG_SEVERITY_INFO,
498                         "Read from socket failed: %.100s", strerror(errno));
499        }
500      /* Append it to the buffer. */
501      packet_process_incoming(buf, len);
502    }
503  /*NOTREACHED*/
504}
505
506/* Waits until a packet has been received, verifies that its type matches
507   that given, and gives a fatal error and exits if there is a mismatch. */
508
509void packet_read_expect(int expected_type)
510{
511  int type;
512
513  type = packet_read();
514  if (type != expected_type)
515    packet_disconnect("Protocol error: expected packet type %d, got %d",
516                      expected_type, type);
517}
518
519/* Checks if a full packet is available in the data received so far via
520   packet_process_incoming.  If so, reads the packet; otherwise returns
521   SSH_MSG_NONE.  This does not wait for data from the connection.
522   
523   SSH_MSG_DISCONNECT is handled specially here.  Also,
524   SSH_MSG_IGNORE messages are skipped by this function and are never returned
525   to higher levels. */
526
527int packet_read_poll(void)
528{
529  unsigned int len, padded_len;
530  unsigned char *ucp;
531  char buf[8], *cp;
532  unsigned long checksum, stored_checksum;
533 
534 restart:
535
536  /* Check if input size is less than minimum packet size. */
537  if (buffer_len(&input) < 4 + 8)
538    return SSH_MSG_NONE;
539  /* Get length of incoming packet. */
540  ucp = (unsigned char *)buffer_ptr(&input);
541  len = GET_32BIT(ucp);
542  if (len < 1 + 2 + 2 || len > 256*1024)
543    packet_disconnect("Bad packet length %u.", len);
544  padded_len = (len + 8) & ~7;
545
546  /* Check if the packet has been entirely received. */
547  if (buffer_len(&input) < 4 + padded_len)
548    return SSH_MSG_NONE;
549
550  /* The entire packet is in buffer. */
551
552  /* Consume packet length. */
553  buffer_consume(&input, 4);
554
555/* Confirm that packet is empty after all data is processed from it. Calls
556   fatal buffer is not empty. */
557  if (buffer_len(&incoming_packet) != 0)
558    packet_disconnect("Junk data left to incoming packet buffer after all data processed");
559 
560  /* Copy data to incoming_packet. */
561  buffer_clear(&incoming_packet);
562  buffer_append_space(&incoming_packet, &cp, padded_len);
563  packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
564  buffer_consume(&input, padded_len);
565
566#ifdef PACKET_DEBUG
567  fprintf(stderr, "read_poll plain: "); buffer_dump(&incoming_packet);
568#endif
569 
570  /* Compute packet checksum. */
571  checksum = crc32((unsigned char *)buffer_ptr(&incoming_packet),
572                   buffer_len(&incoming_packet) - 4);
573
574  /* Skip padding. */
575  buffer_consume(&incoming_packet, 8 - len % 8);
576
577  /* Test check bytes. */
578  assert(len == buffer_len(&incoming_packet));
579  ucp = (unsigned char *)buffer_ptr(&incoming_packet) + len - 4;
580  stored_checksum = GET_32BIT(ucp);
581  if (checksum != stored_checksum)
582    packet_disconnect("Corrupted check bytes on input.");
583  buffer_consume_end(&incoming_packet, 4);
584
585  /* If using packet compression, decompress the packet. */
586  if (packet_compression)
587    {
588      buffer_clear(&compression_buffer);
589      buffer_uncompress(&incoming_packet, &compression_buffer);
590      buffer_clear(&incoming_packet);
591      buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
592                    buffer_len(&compression_buffer));
593    }
594
595  /* Get packet type. */
596  buffer_get(&incoming_packet, &buf[0], 1);
597
598  /* Handle disconnect message. */
599  if ((unsigned char)buf[0] == SSH_MSG_DISCONNECT)
600    fatal_severity(SYSLOG_SEVERITY_INFO, "%.900s", packet_get_string(NULL));
601
602  /* Ignore ignore messages. */
603  if ((unsigned char)buf[0] == SSH_MSG_IGNORE)
604    {
605      char *str;
606      str = packet_get_string(NULL);
607      xfree(str);
608      goto restart;
609    }
610
611  /* Send debug messages as debugging output. */
612  if ((unsigned char)buf[0] == SSH_MSG_DEBUG)
613    {
614      char *str;
615
616      str = packet_get_string(NULL);
617      if (*str == '*')          /* Magical kludge to force displaying
618                                   debug messages with '*' anyway, even
619                                   if not in verbose mode. */
620        {
621          error("Remote: %.900s", str);
622        }
623      else
624        {
625          debug("Remote: %.900s", str);
626        }
627      xfree(str);
628      goto restart;
629    }
630
631  /* Return type. */
632  return (unsigned char)buf[0];
633}
634 
635/* Buffers the given amount of input characters.  This is intended to be
636   used together with packet_read_poll. */
637
638void packet_process_incoming(const char *buf, unsigned int len)
639{
640  buffer_append(&input, buf, len);
641}
642
643/* Returns the number of bytes left in the incoming packet. */
644
645unsigned int packet_get_len(void)
646{
647  return buffer_len(&incoming_packet);
648}
649
650/* Returns a character from the packet. */
651
652unsigned int packet_get_char(void)
653{
654  char ch;
655  buffer_get(&incoming_packet, &ch, 1);
656  return (unsigned char)ch;
657}
658
659/* Returns an integer from the packet data. */
660
661unsigned int packet_get_int(void)
662{
663  return buffer_get_int(&incoming_packet);
664}
665
666/* Returns an arbitrary precision integer from the packet data.  The integer
667   must have been initialized before this call. */
668
669void packet_get_mp_int(MP_INT *value)
670{
671  buffer_get_mp_int(&incoming_packet, value);
672}
673
674/* Returns a string from the packet data.  The string is allocated using
675   xmalloc; it is the responsibility of the calling program to free it when
676   no longer needed.  The length_ptr argument may be NULL, or point to an
677   integer into which the length of the string is stored. */
678
679char *packet_get_string(unsigned int *length_ptr)
680{
681  return buffer_get_string(&incoming_packet, length_ptr);
682}
683
684/* Clears incoming data buffer */
685
686void packet_get_all(void)
687{
688  buffer_clear(&incoming_packet);
689}
690
691/* Sends a diagnostic message from the server to the client.  This message
692   can be sent at any time (but not while constructing another message).
693   The message is printed immediately, but only if the client is being
694   executed in verbose mode.  These messages are primarily intended to
695   ease debugging authentication problems.   The length of the formatted
696   message must not exceed 1024 bytes.  This will automatically call
697   packet_write_wait. */
698
699void packet_send_debug(const char *fmt, ...)
700{
701  char buf[1024];
702  va_list args;
703 
704  va_start(args, fmt);
705  vsprintf(buf, fmt, args);
706  va_end(args);
707 
708  packet_start(SSH_MSG_DEBUG);
709  packet_put_string(buf, strlen(buf));
710  packet_send();
711  packet_write_wait();
712}
713
714/* Logs the error plus constructs and sends a disconnect
715   packet, closes the connection, and exits.  This function never returns.
716   The error message should not contain a newline.  The length of the
717   formatted message must not exceed 1024 bytes. */
718
719void packet_disconnect(const char *fmt, ...)
720{
721  char buf[1024];
722  va_list args;
723  static int disconnecting = 0;
724  if (disconnecting) /* Guard against recursive invocations. */
725    fatal("packet_disconnect called recursively.");
726  disconnecting = 1;
727
728  /* Format the message.  Note that the caller must make sure the message
729     is of limited size. */
730  va_start(args, fmt);
731  vsprintf(buf, fmt, args);
732  va_end(args);
733
734  /* Send the disconnect message to the other side, and wait for it to get
735     sent. */
736  packet_start(SSH_MSG_DISCONNECT);
737  packet_put_string(buf, strlen(buf));
738  packet_send();
739  packet_write_wait();
740
741  /* Stop listening for connections. */
742  channel_stop_listening();
743 
744  /* Close the connection. */
745  packet_close();
746
747  /* Display the error locally and exit. */
748  fatal("Local: %.100s", buf);
749}
750
751/* Checks if there is any buffered output, and tries to write some of the
752   output. */
753
754void packet_write_poll(void)
755{
756  int len = buffer_len(&output);
757  if (len > 0)
758    {
759      len = write(connection_out, buffer_ptr(&output), len);
760      if (len <= 0)
761        if (errno == EAGAIN || errno == EWOULDBLOCK)
762          return;
763        else
764          fatal_severity(SYSLOG_SEVERITY_INFO,
765                         "Write failed: %.100s", strerror(errno));
766      buffer_consume(&output, len);
767    }
768}
769
770/* Calls packet_write_poll repeatedly until all pending output data has
771   been written. */
772
773void packet_write_wait(void)
774{
775  packet_write_poll();
776  while (packet_have_data_to_write())
777    {
778      fd_set set;
779      FD_ZERO(&set);
780      FD_SET(connection_out, &set);
781      select(connection_out + 1, NULL, &set, NULL, NULL);
782      packet_write_poll();
783    }
784}
785
786/* Returns true if there is buffered data to write to the connection. */
787
788int packet_have_data_to_write(void)
789{
790  return buffer_len(&output) != 0;
791}
792
793/* Returns true if there is not too much data to write to the connection. */
794
795int packet_not_very_much_data_to_write(void)
796{
797  if (interactive_mode || sizeof(int) < 4)
798    return buffer_len(&output) < 16384;
799  else
800    return buffer_len(&output) < 128*1024;
801}
802
803/* Informs that the current session is interactive.  Sets IP flags for that. */
804
805void packet_set_interactive(int interactive, int keepalives)
806{
807  int on = 1, off = 0;
808
809  /* Record that we are in interactive mode. */
810  interactive_mode = interactive;
811
812  /* Only set socket options if using a socket (as indicated by the descriptors
813     being the same). */
814  if (connection_in != connection_out)
815    return;
816
817  if (keepalives)
818    {
819      /* Set keepalives if requested. */
820      if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
821                     sizeof(on)) < 0)
822        error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
823    }
824  else
825    {
826      /* Clear keepalives if we don't want them. */
827      if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&off,
828                     sizeof(off)) < 0)
829        error("setsockopt SO_KEEPALIVE off: %.100s", strerror(errno));
830    }
831 
832  if (interactive)
833    {
834      /* Set IP options for an interactive connection.  Use IPTOS_LOWDELAY
835         and TCP_NODELAY. */
836#ifdef IPTOS_LOWDELAY
837      int lowdelay = IPTOS_LOWDELAY;
838      if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&lowdelay,
839                     sizeof(lowdelay)) < 0)
840        error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno));
841#endif /* IPTOS_LOWDELAY */
842#if defined(TCP_NODELAY) && defined(ENABLE_TCP_NODELAY)
843      if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *)&on,
844                     sizeof(on)) < 0)
845        error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
846#endif /* TCP_NODELAY */
847    }
848  else
849    {
850      /* Set IP options for a non-interactive connection.  Use
851         IPTOS_THROUGHPUT. */
852#ifdef IPTOS_THROUGHPUT
853      int throughput = IPTOS_THROUGHPUT;
854      if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&throughput,
855                     sizeof(throughput)) < 0)
856        error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
857#endif /* IPTOS_THROUGHPUT */
858#if defined(TCP_NODELAY) && defined(ENABLE_TCP_NODELAY)
859      if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *)&off,
860                     sizeof(off)) < 0)
861        error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
862#endif /* TCP_NODELAY */
863    }
864}
865
866/* Returns true if the current connection is interactive. */
867
868int packet_is_interactive(void)
869{
870  return interactive_mode;
871}
872
873/* Sets the maximum packet size that can be sent to the other side. */
874
875void packet_set_max_size(unsigned int max_size)
876{
877  max_packet_size = max_size;
878}
879
880/* Returns the maximum packet size that can be sent to the other side. */
881
882unsigned int packet_max_size(void)
883{
884  return max_packet_size;
885}
Note: See TracBrowser for help on using the repository browser.