/*

packet.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Sat Mar 18 02:40:40 1995 ylo

This file contains code implementing the packet protocol and communication
with the other side.  This same code is used both on client and server side.

*/

#include "includes.h"
RCSID("$Id: packet.c,v 1.1 1999/10/27 03:42:44 damien Exp $");

#include "xmalloc.h"
#include "buffer.h"
#include "packet.h"
#include "bufaux.h"
#include "ssh.h"
#include "crc32.h"
#include "cipher.h"
#include "getput.h"

#include "compress.h"
#include "deattack.h"

/* This variable contains the file descriptors used for communicating with
   the other side.  connection_in is used for reading; connection_out
   for writing.  These can be the same descriptor, in which case it is
   assumed to be a socket. */
static int connection_in = -1;
static int connection_out = -1;

/* Cipher type.  This value is only used to determine whether to pad the
   packets with zeroes or random data. */
static int cipher_type = SSH_CIPHER_NONE;

/* Protocol flags for the remote side. */
static unsigned int remote_protocol_flags = 0;

/* Encryption context for receiving data.  This is only used for decryption. */
static CipherContext receive_context;
/* Encryption coontext for sending data.  This is only used for encryption. */
static CipherContext send_context;

/* Buffer for raw input data from the socket. */
static Buffer input;

/* Buffer for raw output data going to the socket. */
static Buffer output;

/* Buffer for the partial outgoing packet being constructed. */
static Buffer outgoing_packet;

/* Buffer for the incoming packet currently being processed. */
static Buffer incoming_packet;

/* Scratch buffer for packet compression/decompression. */
static Buffer compression_buffer;

/* Flag indicating whether packet compression/decompression is enabled. */
static int packet_compression = 0;

/* Flag indicating whether this module has been initialized. */
static int initialized = 0;

/* Set to true if the connection is interactive. */
static int interactive_mode = 0;

/* Sets the descriptors used for communication.  Disables encryption until
   packet_set_encryption_key is called. */

void
packet_set_connection(int fd_in, int fd_out)
{
  connection_in = fd_in;
  connection_out = fd_out;
  cipher_type = SSH_CIPHER_NONE;
  cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 1);
  cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 0);
  if (!initialized)
    {
      initialized = 1;
      buffer_init(&input);
      buffer_init(&output);
      buffer_init(&outgoing_packet);
      buffer_init(&incoming_packet);
    }

  /* Kludge: arrange the close function to be called from fatal(). */
  fatal_add_cleanup((void (*)(void *))packet_close, NULL);
}

/* Sets the connection into non-blocking mode. */

void
packet_set_nonblocking()
{
  /* Set the socket into non-blocking mode. */
  if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
    error("fcntl O_NONBLOCK: %.100s", strerror(errno));

  if (connection_out != connection_in)
    {
      if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0)
	error("fcntl O_NONBLOCK: %.100s", strerror(errno));
    }
}

/* Returns the socket used for reading. */

int
packet_get_connection_in()
{
  return connection_in;
}

/* Returns the descriptor used for writing. */

int
packet_get_connection_out()
{
  return connection_out;
}

/* Closes the connection and clears and frees internal data structures. */

void
packet_close()
{
  if (!initialized)
    return;
  initialized = 0;
  if (connection_in == connection_out)
    {
      shutdown(connection_out, SHUT_RDWR);
      close(connection_out);
    }
  else
    {
      close(connection_in);
      close(connection_out);
    }
  buffer_free(&input);
  buffer_free(&output);
  buffer_free(&outgoing_packet);
  buffer_free(&incoming_packet);
  if (packet_compression)
    {
      buffer_free(&compression_buffer);
      buffer_compress_uninit();
    }
}

/* Sets remote side protocol flags. */

void
packet_set_protocol_flags(unsigned int protocol_flags)
{
  remote_protocol_flags = protocol_flags;
  channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0);
}

/* Returns the remote protocol flags set earlier by the above function. */

unsigned int
packet_get_protocol_flags()
{
  return remote_protocol_flags;
}

/* Starts packet compression from the next packet on in both directions. 
   Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */

void
packet_start_compression(int level)
{
  if (packet_compression)
    fatal("Compression already enabled.");
  packet_compression = 1;
  buffer_init(&compression_buffer);
  buffer_compress_init(level);
}

/* Encrypts the given number of bytes, copying from src to dest.
   bytes is known to be a multiple of 8. */

void
packet_encrypt(CipherContext *cc, void *dest, void *src, 
	       unsigned int bytes)
{
  assert((bytes % 8) == 0);
  cipher_encrypt(cc, dest, src, bytes);
}

/* Decrypts the given number of bytes, copying from src to dest.
   bytes is known to be a multiple of 8. */

void
packet_decrypt(CipherContext *cc, void *dest, void *src, 
	       unsigned int bytes)
{
  int i;
  
  assert((bytes % 8) == 0);
  
  /*
    Cryptographic attack detector for ssh - Modifications for packet.c 
    (C)1998 CORE-SDI, Buenos Aires Argentina
    Ariel Futoransky(futo@core-sdi.com)
  */
  switch (cc->type)
    {
    case SSH_CIPHER_NONE:
      i = DEATTACK_OK;
      break;
    default:
      i = detect_attack(src, bytes, NULL);
      break;
    }
  
  if (i == DEATTACK_DETECTED)
    packet_disconnect("crc32 compensation attack: network attack detected");
  
  cipher_decrypt(cc, dest, src, bytes);
}

/* Causes any further packets to be encrypted using the given key.  The same
   key is used for both sending and reception.  However, both directions
   are encrypted independently of each other. */

void
packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
			  int cipher, int is_client)
{
  cipher_type = cipher;
  if (cipher == SSH_CIPHER_RC4)
    {
      if (is_client)
	{ /* In client: use first half for receiving, second for sending. */
	  cipher_set_key(&receive_context, cipher, key, keylen / 2, 0);
	  cipher_set_key(&send_context, cipher, key + keylen / 2, 
			 keylen / 2, 1);
	}
      else
	{ /* In server: use first half for sending, second for receiving. */
	  cipher_set_key(&receive_context, cipher, key + keylen / 2, 
			 keylen / 2, 0);
	  cipher_set_key(&send_context, cipher, key, keylen / 2, 1);
	}
    }
  else
    {
      /* All other ciphers use the same key in both directions for now. */
      cipher_set_key(&receive_context, cipher, key, keylen, 0);
      cipher_set_key(&send_context, cipher, key, keylen, 1);
    }
}

/* Starts constructing a packet to send. */

void
packet_start(int type)
{
  char buf[9];

  buffer_clear(&outgoing_packet);
  memset(buf, 0, 8);
  buf[8] = type;
  buffer_append(&outgoing_packet, buf, 9);
}

/* Appends a character to the packet data. */

void
packet_put_char(int value)
{
  char ch = value;
  buffer_append(&outgoing_packet, &ch, 1);
}

/* Appends an integer to the packet data. */

void
packet_put_int(unsigned int value)
{
  buffer_put_int(&outgoing_packet, value);
}

/* Appends a string to packet data. */

void
packet_put_string(const char *buf, unsigned int len)
{
  buffer_put_string(&outgoing_packet, buf, len);
}

/* Appends an arbitrary precision integer to packet data. */

void
packet_put_bignum(BIGNUM *value)
{
  buffer_put_bignum(&outgoing_packet, value);
}

/* Finalizes and sends the packet.  If the encryption key has been set,
   encrypts the packet before sending. */
  
void
packet_send()
{
  char buf[8], *cp;
  int i, padding, len;
  unsigned int checksum;
  u_int32_t rand = 0;

  /* If using packet compression, compress the payload of the outgoing
     packet. */
  if (packet_compression)
    {
      buffer_clear(&compression_buffer);
      buffer_consume(&outgoing_packet, 8); /* Skip padding. */
      buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); /* padding */
      buffer_compress(&outgoing_packet, &compression_buffer);
      buffer_clear(&outgoing_packet);
      buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
		    buffer_len(&compression_buffer));
    }

  /* Compute packet length without padding (add checksum, remove padding). */
  len = buffer_len(&outgoing_packet) + 4 - 8;
  
  /* Insert padding. */
  padding = 8 - len % 8;
  if (cipher_type != SSH_CIPHER_NONE)
    {
      cp = buffer_ptr(&outgoing_packet);
      for (i = 0; i < padding; i++) {
        if (i % 4 == 0)
          rand = arc4random();
        cp[7 - i] = rand & 0xff;
        rand >>= 8;
      }
    }
  buffer_consume(&outgoing_packet, 8 - padding);
  
  /* Add check bytes. */
  checksum = crc32((unsigned char *)buffer_ptr(&outgoing_packet),
		   buffer_len(&outgoing_packet));
  PUT_32BIT(buf, checksum);
  buffer_append(&outgoing_packet, buf, 4);

#ifdef PACKET_DEBUG
  fprintf(stderr, "packet_send plain: ");
  buffer_dump(&outgoing_packet);
#endif

  /* Append to output. */
  PUT_32BIT(buf, len);
  buffer_append(&output, buf, 4);
  buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
  packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
		 buffer_len(&outgoing_packet));
  
#ifdef PACKET_DEBUG
  fprintf(stderr, "encrypted: "); buffer_dump(&output);
#endif

  buffer_clear(&outgoing_packet);

  /* Note that the packet is now only buffered in output.  It won\'t be
     actually sent until packet_write_wait or packet_write_poll is called. */
}

/* Waits until a packet has been received, and returns its type.  Note that
   no other data is processed until this returns, so this function should
   not be used during the interactive session. */

int
packet_read(int *payload_len_ptr)
{
  int type, len;
  fd_set set;
  char buf[8192];

  /* Since we are blocking, ensure that all written packets have been sent. */
  packet_write_wait();

  /* Stay in the loop until we have received a complete packet. */
  for (;;)
    {
      /* Try to read a packet from the buffer. */
      type = packet_read_poll(payload_len_ptr);
      if (type == SSH_SMSG_SUCCESS
	  || type == SSH_SMSG_FAILURE
	  || type == SSH_CMSG_EOF
	  || type == SSH_CMSG_EXIT_CONFIRMATION)
	packet_integrity_check(*payload_len_ptr, 0, type);
      /* If we got a packet, return it. */
      if (type != SSH_MSG_NONE)
	return type;
      /* Otherwise, wait for some data to arrive, add it to the buffer,
	 and try again. */
      FD_ZERO(&set);
      FD_SET(connection_in, &set);
      /* Wait for some data to arrive. */
      select(connection_in + 1, &set, NULL, NULL, NULL);
      /* Read data from the socket. */
      len = read(connection_in, buf, sizeof(buf));
      if (len == 0)
	fatal("Connection closed by remote host.");
      if (len < 0)
	fatal("Read from socket failed: %.100s", strerror(errno));
      /* Append it to the buffer. */
      packet_process_incoming(buf, len);
    }
  /*NOTREACHED*/
}

/* Waits until a packet has been received, verifies that its type matches
   that given, and gives a fatal error and exits if there is a mismatch. */

void
packet_read_expect(int *payload_len_ptr, int expected_type)
{
  int type;

  type = packet_read(payload_len_ptr);
  if (type != expected_type)
    packet_disconnect("Protocol error: expected packet type %d, got %d",
		      expected_type, type);
}

/* Checks if a full packet is available in the data received so far via
   packet_process_incoming.  If so, reads the packet; otherwise returns
   SSH_MSG_NONE.  This does not wait for data from the connection. 
   
   SSH_MSG_DISCONNECT is handled specially here.  Also,
   SSH_MSG_IGNORE messages are skipped by this function and are never returned
   to higher levels.

   The returned payload_len does include space consumed by:
   Packet length
   Padding
   Packet type
   Check bytes

   
   */

int
packet_read_poll(int *payload_len_ptr)
{
  unsigned int len, padded_len;
  unsigned char *ucp;
  char buf[8], *cp;
  unsigned int checksum, stored_checksum;
  
 restart:

  /* Check if input size is less than minimum packet size. */
  if (buffer_len(&input) < 4 + 8)
    return SSH_MSG_NONE;
  /* Get length of incoming packet. */
  ucp = (unsigned char *)buffer_ptr(&input);
  len = GET_32BIT(ucp);
  if (len < 1 + 2 + 2 || len > 256*1024)
    packet_disconnect("Bad packet length %d.", len);
  padded_len = (len + 8) & ~7;

  /* Check if the packet has been entirely received. */
  if (buffer_len(&input) < 4 + padded_len)
    return SSH_MSG_NONE;

  /* The entire packet is in buffer. */

  /* Consume packet length. */
  buffer_consume(&input, 4);

  /* Copy data to incoming_packet. */
  buffer_clear(&incoming_packet);
  buffer_append_space(&incoming_packet, &cp, padded_len);
  packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
  buffer_consume(&input, padded_len);

#ifdef PACKET_DEBUG
  fprintf(stderr, "read_poll plain: "); buffer_dump(&incoming_packet);
#endif
  
  /* Compute packet checksum. */
  checksum = crc32((unsigned char *)buffer_ptr(&incoming_packet),
		   buffer_len(&incoming_packet) - 4);

  /* Skip padding. */
  buffer_consume(&incoming_packet, 8 - len % 8);

  /* Test check bytes. */
  assert(len == buffer_len(&incoming_packet));
  ucp = (unsigned char *)buffer_ptr(&incoming_packet) + len - 4;
  stored_checksum = GET_32BIT(ucp);
  if (checksum != stored_checksum)
    packet_disconnect("Corrupted check bytes on input.");
  buffer_consume_end(&incoming_packet, 4);

  /* If using packet compression, decompress the packet. */
  if (packet_compression)
    {
      buffer_clear(&compression_buffer);
      buffer_uncompress(&incoming_packet, &compression_buffer);
      buffer_clear(&incoming_packet);
      buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
		    buffer_len(&compression_buffer));
    }

  /* Get packet type. */
  buffer_get(&incoming_packet, &buf[0], 1);

  /* Return length of payload (without type field). */
  *payload_len_ptr = buffer_len(&incoming_packet);

  /* Handle disconnect message. */
  if ((unsigned char)buf[0] == SSH_MSG_DISCONNECT)
    fatal("%.900s", packet_get_string(NULL));

  /* Ignore ignore messages. */
  if ((unsigned char)buf[0] == SSH_MSG_IGNORE)
    goto restart;

  /* Send debug messages as debugging output. */
  if ((unsigned char)buf[0] == SSH_MSG_DEBUG)
    {
      debug("Remote: %.900s", packet_get_string(NULL));
      goto restart;
    }

  /* Return type. */
  return (unsigned char)buf[0];
}
  
/* Buffers the given amount of input characters.  This is intended to be
   used together with packet_read_poll. */

void
packet_process_incoming(const char *buf, unsigned int len)
{
  buffer_append(&input, buf, len);
}

/* Returns a character from the packet. */

unsigned int
packet_get_char()
{
  char ch;
  buffer_get(&incoming_packet, &ch, 1);
  return (unsigned char)ch;
}

/* Returns an integer from the packet data. */

unsigned int
packet_get_int()
{
  return buffer_get_int(&incoming_packet);
}

/* Returns an arbitrary precision integer from the packet data.  The integer
   must have been initialized before this call. */

void
packet_get_bignum(BIGNUM *value, int *length_ptr)
{
  *length_ptr = buffer_get_bignum(&incoming_packet, value);
}

/* Returns a string from the packet data.  The string is allocated using
   xmalloc; it is the responsibility of the calling program to free it when
   no longer needed.  The length_ptr argument may be NULL, or point to an
   integer into which the length of the string is stored. */

char
*packet_get_string(unsigned int *length_ptr)
{
  return buffer_get_string(&incoming_packet, length_ptr);
}

/* Sends a diagnostic message from the server to the client.  This message
   can be sent at any time (but not while constructing another message).
   The message is printed immediately, but only if the client is being
   executed in verbose mode.  These messages are primarily intended to
   ease debugging authentication problems.   The length of the formatted
   message must not exceed 1024 bytes.  This will automatically call
   packet_write_wait. */

void
packet_send_debug(const char *fmt, ...)
{
  char buf[1024];
  va_list args;
  
  va_start(args, fmt);
  vsnprintf(buf, sizeof(buf), fmt, args);
  va_end(args);
  
  packet_start(SSH_MSG_DEBUG);
  packet_put_string(buf, strlen(buf));
  packet_send();
  packet_write_wait();
}

/* Logs the error plus constructs and sends a disconnect
   packet, closes the connection, and exits.  This function never returns.
   The error message should not contain a newline.  The length of the
   formatted message must not exceed 1024 bytes. */

void
packet_disconnect(const char *fmt, ...)
{
  char buf[1024];
  va_list args;
  static int disconnecting = 0;
  if (disconnecting) /* Guard against recursive invocations. */
    fatal("packet_disconnect called recursively.");
  disconnecting = 1;

  /* Format the message.  Note that the caller must make sure the message
     is of limited size. */
  va_start(args, fmt);
  vsnprintf(buf, sizeof(buf), fmt, args);
  va_end(args);

  /* Send the disconnect message to the other side, and wait for it to get 
     sent. */
  packet_start(SSH_MSG_DISCONNECT);
  packet_put_string(buf, strlen(buf));
  packet_send();
  packet_write_wait();

  /* Stop listening for connections. */
  channel_stop_listening();
  
  /* Close the connection. */
  packet_close();

  /* Display the error locally and exit. */
  fatal("Local: %.100s", buf);
}

/* Checks if there is any buffered output, and tries to write some of the
   output. */

void
packet_write_poll()
{
  int len = buffer_len(&output);
  if (len > 0)
    {
      len = write(connection_out, buffer_ptr(&output), len);
      if (len <= 0) {
	if (errno == EAGAIN)
	  return;
        else
	  fatal("Write failed: %.100s", strerror(errno));
      }
      buffer_consume(&output, len);
    }
}

/* Calls packet_write_poll repeatedly until all pending output data has
   been written. */

void
packet_write_wait()
{
  packet_write_poll();
  while (packet_have_data_to_write())
    {
      fd_set set;
      FD_ZERO(&set);
      FD_SET(connection_out, &set);
      select(connection_out + 1, NULL, &set, NULL, NULL);
      packet_write_poll();
    }
}

/* Returns true if there is buffered data to write to the connection. */

int
packet_have_data_to_write()
{
  return buffer_len(&output) != 0;
}

/* Returns true if there is not too much data to write to the connection. */

int
packet_not_very_much_data_to_write()
{
  if (interactive_mode)
    return buffer_len(&output) < 16384;
  else
    return buffer_len(&output) < 128*1024;
}

/* Informs that the current session is interactive.  Sets IP flags for that. */

void
packet_set_interactive(int interactive, int keepalives)
{
  int on = 1;

  /* Record that we are in interactive mode. */
  interactive_mode = interactive;

  /* Only set socket options if using a socket (as indicated by the descriptors
     being the same). */
  if (connection_in != connection_out)
    return;

  if (keepalives)
    {
      /* Set keepalives if requested. */
      if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 
		     sizeof(on)) < 0)
	error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
    }

  if (interactive)
    {
      /* Set IP options for an interactive connection.  Use IPTOS_LOWDELAY
	 and TCP_NODELAY. */
      int lowdelay = IPTOS_LOWDELAY;
      if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&lowdelay, 
		     sizeof(lowdelay)) < 0)
	error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno));
      if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *)&on, 
		     sizeof(on)) < 0)
	error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
    }
  else
    {
      /* Set IP options for a non-interactive connection.  Use 
	 IPTOS_THROUGHPUT. */
      int throughput = IPTOS_THROUGHPUT;
      if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&throughput, 
		     sizeof(throughput)) < 0)
	error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
    }
}

/* Returns true if the current connection is interactive. */

int
packet_is_interactive()
{
  return interactive_mode;
}
