[BACK]Return to packet.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/packet.c between version 1.160 and 1.161

version 1.160, 2009/02/13 11:50:21 version 1.161, 2009/05/25 06:48:01
Line 82 
Line 82 
   
 #define PACKET_MAX_SIZE (256 * 1024)  #define PACKET_MAX_SIZE (256 * 1024)
   
 /*  struct packet_state {
  * This variable contains the file descriptors used for communicating with          u_int32_t seqnr;
  * the other side.  connection_in is used for reading; connection_out for          u_int32_t packets;
  * writing.  These can be the same descriptor, in which case it is assumed to          u_int64_t blocks;
  * be a socket.          u_int64_t bytes;
  */  };
 static int connection_in = -1;  
 static int connection_out = -1;  
   
 /* Protocol flags for the remote side. */  struct packet {
 static u_int remote_protocol_flags = 0;          TAILQ_ENTRY(packet) next;
           u_char type;
           Buffer payload;
   };
   
 /* Encryption context for receiving data.  This is only used for decryption. */  struct session_state {
 static CipherContext receive_context;          /*
            * 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.
            */
           int connection_in;
           int connection_out;
   
 /* Encryption context for sending data.  This is only used for encryption. */          /* Protocol flags for the remote side. */
 static CipherContext send_context;          u_int remote_protocol_flags;
   
 /* Buffer for raw input data from the socket. */          /* Encryption context for receiving data.  Only used for decryption. */
 Buffer input;          CipherContext receive_context;
   
 /* Buffer for raw output data going to the socket. */          /* Encryption context for sending data.  Only used for encryption. */
 Buffer output;          CipherContext send_context;
   
 /* Buffer for the partial outgoing packet being constructed. */          /* Buffer for raw input data from the socket. */
 static Buffer outgoing_packet;          Buffer input;
   
 /* Buffer for the incoming packet currently being processed. */          /* Buffer for raw output data going to the socket. */
 static Buffer incoming_packet;          Buffer output;
   
 /* Scratch buffer for packet compression/decompression. */          /* Buffer for the partial outgoing packet being constructed. */
 static Buffer compression_buffer;          Buffer outgoing_packet;
 static int compression_buffer_ready = 0;  
   
 /* Flag indicating whether packet compression/decompression is enabled. */          /* Buffer for the incoming packet currently being processed. */
 static int packet_compression = 0;          Buffer incoming_packet;
   
 /* default maximum packet size */          /* Scratch buffer for packet compression/decompression. */
 u_int max_packet_size = 32768;          Buffer compression_buffer;
           int compression_buffer_ready;
   
 /* Flag indicating whether this module has been initialized. */          /*
 static int initialized = 0;           * Flag indicating whether packet compression/decompression is
            * enabled.
            */
           int packet_compression;
   
 /* Set to true if the connection is interactive. */          /* default maximum packet size */
 static int interactive_mode = 0;          u_int max_packet_size;
   
 /* Set to true if we are the server side. */          /* Flag indicating whether this module has been initialized. */
 static int server_side = 0;          int initialized;
   
 /* Set to true if we are authenticated. */          /* Set to true if the connection is interactive. */
 static int after_authentication = 0;          int interactive_mode;
   
 int keep_alive_timeouts = 0;          /* Set to true if we are the server side. */
           int server_side;
   
 /* Set to the maximum time that we will wait to send or receive a packet */          /* Set to true if we are authenticated. */
 static int packet_timeout_ms = -1;          int after_authentication;
   
 /* Session key information for Encryption and MAC */          int keep_alive_timeouts;
 Newkeys *newkeys[MODE_MAX];  
 static struct packet_state {  
         u_int32_t seqnr;  
         u_int32_t packets;  
         u_int64_t blocks;  
         u_int64_t bytes;  
 } p_read, p_send;  
   
 static u_int64_t max_blocks_in, max_blocks_out;          /* The maximum time that we will wait to send or receive a packet */
 static u_int32_t rekey_limit;          int packet_timeout_ms;
   
 /* Session key for protocol v1 */          /* Session key information for Encryption and MAC */
 static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];          Newkeys *newkeys[MODE_MAX];
 static u_int ssh1_keylen;          struct packet_state p_read, p_send;
   
 /* roundup current message to extra_pad bytes */          u_int64_t max_blocks_in, max_blocks_out;
 static u_char extra_pad = 0;          u_int32_t rekey_limit;
   
 /* XXX discard incoming data after MAC error */          /* Session key for protocol v1 */
 static u_int packet_discard = 0;          u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
 static Mac *packet_discard_mac = NULL;          u_int ssh1_keylen;
   
 struct packet {          /* roundup current message to extra_pad bytes */
         TAILQ_ENTRY(packet) next;          u_char extra_pad;
         u_char type;  
         Buffer payload;          /* XXX discard incoming data after MAC error */
           u_int packet_discard;
           Mac *packet_discard_mac;
   
           /* Used in packet_read_poll2() */
           u_int packlen;
   
           TAILQ_HEAD(, packet) outgoing;
 };  };
 TAILQ_HEAD(, packet) outgoing;  
   
   static struct session_state *active_state;
   
   static struct session_state *
   alloc_session_state()
   {
       struct session_state *s = xcalloc(1, sizeof(*s));
   
       s->connection_in = -1;
       s->connection_out = -1;
       s->max_packet_size = 32768;
       s->packet_timeout_ms = -1;
       return s;
   }
   
 /*  /*
  * Sets the descriptors used for communication.  Disables encryption until   * Sets the descriptors used for communication.  Disables encryption until
  * packet_set_encryption_key is called.   * packet_set_encryption_key is called.
Line 180 
Line 205 
   
         if (none == NULL)          if (none == NULL)
                 fatal("packet_set_connection: cannot load cipher 'none'");                  fatal("packet_set_connection: cannot load cipher 'none'");
         connection_in = fd_in;          if (active_state == NULL)
         connection_out = fd_out;                  active_state = alloc_session_state();
         cipher_init(&send_context, none, (const u_char *)"",          active_state->connection_in = fd_in;
           active_state->connection_out = fd_out;
           cipher_init(&active_state->send_context, none, (const u_char *)"",
             0, NULL, 0, CIPHER_ENCRYPT);              0, NULL, 0, CIPHER_ENCRYPT);
         cipher_init(&receive_context, none, (const u_char *)"",          cipher_init(&active_state->receive_context, none, (const u_char *)"",
             0, NULL, 0, CIPHER_DECRYPT);              0, NULL, 0, CIPHER_DECRYPT);
         newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;          active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
         if (!initialized) {          if (!active_state->initialized) {
                 initialized = 1;                  active_state->initialized = 1;
                 buffer_init(&input);                  buffer_init(&active_state->input);
                 buffer_init(&output);                  buffer_init(&active_state->output);
                 buffer_init(&outgoing_packet);                  buffer_init(&active_state->outgoing_packet);
                 buffer_init(&incoming_packet);                  buffer_init(&active_state->incoming_packet);
                 TAILQ_INIT(&outgoing);                  TAILQ_INIT(&active_state->outgoing);
                 p_send.packets = p_read.packets = 0;                  active_state->p_send.packets = active_state->p_read.packets = 0;
         }          }
 }  }
   
Line 202 
Line 229 
 packet_set_timeout(int timeout, int count)  packet_set_timeout(int timeout, int count)
 {  {
         if (timeout == 0 || count == 0) {          if (timeout == 0 || count == 0) {
                 packet_timeout_ms = -1;                  active_state->packet_timeout_ms = -1;
                 return;                  return;
         }          }
         if ((INT_MAX / 1000) / count < timeout)          if ((INT_MAX / 1000) / count < timeout)
                 packet_timeout_ms = INT_MAX;                  active_state->packet_timeout_ms = INT_MAX;
         else          else
                 packet_timeout_ms = timeout * count * 1000;                  active_state->packet_timeout_ms = timeout * count * 1000;
 }  }
   
 static void  static void
 packet_stop_discard(void)  packet_stop_discard(void)
 {  {
         if (packet_discard_mac) {          if (active_state->packet_discard_mac) {
                 char buf[1024];                  char buf[1024];
   
                 memset(buf, 'a', sizeof(buf));                  memset(buf, 'a', sizeof(buf));
                 while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)                  while (buffer_len(&active_state->incoming_packet) <
                         buffer_append(&incoming_packet, buf, sizeof(buf));                      PACKET_MAX_SIZE)
                 (void) mac_compute(packet_discard_mac,                          buffer_append(&active_state->incoming_packet, buf,
                     p_read.seqnr,                              sizeof(buf));
                     buffer_ptr(&incoming_packet),                  (void) mac_compute(active_state->packet_discard_mac,
                       active_state->p_read.seqnr,
                       buffer_ptr(&active_state->incoming_packet),
                     PACKET_MAX_SIZE);                      PACKET_MAX_SIZE);
         }          }
         logit("Finished discarding for %.200s", get_remote_ipaddr());          logit("Finished discarding for %.200s", get_remote_ipaddr());
Line 235 
Line 264 
         if (enc == NULL || !cipher_is_cbc(enc->cipher))          if (enc == NULL || !cipher_is_cbc(enc->cipher))
                 packet_disconnect("Packet corrupt");                  packet_disconnect("Packet corrupt");
         if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)          if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
                 packet_discard_mac = mac;                  active_state->packet_discard_mac = mac;
         if (buffer_len(&input) >= discard)          if (buffer_len(&active_state->input) >= discard)
                 packet_stop_discard();                  packet_stop_discard();
         packet_discard = discard - buffer_len(&input);          active_state->packet_discard = discard -
               buffer_len(&active_state->input);
 }  }
   
 /* Returns 1 if remote host is connected via socket, 0 if not. */  /* Returns 1 if remote host is connected via socket, 0 if not. */
Line 250 
Line 280 
         socklen_t fromlen, tolen;          socklen_t fromlen, tolen;
   
         /* filedescriptors in and out are the same, so it's a socket */          /* filedescriptors in and out are the same, so it's a socket */
         if (connection_in == connection_out)          if (active_state->connection_in == active_state->connection_out)
                 return 1;                  return 1;
         fromlen = sizeof(from);          fromlen = sizeof(from);
         memset(&from, 0, sizeof(from));          memset(&from, 0, sizeof(from));
         if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)          if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
               &fromlen) < 0)
                 return 0;                  return 0;
         tolen = sizeof(to);          tolen = sizeof(to);
         memset(&to, 0, sizeof(to));          memset(&to, 0, sizeof(to));
         if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)          if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
               &tolen) < 0)
                 return 0;                  return 0;
         if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)          if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
                 return 0;                  return 0;
Line 279 
Line 311 
         CipherContext *cc;          CipherContext *cc;
   
         if (mode == MODE_OUT)          if (mode == MODE_OUT)
                 cc = &send_context;                  cc = &active_state->send_context;
         else          else
                 cc = &receive_context;                  cc = &active_state->receive_context;
   
         cipher_get_keyiv(cc, iv, len);          cipher_get_keyiv(cc, iv, len);
 }  }
Line 292 
Line 324 
         CipherContext *cc;          CipherContext *cc;
   
         if (mode == MODE_OUT)          if (mode == MODE_OUT)
                 cc = &send_context;                  cc = &active_state->send_context;
         else          else
                 cc = &receive_context;                  cc = &active_state->receive_context;
   
         return (cipher_get_keycontext(cc, dat));          return (cipher_get_keycontext(cc, dat));
 }  }
Line 305 
Line 337 
         CipherContext *cc;          CipherContext *cc;
   
         if (mode == MODE_OUT)          if (mode == MODE_OUT)
                 cc = &send_context;                  cc = &active_state->send_context;
         else          else
                 cc = &receive_context;                  cc = &active_state->receive_context;
   
         cipher_set_keycontext(cc, dat);          cipher_set_keycontext(cc, dat);
 }  }
Line 318 
Line 350 
         CipherContext *cc;          CipherContext *cc;
   
         if (mode == MODE_OUT)          if (mode == MODE_OUT)
                 cc = &send_context;                  cc = &active_state->send_context;
         else          else
                 cc = &receive_context;                  cc = &active_state->receive_context;
   
         return (cipher_get_keyiv_len(cc));          return (cipher_get_keyiv_len(cc));
 }  }
Line 331 
Line 363 
         CipherContext *cc;          CipherContext *cc;
   
         if (mode == MODE_OUT)          if (mode == MODE_OUT)
                 cc = &send_context;                  cc = &active_state->send_context;
         else          else
                 cc = &receive_context;                  cc = &active_state->receive_context;
   
         cipher_set_keyiv(cc, dat);          cipher_set_keyiv(cc, dat);
 }  }
Line 341 
Line 373 
 int  int
 packet_get_ssh1_cipher(void)  packet_get_ssh1_cipher(void)
 {  {
         return (cipher_get_number(receive_context.cipher));          return (cipher_get_number(active_state->receive_context.cipher));
 }  }
   
 void  void
Line 350 
Line 382 
 {  {
         struct packet_state *state;          struct packet_state *state;
   
         state = (mode == MODE_IN) ? &p_read : &p_send;          state = (mode == MODE_IN) ?
               &active_state->p_read : &active_state->p_send;
         if (seqnr)          if (seqnr)
                 *seqnr = state->seqnr;                  *seqnr = state->seqnr;
         if (blocks)          if (blocks)
Line 367 
Line 400 
 {  {
         struct packet_state *state;          struct packet_state *state;
   
         state = (mode == MODE_IN) ? &p_read : &p_send;          state = (mode == MODE_IN) ?
               &active_state->p_read : &active_state->p_send;
         state->seqnr = seqnr;          state->seqnr = seqnr;
         state->blocks = blocks;          state->blocks = blocks;
         state->packets = packets;          state->packets = packets;
Line 383 
Line 417 
         socklen_t tolen = sizeof(to);          socklen_t tolen = sizeof(to);
   
         memset(&to, 0, sizeof(to));          memset(&to, 0, sizeof(to));
         if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)          if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
               &tolen) < 0)
                 return 0;                  return 0;
         if (to.ss_family != AF_INET)          if (to.ss_family != AF_INET)
                 return 0;                  return 0;
Line 396 
Line 431 
 packet_set_nonblocking(void)  packet_set_nonblocking(void)
 {  {
         /* Set the socket into non-blocking mode. */          /* Set the socket into non-blocking mode. */
         set_nonblock(connection_in);          set_nonblock(active_state->connection_in);
   
         if (connection_out != connection_in)          if (active_state->connection_out != active_state->connection_in)
                 set_nonblock(connection_out);                  set_nonblock(active_state->connection_out);
 }  }
   
 /* Returns the socket used for reading. */  /* Returns the socket used for reading. */
Line 407 
Line 442 
 int  int
 packet_get_connection_in(void)  packet_get_connection_in(void)
 {  {
         return connection_in;          return active_state->connection_in;
 }  }
   
 /* Returns the descriptor used for writing. */  /* Returns the descriptor used for writing. */
Line 415 
Line 450 
 int  int
 packet_get_connection_out(void)  packet_get_connection_out(void)
 {  {
         return connection_out;          return active_state->connection_out;
 }  }
   
 /* Closes the connection and clears and frees internal data structures. */  /* Closes the connection and clears and frees internal data structures. */
Line 423 
Line 458 
 void  void
 packet_close(void)  packet_close(void)
 {  {
         if (!initialized)          if (!active_state->initialized)
                 return;                  return;
         initialized = 0;          active_state->initialized = 0;
         if (connection_in == connection_out) {          if (active_state->connection_in == active_state->connection_out) {
                 shutdown(connection_out, SHUT_RDWR);                  shutdown(active_state->connection_out, SHUT_RDWR);
                 close(connection_out);                  close(active_state->connection_out);
         } else {          } else {
                 close(connection_in);                  close(active_state->connection_in);
                 close(connection_out);                  close(active_state->connection_out);
         }          }
         buffer_free(&input);          buffer_free(&active_state->input);
         buffer_free(&output);          buffer_free(&active_state->output);
         buffer_free(&outgoing_packet);          buffer_free(&active_state->outgoing_packet);
         buffer_free(&incoming_packet);          buffer_free(&active_state->incoming_packet);
         if (compression_buffer_ready) {          if (active_state->compression_buffer_ready) {
                 buffer_free(&compression_buffer);                  buffer_free(&active_state->compression_buffer);
                 buffer_compress_uninit();                  buffer_compress_uninit();
         }          }
         cipher_cleanup(&send_context);          cipher_cleanup(&active_state->send_context);
         cipher_cleanup(&receive_context);          cipher_cleanup(&active_state->receive_context);
 }  }
   
 /* Sets remote side protocol flags. */  /* Sets remote side protocol flags. */
Line 450 
Line 485 
 void  void
 packet_set_protocol_flags(u_int protocol_flags)  packet_set_protocol_flags(u_int protocol_flags)
 {  {
         remote_protocol_flags = protocol_flags;          active_state->remote_protocol_flags = protocol_flags;
 }  }
   
 /* Returns the remote protocol flags set earlier by the above function. */  /* Returns the remote protocol flags set earlier by the above function. */
Line 458 
Line 493 
 u_int  u_int
 packet_get_protocol_flags(void)  packet_get_protocol_flags(void)
 {  {
         return remote_protocol_flags;          return active_state->remote_protocol_flags;
 }  }
   
 /*  /*
Line 469 
Line 504 
 static void  static void
 packet_init_compression(void)  packet_init_compression(void)
 {  {
         if (compression_buffer_ready == 1)          if (active_state->compression_buffer_ready == 1)
                 return;                  return;
         compression_buffer_ready = 1;          active_state->compression_buffer_ready = 1;
         buffer_init(&compression_buffer);          buffer_init(&active_state->compression_buffer);
 }  }
   
 void  void
 packet_start_compression(int level)  packet_start_compression(int level)
 {  {
         if (packet_compression && !compat20)          if (active_state->packet_compression && !compat20)
                 fatal("Compression already enabled.");                  fatal("Compression already enabled.");
         packet_compression = 1;          active_state->packet_compression = 1;
         packet_init_compression();          packet_init_compression();
         buffer_compress_init_send(level);          buffer_compress_init_send(level);
         buffer_compress_init_recv();          buffer_compress_init_recv();
Line 504 
Line 539 
                 fatal("packet_set_encryption_key: keylen too small: %d", keylen);                  fatal("packet_set_encryption_key: keylen too small: %d", keylen);
         if (keylen > SSH_SESSION_KEY_LENGTH)          if (keylen > SSH_SESSION_KEY_LENGTH)
                 fatal("packet_set_encryption_key: keylen too big: %d", keylen);                  fatal("packet_set_encryption_key: keylen too big: %d", keylen);
         memcpy(ssh1_key, key, keylen);          memcpy(active_state->ssh1_key, key, keylen);
         ssh1_keylen = keylen;          active_state->ssh1_keylen = keylen;
         cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);          cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
         cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);              0, CIPHER_ENCRYPT);
           cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
               0, CIPHER_DECRYPT);
 }  }
   
 u_int  u_int
 packet_get_encryption_key(u_char *key)  packet_get_encryption_key(u_char *key)
 {  {
         if (key == NULL)          if (key == NULL)
                 return (ssh1_keylen);                  return (active_state->ssh1_keylen);
         memcpy(key, ssh1_key, ssh1_keylen);          memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
         return (ssh1_keylen);          return (active_state->ssh1_keylen);
 }  }
   
 /* Start constructing a packet to send. */  /* Start constructing a packet to send. */
Line 530 
Line 567 
         len = compat20 ? 6 : 9;          len = compat20 ? 6 : 9;
         memset(buf, 0, len - 1);          memset(buf, 0, len - 1);
         buf[len - 1] = type;          buf[len - 1] = type;
         buffer_clear(&outgoing_packet);          buffer_clear(&active_state->outgoing_packet);
         buffer_append(&outgoing_packet, buf, len);          buffer_append(&active_state->outgoing_packet, buf, len);
 }  }
   
 /* Append payload. */  /* Append payload. */
Line 540 
Line 577 
 {  {
         char ch = value;          char ch = value;
   
         buffer_append(&outgoing_packet, &ch, 1);          buffer_append(&active_state->outgoing_packet, &ch, 1);
 }  }
   
 void  void
 packet_put_int(u_int value)  packet_put_int(u_int value)
 {  {
         buffer_put_int(&outgoing_packet, value);          buffer_put_int(&active_state->outgoing_packet, value);
 }  }
   
 void  void
 packet_put_string(const void *buf, u_int len)  packet_put_string(const void *buf, u_int len)
 {  {
         buffer_put_string(&outgoing_packet, buf, len);          buffer_put_string(&active_state->outgoing_packet, buf, len);
 }  }
   
 void  void
 packet_put_cstring(const char *str)  packet_put_cstring(const char *str)
 {  {
         buffer_put_cstring(&outgoing_packet, str);          buffer_put_cstring(&active_state->outgoing_packet, str);
 }  }
   
 void  void
 packet_put_raw(const void *buf, u_int len)  packet_put_raw(const void *buf, u_int len)
 {  {
         buffer_append(&outgoing_packet, buf, len);          buffer_append(&active_state->outgoing_packet, buf, len);
 }  }
   
 void  void
 packet_put_bignum(BIGNUM * value)  packet_put_bignum(BIGNUM * value)
 {  {
         buffer_put_bignum(&outgoing_packet, value);          buffer_put_bignum(&active_state->outgoing_packet, value);
 }  }
   
 void  void
 packet_put_bignum2(BIGNUM * value)  packet_put_bignum2(BIGNUM * value)
 {  {
         buffer_put_bignum2(&outgoing_packet, value);          buffer_put_bignum2(&active_state->outgoing_packet, value);
 }  }
   
 /*  /*
Line 596 
Line 633 
          * If using packet compression, compress the payload of the outgoing           * If using packet compression, compress the payload of the outgoing
          * packet.           * packet.
          */           */
         if (packet_compression) {          if (active_state->packet_compression) {
                 buffer_clear(&compression_buffer);                  buffer_clear(&active_state->compression_buffer);
                 /* Skip padding. */                  /* Skip padding. */
                 buffer_consume(&outgoing_packet, 8);                  buffer_consume(&active_state->outgoing_packet, 8);
                 /* padding */                  /* padding */
                 buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);                  buffer_append(&active_state->compression_buffer,
                 buffer_compress(&outgoing_packet, &compression_buffer);                      "\0\0\0\0\0\0\0\0", 8);
                 buffer_clear(&outgoing_packet);                  buffer_compress(&active_state->outgoing_packet,
                 buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),                      &active_state->compression_buffer);
                     buffer_len(&compression_buffer));                  buffer_clear(&active_state->outgoing_packet);
                   buffer_append(&active_state->outgoing_packet,
                       buffer_ptr(&active_state->compression_buffer),
                       buffer_len(&active_state->compression_buffer));
         }          }
         /* Compute packet length without padding (add checksum, remove padding). */          /* Compute packet length without padding (add checksum, remove padding). */
         len = buffer_len(&outgoing_packet) + 4 - 8;          len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
   
         /* Insert padding. Initialized to zero in packet_start1() */          /* Insert padding. Initialized to zero in packet_start1() */
         padding = 8 - len % 8;          padding = 8 - len % 8;
         if (!send_context.plaintext) {          if (!active_state->send_context.plaintext) {
                 cp = buffer_ptr(&outgoing_packet);                  cp = buffer_ptr(&active_state->outgoing_packet);
                 for (i = 0; i < padding; i++) {                  for (i = 0; i < padding; i++) {
                         if (i % 4 == 0)                          if (i % 4 == 0)
                                 rnd = arc4random();                                  rnd = arc4random();
Line 621 
Line 661 
                         rnd >>= 8;                          rnd >>= 8;
                 }                  }
         }          }
         buffer_consume(&outgoing_packet, 8 - padding);          buffer_consume(&active_state->outgoing_packet, 8 - padding);
   
         /* Add check bytes. */          /* Add check bytes. */
         checksum = ssh_crc32(buffer_ptr(&outgoing_packet),          checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
             buffer_len(&outgoing_packet));              buffer_len(&active_state->outgoing_packet));
         put_u32(buf, checksum);          put_u32(buf, checksum);
         buffer_append(&outgoing_packet, buf, 4);          buffer_append(&active_state->outgoing_packet, buf, 4);
   
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "packet_send plain: ");          fprintf(stderr, "packet_send plain: ");
         buffer_dump(&outgoing_packet);          buffer_dump(&active_state->outgoing_packet);
 #endif  #endif
   
         /* Append to output. */          /* Append to output. */
         put_u32(buf, len);          put_u32(buf, len);
         buffer_append(&output, buf, 4);          buffer_append(&active_state->output, buf, 4);
         cp = buffer_append_space(&output, buffer_len(&outgoing_packet));          cp = buffer_append_space(&active_state->output,
         cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),              buffer_len(&active_state->outgoing_packet));
             buffer_len(&outgoing_packet));          cipher_crypt(&active_state->send_context, cp,
               buffer_ptr(&active_state->outgoing_packet),
               buffer_len(&active_state->outgoing_packet));
   
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "encrypted: ");          fprintf(stderr, "encrypted: ");
         buffer_dump(&output);          buffer_dump(&active_state->output);
 #endif  #endif
         p_send.packets++;          active_state->p_send.packets++;
         p_send.bytes += len + buffer_len(&outgoing_packet);          active_state->p_send.bytes += len +
         buffer_clear(&outgoing_packet);              buffer_len(&active_state->outgoing_packet);
           buffer_clear(&active_state->outgoing_packet);
   
         /*          /*
          * Note that the packet is now only buffered in output.  It won't be           * Note that the packet is now only buffered in output.  It won't be
Line 669 
Line 712 
         debug2("set_newkeys: mode %d", mode);          debug2("set_newkeys: mode %d", mode);
   
         if (mode == MODE_OUT) {          if (mode == MODE_OUT) {
                 cc = &send_context;                  cc = &active_state->send_context;
                 crypt_type = CIPHER_ENCRYPT;                  crypt_type = CIPHER_ENCRYPT;
                 p_send.packets = p_send.blocks = 0;                  active_state->p_send.packets = active_state->p_send.blocks = 0;
                 max_blocks = &max_blocks_out;                  max_blocks = &active_state->max_blocks_out;
         } else {          } else {
                 cc = &receive_context;                  cc = &active_state->receive_context;
                 crypt_type = CIPHER_DECRYPT;                  crypt_type = CIPHER_DECRYPT;
                 p_read.packets = p_read.blocks = 0;                  active_state->p_read.packets = active_state->p_read.blocks = 0;
                 max_blocks = &max_blocks_in;                  max_blocks = &active_state->max_blocks_in;
         }          }
         if (newkeys[mode] != NULL) {          if (active_state->newkeys[mode] != NULL) {
                 debug("set_newkeys: rekeying");                  debug("set_newkeys: rekeying");
                 cipher_cleanup(cc);                  cipher_cleanup(cc);
                 enc  = &newkeys[mode]->enc;                  enc  = &active_state->newkeys[mode]->enc;
                 mac  = &newkeys[mode]->mac;                  mac  = &active_state->newkeys[mode]->mac;
                 comp = &newkeys[mode]->comp;                  comp = &active_state->newkeys[mode]->comp;
                 mac_clear(mac);                  mac_clear(mac);
                 xfree(enc->name);                  xfree(enc->name);
                 xfree(enc->iv);                  xfree(enc->iv);
Line 692 
Line 735 
                 xfree(mac->name);                  xfree(mac->name);
                 xfree(mac->key);                  xfree(mac->key);
                 xfree(comp->name);                  xfree(comp->name);
                 xfree(newkeys[mode]);                  xfree(active_state->newkeys[mode]);
         }          }
         newkeys[mode] = kex_get_newkeys(mode);          active_state->newkeys[mode] = kex_get_newkeys(mode);
         if (newkeys[mode] == NULL)          if (active_state->newkeys[mode] == NULL)
                 fatal("newkeys: no keys for mode %d", mode);                  fatal("newkeys: no keys for mode %d", mode);
         enc  = &newkeys[mode]->enc;          enc  = &active_state->newkeys[mode]->enc;
         mac  = &newkeys[mode]->mac;          mac  = &active_state->newkeys[mode]->mac;
         comp = &newkeys[mode]->comp;          comp = &active_state->newkeys[mode]->comp;
         if (mac_init(mac) == 0)          if (mac_init(mac) == 0)
                 mac->enabled = 1;                  mac->enabled = 1;
         DBG(debug("cipher_init_context: %d", mode));          DBG(debug("cipher_init_context: %d", mode));
Line 710 
Line 753 
            memset(enc->key, 0, enc->key_len);             memset(enc->key, 0, enc->key_len);
            memset(mac->key, 0, mac->key_len); */             memset(mac->key, 0, mac->key_len); */
         if ((comp->type == COMP_ZLIB ||          if ((comp->type == COMP_ZLIB ||
             (comp->type == COMP_DELAYED && after_authentication)) &&              (comp->type == COMP_DELAYED &&
             comp->enabled == 0) {               active_state->after_authentication)) && comp->enabled == 0) {
                 packet_init_compression();                  packet_init_compression();
                 if (mode == MODE_OUT)                  if (mode == MODE_OUT)
                         buffer_compress_init_send(6);                          buffer_compress_init_send(6);
Line 727 
Line 770 
                 *max_blocks = (u_int64_t)1 << (enc->block_size*2);                  *max_blocks = (u_int64_t)1 << (enc->block_size*2);
         else          else
                 *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;                  *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
         if (rekey_limit)          if (active_state->rekey_limit)
                 *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);                  *max_blocks = MIN(*max_blocks,
                       active_state->rekey_limit / enc->block_size);
 }  }
   
 /*  /*
Line 746 
Line 790 
          * Remember that we are past the authentication step, so rekeying           * Remember that we are past the authentication step, so rekeying
          * with COMP_DELAYED will turn on compression immediately.           * with COMP_DELAYED will turn on compression immediately.
          */           */
         after_authentication = 1;          active_state->after_authentication = 1;
         for (mode = 0; mode < MODE_MAX; mode++) {          for (mode = 0; mode < MODE_MAX; mode++) {
                 /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */                  /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
                 if (newkeys[mode] == NULL)                  if (active_state->newkeys[mode] == NULL)
                         continue;                          continue;
                 comp = &newkeys[mode]->comp;                  comp = &active_state->newkeys[mode]->comp;
                 if (comp && !comp->enabled && comp->type == COMP_DELAYED) {                  if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
                         packet_init_compression();                          packet_init_compression();
                         if (mode == MODE_OUT)                          if (mode == MODE_OUT)
Line 779 
Line 823 
         Comp *comp = NULL;          Comp *comp = NULL;
         int block_size;          int block_size;
   
         if (newkeys[MODE_OUT] != NULL) {          if (active_state->newkeys[MODE_OUT] != NULL) {
                 enc  = &newkeys[MODE_OUT]->enc;                  enc  = &active_state->newkeys[MODE_OUT]->enc;
                 mac  = &newkeys[MODE_OUT]->mac;                  mac  = &active_state->newkeys[MODE_OUT]->mac;
                 comp = &newkeys[MODE_OUT]->comp;                  comp = &active_state->newkeys[MODE_OUT]->comp;
         }          }
         block_size = enc ? enc->block_size : 8;          block_size = enc ? enc->block_size : 8;
   
         cp = buffer_ptr(&outgoing_packet);          cp = buffer_ptr(&active_state->outgoing_packet);
         type = cp[5];          type = cp[5];
   
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "plain:     ");          fprintf(stderr, "plain:     ");
         buffer_dump(&outgoing_packet);          buffer_dump(&active_state->outgoing_packet);
 #endif  #endif
   
         if (comp && comp->enabled) {          if (comp && comp->enabled) {
                 len = buffer_len(&outgoing_packet);                  len = buffer_len(&active_state->outgoing_packet);
                 /* skip header, compress only payload */                  /* skip header, compress only payload */
                 buffer_consume(&outgoing_packet, 5);                  buffer_consume(&active_state->outgoing_packet, 5);
                 buffer_clear(&compression_buffer);                  buffer_clear(&active_state->compression_buffer);
                 buffer_compress(&outgoing_packet, &compression_buffer);                  buffer_compress(&active_state->outgoing_packet,
                 buffer_clear(&outgoing_packet);                      &active_state->compression_buffer);
                 buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);                  buffer_clear(&active_state->outgoing_packet);
                 buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),                  buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
                     buffer_len(&compression_buffer));                  buffer_append(&active_state->outgoing_packet,
                       buffer_ptr(&active_state->compression_buffer),
                       buffer_len(&active_state->compression_buffer));
                 DBG(debug("compression: raw %d compressed %d", len,                  DBG(debug("compression: raw %d compressed %d", len,
                     buffer_len(&outgoing_packet)));                      buffer_len(&active_state->outgoing_packet)));
         }          }
   
         /* sizeof (packet_len + pad_len + payload) */          /* sizeof (packet_len + pad_len + payload) */
         len = buffer_len(&outgoing_packet);          len = buffer_len(&active_state->outgoing_packet);
   
         /*          /*
          * calc size of padding, alloc space, get random data,           * calc size of padding, alloc space, get random data,
Line 818 
Line 864 
         padlen = block_size - (len % block_size);          padlen = block_size - (len % block_size);
         if (padlen < 4)          if (padlen < 4)
                 padlen += block_size;                  padlen += block_size;
         if (extra_pad) {          if (active_state->extra_pad) {
                 /* will wrap if extra_pad+padlen > 255 */                  /* will wrap if extra_pad+padlen > 255 */
                 extra_pad  = roundup(extra_pad, block_size);                  active_state->extra_pad =
                 pad = extra_pad - ((len + padlen) % extra_pad);                      roundup(active_state->extra_pad, block_size);
                   pad = active_state->extra_pad -
                       ((len + padlen) % active_state->extra_pad);
                 debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",                  debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
                     pad, len, padlen, extra_pad);                      pad, len, padlen, active_state->extra_pad);
                 padlen += pad;                  padlen += pad;
                 extra_pad = 0;                  active_state->extra_pad = 0;
         }          }
         cp = buffer_append_space(&outgoing_packet, padlen);          cp = buffer_append_space(&active_state->outgoing_packet, padlen);
         if (enc && !send_context.plaintext) {          if (enc && !active_state->send_context.plaintext) {
                 /* random padding */                  /* random padding */
                 for (i = 0; i < padlen; i++) {                  for (i = 0; i < padlen; i++) {
                         if (i % 4 == 0)                          if (i % 4 == 0)
Line 841 
Line 889 
                 memset(cp, 0, padlen);                  memset(cp, 0, padlen);
         }          }
         /* packet_length includes payload, padding and padding length field */          /* packet_length includes payload, padding and padding length field */
         packet_length = buffer_len(&outgoing_packet) - 4;          packet_length = buffer_len(&active_state->outgoing_packet) - 4;
         cp = buffer_ptr(&outgoing_packet);          cp = buffer_ptr(&active_state->outgoing_packet);
         put_u32(cp, packet_length);          put_u32(cp, packet_length);
         cp[4] = padlen;          cp[4] = padlen;
         DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));          DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
   
         /* compute MAC over seqnr and packet(length fields, payload, padding) */          /* compute MAC over seqnr and packet(length fields, payload, padding) */
         if (mac && mac->enabled) {          if (mac && mac->enabled) {
                 macbuf = mac_compute(mac, p_send.seqnr,                  macbuf = mac_compute(mac, active_state->p_send.seqnr,
                     buffer_ptr(&outgoing_packet),                      buffer_ptr(&active_state->outgoing_packet),
                     buffer_len(&outgoing_packet));                      buffer_len(&active_state->outgoing_packet));
                 DBG(debug("done calc MAC out #%d", p_send.seqnr));                  DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
         }          }
         /* encrypt packet and append to output buffer. */          /* encrypt packet and append to output buffer. */
         cp = buffer_append_space(&output, buffer_len(&outgoing_packet));          cp = buffer_append_space(&active_state->output,
         cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),              buffer_len(&active_state->outgoing_packet));
             buffer_len(&outgoing_packet));          cipher_crypt(&active_state->send_context, cp,
               buffer_ptr(&active_state->outgoing_packet),
               buffer_len(&active_state->outgoing_packet));
         /* append unencrypted MAC */          /* append unencrypted MAC */
         if (mac && mac->enabled)          if (mac && mac->enabled)
                 buffer_append(&output, macbuf, mac->mac_len);                  buffer_append(&active_state->output, macbuf, mac->mac_len);
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "encrypted: ");          fprintf(stderr, "encrypted: ");
         buffer_dump(&output);          buffer_dump(&active_state->output);
 #endif  #endif
         /* increment sequence number for outgoing packets */          /* increment sequence number for outgoing packets */
         if (++p_send.seqnr == 0)          if (++active_state->p_send.seqnr == 0)
                 logit("outgoing seqnr wraps around");                  logit("outgoing seqnr wraps around");
         if (++p_send.packets == 0)          if (++active_state->p_send.packets == 0)
                 if (!(datafellows & SSH_BUG_NOREKEY))                  if (!(datafellows & SSH_BUG_NOREKEY))
                         fatal("XXX too many packets with same key");                          fatal("XXX too many packets with same key");
         p_send.blocks += (packet_length + 4) / block_size;          active_state->p_send.blocks += (packet_length + 4) / block_size;
         p_send.bytes += packet_length + 4;          active_state->p_send.bytes += packet_length + 4;
         buffer_clear(&outgoing_packet);          buffer_clear(&active_state->outgoing_packet);
   
         if (type == SSH2_MSG_NEWKEYS)          if (type == SSH2_MSG_NEWKEYS)
                 set_newkeys(MODE_OUT);                  set_newkeys(MODE_OUT);
         else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)          else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
                 packet_enable_delayed_compress();                  packet_enable_delayed_compress();
 }  }
   
Line 888 
Line 938 
         struct packet *p;          struct packet *p;
         u_char type, *cp;          u_char type, *cp;
   
         cp = buffer_ptr(&outgoing_packet);          cp = buffer_ptr(&active_state->outgoing_packet);
         type = cp[5];          type = cp[5];
   
         /* during rekeying we can only send key exchange messages */          /* during rekeying we can only send key exchange messages */
Line 898 
Line 948 
                         debug("enqueue packet: %u", type);                          debug("enqueue packet: %u", type);
                         p = xmalloc(sizeof(*p));                          p = xmalloc(sizeof(*p));
                         p->type = type;                          p->type = type;
                         memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));                          memcpy(&p->payload, &active_state->outgoing_packet,
                         buffer_init(&outgoing_packet);                              sizeof(Buffer));
                         TAILQ_INSERT_TAIL(&outgoing, p, next);                          buffer_init(&active_state->outgoing_packet);
                           TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
                         return;                          return;
                 }                  }
         }          }
Line 914 
Line 965 
         /* after a NEWKEYS message we can send the complete queue */          /* after a NEWKEYS message we can send the complete queue */
         if (type == SSH2_MSG_NEWKEYS) {          if (type == SSH2_MSG_NEWKEYS) {
                 rekeying = 0;                  rekeying = 0;
                 while ((p = TAILQ_FIRST(&outgoing))) {                  while ((p = TAILQ_FIRST(&active_state->outgoing))) {
                         type = p->type;                          type = p->type;
                         debug("dequeue packet: %u", type);                          debug("dequeue packet: %u", type);
                         buffer_free(&outgoing_packet);                          buffer_free(&active_state->outgoing_packet);
                         memcpy(&outgoing_packet, &p->payload,                          memcpy(&active_state->outgoing_packet, &p->payload,
                             sizeof(Buffer));                              sizeof(Buffer));
                         TAILQ_REMOVE(&outgoing, p, next);                          TAILQ_REMOVE(&active_state->outgoing, p, next);
                         xfree(p);                          xfree(p);
                         packet_send2_wrapped();                          packet_send2_wrapped();
                 }                  }
Line 953 
Line 1004 
   
         DBG(debug("packet_read()"));          DBG(debug("packet_read()"));
   
         setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),          setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
             sizeof(fd_mask));              NFDBITS), sizeof(fd_mask));
   
         /* Since we are blocking, ensure that all written packets have been sent. */          /* Since we are blocking, ensure that all written packets have been sent. */
         packet_write_wait();          packet_write_wait();
Line 978 
Line 1029 
                  * Otherwise, wait for some data to arrive, add it to the                   * Otherwise, wait for some data to arrive, add it to the
                  * buffer, and try again.                   * buffer, and try again.
                  */                   */
                 memset(setp, 0, howmany(connection_in + 1, NFDBITS) *                  memset(setp, 0, howmany(active_state->connection_in + 1,
                     sizeof(fd_mask));                      NFDBITS) * sizeof(fd_mask));
                 FD_SET(connection_in, setp);                  FD_SET(active_state->connection_in, setp);
   
                 if (packet_timeout_ms > 0) {                  if (active_state->packet_timeout_ms > 0) {
                         ms_remain = packet_timeout_ms;                          ms_remain = active_state->packet_timeout_ms;
                         timeoutp = &timeout;                          timeoutp = &timeout;
                 }                  }
                 /* Wait for some data to arrive. */                  /* Wait for some data to arrive. */
                 for (;;) {                  for (;;) {
                         if (packet_timeout_ms != -1) {                          if (active_state->packet_timeout_ms != -1) {
                                 ms_to_timeval(&timeout, ms_remain);                                  ms_to_timeval(&timeout, ms_remain);
                                 gettimeofday(&start, NULL);                                  gettimeofday(&start, NULL);
                         }                          }
                         if ((ret = select(connection_in + 1, setp, NULL,                          if ((ret = select(active_state->connection_in + 1, setp,
                             NULL, timeoutp)) >= 0)                              NULL, NULL, timeoutp)) >= 0)
                                 break;                                  break;
                         if (errno != EAGAIN && errno != EINTR)                          if (errno != EAGAIN && errno != EINTR)
                                 break;                                  break;
                         if (packet_timeout_ms == -1)                          if (active_state->packet_timeout_ms == -1)
                                 continue;                                  continue;
                         ms_subtract_diff(&start, &ms_remain);                          ms_subtract_diff(&start, &ms_remain);
                         if (ms_remain <= 0) {                          if (ms_remain <= 0) {
Line 1011 
Line 1062 
                         cleanup_exit(255);                          cleanup_exit(255);
                 }                  }
                 /* Read data from the socket. */                  /* Read data from the socket. */
                 len = read(connection_in, buf, sizeof(buf));                  len = read(active_state->connection_in, buf, sizeof(buf));
                 if (len == 0) {                  if (len == 0) {
                         logit("Connection closed by %.200s", get_remote_ipaddr());                          logit("Connection closed by %.200s", get_remote_ipaddr());
                         cleanup_exit(255);                          cleanup_exit(255);
Line 1063 
Line 1114 
         u_int checksum, stored_checksum;          u_int checksum, stored_checksum;
   
         /* Check if input size is less than minimum packet size. */          /* Check if input size is less than minimum packet size. */
         if (buffer_len(&input) < 4 + 8)          if (buffer_len(&active_state->input) < 4 + 8)
                 return SSH_MSG_NONE;                  return SSH_MSG_NONE;
         /* Get length of incoming packet. */          /* Get length of incoming packet. */
         cp = buffer_ptr(&input);          cp = buffer_ptr(&active_state->input);
         len = get_u32(cp);          len = get_u32(cp);
         if (len < 1 + 2 + 2 || len > 256 * 1024)          if (len < 1 + 2 + 2 || len > 256 * 1024)
                 packet_disconnect("Bad packet length %u.", len);                  packet_disconnect("Bad packet length %u.", len);
         padded_len = (len + 8) & ~7;          padded_len = (len + 8) & ~7;
   
         /* Check if the packet has been entirely received. */          /* Check if the packet has been entirely received. */
         if (buffer_len(&input) < 4 + padded_len)          if (buffer_len(&active_state->input) < 4 + padded_len)
                 return SSH_MSG_NONE;                  return SSH_MSG_NONE;
   
         /* The entire packet is in buffer. */          /* The entire packet is in buffer. */
   
         /* Consume packet length. */          /* Consume packet length. */
         buffer_consume(&input, 4);          buffer_consume(&active_state->input, 4);
   
         /*          /*
          * Cryptographic attack detector for ssh           * Cryptographic attack detector for ssh
          * (C)1998 CORE-SDI, Buenos Aires Argentina           * (C)1998 CORE-SDI, Buenos Aires Argentina
          * Ariel Futoransky(futo@core-sdi.com)           * Ariel Futoransky(futo@core-sdi.com)
          */           */
         if (!receive_context.plaintext) {          if (!active_state->receive_context.plaintext) {
                 switch (detect_attack(buffer_ptr(&input), padded_len)) {                  switch (detect_attack(buffer_ptr(&active_state->input),
                       padded_len)) {
                 case DEATTACK_DETECTED:                  case DEATTACK_DETECTED:
                         packet_disconnect("crc32 compensation attack: "                          packet_disconnect("crc32 compensation attack: "
                             "network attack detected");                              "network attack detected");
Line 1098 
Line 1150 
         }          }
   
         /* Decrypt data to incoming_packet. */          /* Decrypt data to incoming_packet. */
         buffer_clear(&incoming_packet);          buffer_clear(&active_state->incoming_packet);
         cp = buffer_append_space(&incoming_packet, padded_len);          cp = buffer_append_space(&active_state->incoming_packet, padded_len);
         cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);          cipher_crypt(&active_state->receive_context, cp,
               buffer_ptr(&active_state->input), padded_len);
   
         buffer_consume(&input, padded_len);          buffer_consume(&active_state->input, padded_len);
   
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "read_poll plain: ");          fprintf(stderr, "read_poll plain: ");
         buffer_dump(&incoming_packet);          buffer_dump(&active_state->incoming_packet);
 #endif  #endif
   
         /* Compute packet checksum. */          /* Compute packet checksum. */
         checksum = ssh_crc32(buffer_ptr(&incoming_packet),          checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
             buffer_len(&incoming_packet) - 4);              buffer_len(&active_state->incoming_packet) - 4);
   
         /* Skip padding. */          /* Skip padding. */
         buffer_consume(&incoming_packet, 8 - len % 8);          buffer_consume(&active_state->incoming_packet, 8 - len % 8);
   
         /* Test check bytes. */          /* Test check bytes. */
         if (len != buffer_len(&incoming_packet))          if (len != buffer_len(&active_state->incoming_packet))
                 packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",                  packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
                     len, buffer_len(&incoming_packet));                      len, buffer_len(&active_state->incoming_packet));
   
         cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;          cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
         stored_checksum = get_u32(cp);          stored_checksum = get_u32(cp);
         if (checksum != stored_checksum)          if (checksum != stored_checksum)
                 packet_disconnect("Corrupted check bytes on input.");                  packet_disconnect("Corrupted check bytes on input.");
         buffer_consume_end(&incoming_packet, 4);          buffer_consume_end(&active_state->incoming_packet, 4);
   
         if (packet_compression) {          if (active_state->packet_compression) {
                 buffer_clear(&compression_buffer);                  buffer_clear(&active_state->compression_buffer);
                 buffer_uncompress(&incoming_packet, &compression_buffer);                  buffer_uncompress(&active_state->incoming_packet,
                 buffer_clear(&incoming_packet);                      &active_state->compression_buffer);
                 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),                  buffer_clear(&active_state->incoming_packet);
                     buffer_len(&compression_buffer));                  buffer_append(&active_state->incoming_packet,
                       buffer_ptr(&active_state->compression_buffer),
                       buffer_len(&active_state->compression_buffer));
         }          }
         p_read.packets++;          active_state->p_read.packets++;
         p_read.bytes += padded_len + 4;          active_state->p_read.bytes += padded_len + 4;
         type = buffer_get_char(&incoming_packet);          type = buffer_get_char(&active_state->incoming_packet);
         if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)          if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
                 packet_disconnect("Invalid ssh1 packet type: %d", type);                  packet_disconnect("Invalid ssh1 packet type: %d", type);
         return type;          return type;
Line 1145 
Line 1200 
 static int  static int
 packet_read_poll2(u_int32_t *seqnr_p)  packet_read_poll2(u_int32_t *seqnr_p)
 {  {
         static u_int packet_length = 0;  
         u_int padlen, need;          u_int padlen, need;
         u_char *macbuf, *cp, type;          u_char *macbuf, *cp, type;
         u_int maclen, block_size;          u_int maclen, block_size;
Line 1153 
Line 1207 
         Mac *mac   = NULL;          Mac *mac   = NULL;
         Comp *comp = NULL;          Comp *comp = NULL;
   
         if (packet_discard)          if (active_state->packet_discard)
                 return SSH_MSG_NONE;                  return SSH_MSG_NONE;
   
         if (newkeys[MODE_IN] != NULL) {          if (active_state->newkeys[MODE_IN] != NULL) {
                 enc  = &newkeys[MODE_IN]->enc;                  enc  = &active_state->newkeys[MODE_IN]->enc;
                 mac  = &newkeys[MODE_IN]->mac;                  mac  = &active_state->newkeys[MODE_IN]->mac;
                 comp = &newkeys[MODE_IN]->comp;                  comp = &active_state->newkeys[MODE_IN]->comp;
         }          }
         maclen = mac && mac->enabled ? mac->mac_len : 0;          maclen = mac && mac->enabled ? mac->mac_len : 0;
         block_size = enc ? enc->block_size : 8;          block_size = enc ? enc->block_size : 8;
   
         if (packet_length == 0) {          if (active_state->packlen == 0) {
                 /*                  /*
                  * check if input size is less than the cipher block size,                   * check if input size is less than the cipher block size,
                  * decrypt first block and extract length of incoming packet                   * decrypt first block and extract length of incoming packet
                  */                   */
                 if (buffer_len(&input) < block_size)                  if (buffer_len(&active_state->input) < block_size)
                         return SSH_MSG_NONE;                          return SSH_MSG_NONE;
                 buffer_clear(&incoming_packet);                  buffer_clear(&active_state->incoming_packet);
                 cp = buffer_append_space(&incoming_packet, block_size);                  cp = buffer_append_space(&active_state->incoming_packet,
                 cipher_crypt(&receive_context, cp, buffer_ptr(&input),  
                     block_size);                      block_size);
                 cp = buffer_ptr(&incoming_packet);                  cipher_crypt(&active_state->receive_context, cp,
                 packet_length = get_u32(cp);                      buffer_ptr(&active_state->input), block_size);
                 if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {                  cp = buffer_ptr(&active_state->incoming_packet);
                   active_state->packlen = get_u32(cp);
                   if (active_state->packlen < 1 + 4 ||
                       active_state->packlen > PACKET_MAX_SIZE) {
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
                         buffer_dump(&incoming_packet);                          buffer_dump(&active_state->incoming_packet);
 #endif  #endif
                         logit("Bad packet length %u.", packet_length);                          logit("Bad packet length %u.", active_state->packlen);
                         packet_start_discard(enc, mac, packet_length,                          packet_start_discard(enc, mac, active_state->packlen,
                             PACKET_MAX_SIZE);                              PACKET_MAX_SIZE);
                         return SSH_MSG_NONE;                          return SSH_MSG_NONE;
                 }                  }
                 DBG(debug("input: packet len %u", packet_length+4));                  DBG(debug("input: packet len %u", active_state->packlen+4));
                 buffer_consume(&input, block_size);                  buffer_consume(&active_state->input, block_size);
         }          }
         /* we have a partial packet of block_size bytes */          /* we have a partial packet of block_size bytes */
         need = 4 + packet_length - block_size;          need = 4 + active_state->packlen - block_size;
         DBG(debug("partial packet %d, need %d, maclen %d", block_size,          DBG(debug("partial packet %d, need %d, maclen %d", block_size,
             need, maclen));              need, maclen));
         if (need % block_size != 0) {          if (need % block_size != 0) {
                 logit("padding error: need %d block %d mod %d",                  logit("padding error: need %d block %d mod %d",
                     need, block_size, need % block_size);                      need, block_size, need % block_size);
                 packet_start_discard(enc, mac, packet_length,                  packet_start_discard(enc, mac, active_state->packlen,
                     PACKET_MAX_SIZE - block_size);                      PACKET_MAX_SIZE - block_size);
                 return SSH_MSG_NONE;                  return SSH_MSG_NONE;
         }          }
Line 1204 
Line 1260 
          * check if the entire packet has been received and           * check if the entire packet has been received and
          * decrypt into incoming_packet           * decrypt into incoming_packet
          */           */
         if (buffer_len(&input) < need + maclen)          if (buffer_len(&active_state->input) < need + maclen)
                 return SSH_MSG_NONE;                  return SSH_MSG_NONE;
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "read_poll enc/full: ");          fprintf(stderr, "read_poll enc/full: ");
         buffer_dump(&input);          buffer_dump(&active_state->input);
 #endif  #endif
         cp = buffer_append_space(&incoming_packet, need);          cp = buffer_append_space(&active_state->incoming_packet, need);
         cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);          cipher_crypt(&active_state->receive_context, cp,
         buffer_consume(&input, need);              buffer_ptr(&active_state->input), need);
           buffer_consume(&active_state->input, need);
         /*          /*
          * compute MAC over seqnr and packet,           * compute MAC over seqnr and packet,
          * increment sequence number for incoming packet           * increment sequence number for incoming packet
          */           */
         if (mac && mac->enabled) {          if (mac && mac->enabled) {
                 macbuf = mac_compute(mac, p_read.seqnr,                  macbuf = mac_compute(mac, active_state->p_read.seqnr,
                     buffer_ptr(&incoming_packet),                      buffer_ptr(&active_state->incoming_packet),
                     buffer_len(&incoming_packet));                      buffer_len(&active_state->incoming_packet));
                 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {                  if (memcmp(macbuf, buffer_ptr(&active_state->input),
                       mac->mac_len) != 0) {
                         logit("Corrupted MAC on input.");                          logit("Corrupted MAC on input.");
                         if (need > PACKET_MAX_SIZE)                          if (need > PACKET_MAX_SIZE)
                                 fatal("internal error need %d", need);                                  fatal("internal error need %d", need);
                         packet_start_discard(enc, mac, packet_length,                          packet_start_discard(enc, mac, active_state->packlen,
                             PACKET_MAX_SIZE - need);                              PACKET_MAX_SIZE - need);
                         return SSH_MSG_NONE;                          return SSH_MSG_NONE;
                 }                  }
   
                 DBG(debug("MAC #%d ok", p_read.seqnr));                  DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
                 buffer_consume(&input, mac->mac_len);                  buffer_consume(&active_state->input, mac->mac_len);
         }          }
         /* XXX now it's safe to use fatal/packet_disconnect */          /* XXX now it's safe to use fatal/packet_disconnect */
         if (seqnr_p != NULL)          if (seqnr_p != NULL)
                 *seqnr_p = p_read.seqnr;                  *seqnr_p = active_state->p_read.seqnr;
         if (++p_read.seqnr == 0)          if (++active_state->p_read.seqnr == 0)
                 logit("incoming seqnr wraps around");                  logit("incoming seqnr wraps around");
         if (++p_read.packets == 0)          if (++active_state->p_read.packets == 0)
                 if (!(datafellows & SSH_BUG_NOREKEY))                  if (!(datafellows & SSH_BUG_NOREKEY))
                         fatal("XXX too many packets with same key");                          fatal("XXX too many packets with same key");
         p_read.blocks += (packet_length + 4) / block_size;          active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
         p_read.bytes += packet_length + 4;          active_state->p_read.bytes += active_state->packlen + 4;
   
         /* get padlen */          /* get padlen */
         cp = buffer_ptr(&incoming_packet);          cp = buffer_ptr(&active_state->incoming_packet);
         padlen = cp[4];          padlen = cp[4];
         DBG(debug("input: padlen %d", padlen));          DBG(debug("input: padlen %d", padlen));
         if (padlen < 4)          if (padlen < 4)
                 packet_disconnect("Corrupted padlen %d on input.", padlen);                  packet_disconnect("Corrupted padlen %d on input.", padlen);
   
         /* skip packet size + padlen, discard padding */          /* skip packet size + padlen, discard padding */
         buffer_consume(&incoming_packet, 4 + 1);          buffer_consume(&active_state->incoming_packet, 4 + 1);
         buffer_consume_end(&incoming_packet, padlen);          buffer_consume_end(&active_state->incoming_packet, padlen);
   
         DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));          DBG(debug("input: len before de-compress %d",
               buffer_len(&active_state->incoming_packet)));
         if (comp && comp->enabled) {          if (comp && comp->enabled) {
                 buffer_clear(&compression_buffer);                  buffer_clear(&active_state->compression_buffer);
                 buffer_uncompress(&incoming_packet, &compression_buffer);                  buffer_uncompress(&active_state->incoming_packet,
                 buffer_clear(&incoming_packet);                      &active_state->compression_buffer);
                 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),                  buffer_clear(&active_state->incoming_packet);
                     buffer_len(&compression_buffer));                  buffer_append(&active_state->incoming_packet,
                       buffer_ptr(&active_state->compression_buffer),
                       buffer_len(&active_state->compression_buffer));
                 DBG(debug("input: len after de-compress %d",                  DBG(debug("input: len after de-compress %d",
                     buffer_len(&incoming_packet)));                      buffer_len(&active_state->incoming_packet)));
         }          }
         /*          /*
          * get packet type, implies consume.           * get packet type, implies consume.
          * return length of payload (without type field)           * return length of payload (without type field)
          */           */
         type = buffer_get_char(&incoming_packet);          type = buffer_get_char(&active_state->incoming_packet);
         if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)          if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
                 packet_disconnect("Invalid ssh2 packet type: %d", type);                  packet_disconnect("Invalid ssh2 packet type: %d", type);
         if (type == SSH2_MSG_NEWKEYS)          if (type == SSH2_MSG_NEWKEYS)
                 set_newkeys(MODE_IN);                  set_newkeys(MODE_IN);
         else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)          else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
               !active_state->server_side)
                 packet_enable_delayed_compress();                  packet_enable_delayed_compress();
 #ifdef PACKET_DEBUG  #ifdef PACKET_DEBUG
         fprintf(stderr, "read/plain[%d]:\r\n", type);          fprintf(stderr, "read/plain[%d]:\r\n", type);
         buffer_dump(&incoming_packet);          buffer_dump(&active_state->incoming_packet);
 #endif  #endif
         /* reset for next packet */          /* reset for next packet */
         packet_length = 0;          active_state->packlen = 0;
         return type;          return type;
 }  }
   
Line 1296 
Line 1358 
                 if (compat20) {                  if (compat20) {
                         type = packet_read_poll2(seqnr_p);                          type = packet_read_poll2(seqnr_p);
                         if (type) {                          if (type) {
                                 keep_alive_timeouts = 0;                                  active_state->keep_alive_timeouts = 0;
                                 DBG(debug("received packet type %d", type));                                  DBG(debug("received packet type %d", type));
                         }                          }
                         switch (type) {                          switch (type) {
Line 1366 
Line 1428 
 void  void
 packet_process_incoming(const char *buf, u_int len)  packet_process_incoming(const char *buf, u_int len)
 {  {
         if (packet_discard) {          if (active_state->packet_discard) {
                 keep_alive_timeouts = 0; /* ?? */                  active_state->keep_alive_timeouts = 0; /* ?? */
                 if (len >= packet_discard)                  if (len >= active_state->packet_discard)
                         packet_stop_discard();                          packet_stop_discard();
                 packet_discard -= len;                  active_state->packet_discard -= len;
                 return;                  return;
         }          }
         buffer_append(&input, buf, len);          buffer_append(&active_state->input, buf, len);
 }  }
   
 /* Returns a character from the packet. */  /* Returns a character from the packet. */
Line 1383 
Line 1445 
 {  {
         char ch;          char ch;
   
         buffer_get(&incoming_packet, &ch, 1);          buffer_get(&active_state->incoming_packet, &ch, 1);
         return (u_char) ch;          return (u_char) ch;
 }  }
   
Line 1392 
Line 1454 
 u_int  u_int
 packet_get_int(void)  packet_get_int(void)
 {  {
         return buffer_get_int(&incoming_packet);          return buffer_get_int(&active_state->incoming_packet);
 }  }
   
 /*  /*
Line 1403 
Line 1465 
 void  void
 packet_get_bignum(BIGNUM * value)  packet_get_bignum(BIGNUM * value)
 {  {
         buffer_get_bignum(&incoming_packet, value);          buffer_get_bignum(&active_state->incoming_packet, value);
 }  }
   
 void  void
 packet_get_bignum2(BIGNUM * value)  packet_get_bignum2(BIGNUM * value)
 {  {
         buffer_get_bignum2(&incoming_packet, value);          buffer_get_bignum2(&active_state->incoming_packet, value);
 }  }
   
 void *  void *
 packet_get_raw(u_int *length_ptr)  packet_get_raw(u_int *length_ptr)
 {  {
         u_int bytes = buffer_len(&incoming_packet);          u_int bytes = buffer_len(&active_state->incoming_packet);
   
         if (length_ptr != NULL)          if (length_ptr != NULL)
                 *length_ptr = bytes;                  *length_ptr = bytes;
         return buffer_ptr(&incoming_packet);          return buffer_ptr(&active_state->incoming_packet);
 }  }
   
 int  int
 packet_remaining(void)  packet_remaining(void)
 {  {
         return buffer_len(&incoming_packet);          return buffer_len(&active_state->incoming_packet);
 }  }
   
 /*  /*
Line 1438 
Line 1500 
 void *  void *
 packet_get_string(u_int *length_ptr)  packet_get_string(u_int *length_ptr)
 {  {
         return buffer_get_string(&incoming_packet, length_ptr);          return buffer_get_string(&active_state->incoming_packet, length_ptr);
 }  }
   
 void *  void *
 packet_get_string_ptr(u_int *length_ptr)  packet_get_string_ptr(u_int *length_ptr)
 {  {
         return buffer_get_string_ptr(&incoming_packet, length_ptr);          return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
 }  }
   
 /*  /*
Line 1537 
Line 1599 
 void  void
 packet_write_poll(void)  packet_write_poll(void)
 {  {
         int len = buffer_len(&output);          int len = buffer_len(&active_state->output);
   
         if (len > 0) {          if (len > 0) {
                 len = write(connection_out, buffer_ptr(&output), len);                  len = write(active_state->connection_out,
                       buffer_ptr(&active_state->output), len);
                 if (len == -1) {                  if (len == -1) {
                         if (errno == EINTR || errno == EAGAIN)                          if (errno == EINTR || errno == EAGAIN)
                                 return;                                  return;
Line 1548 
Line 1611 
                 }                  }
                 if (len == 0)                  if (len == 0)
                         fatal("Write connection closed");                          fatal("Write connection closed");
                 buffer_consume(&output, len);                  buffer_consume(&active_state->output, len);
         }          }
 }  }
   
Line 1564 
Line 1627 
         int ret, ms_remain;          int ret, ms_remain;
         struct timeval start, timeout, *timeoutp = NULL;          struct timeval start, timeout, *timeoutp = NULL;
   
         setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),          setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
             sizeof(fd_mask));              NFDBITS), sizeof(fd_mask));
         packet_write_poll();          packet_write_poll();
         while (packet_have_data_to_write()) {          while (packet_have_data_to_write()) {
                 memset(setp, 0, howmany(connection_out + 1, NFDBITS) *                  memset(setp, 0, howmany(active_state->connection_out + 1,
                     sizeof(fd_mask));                      NFDBITS) * sizeof(fd_mask));
                 FD_SET(connection_out, setp);                  FD_SET(active_state->connection_out, setp);
   
                 if (packet_timeout_ms > 0) {                  if (active_state->packet_timeout_ms > 0) {
                         ms_remain = packet_timeout_ms;                          ms_remain = active_state->packet_timeout_ms;
                         timeoutp = &timeout;                          timeoutp = &timeout;
                 }                  }
                 for (;;) {                  for (;;) {
                         if (packet_timeout_ms != -1) {                          if (active_state->packet_timeout_ms != -1) {
                                 ms_to_timeval(&timeout, ms_remain);                                  ms_to_timeval(&timeout, ms_remain);
                                 gettimeofday(&start, NULL);                                  gettimeofday(&start, NULL);
                         }                          }
                         if ((ret = select(connection_out + 1, NULL, setp,                          if ((ret = select(active_state->connection_out + 1,
                             NULL, timeoutp)) >= 0)                              NULL, setp, NULL, timeoutp)) >= 0)
                                 break;                                  break;
                         if (errno != EAGAIN && errno != EINTR)                          if (errno != EAGAIN && errno != EINTR)
                                 break;                                  break;
                         if (packet_timeout_ms == -1)                          if (active_state->packet_timeout_ms == -1)
                                 continue;                                  continue;
                         ms_subtract_diff(&start, &ms_remain);                          ms_subtract_diff(&start, &ms_remain);
                         if (ms_remain <= 0) {                          if (ms_remain <= 0) {
Line 1609 
Line 1672 
 int  int
 packet_have_data_to_write(void)  packet_have_data_to_write(void)
 {  {
         return buffer_len(&output) != 0;          return buffer_len(&active_state->output) != 0;
 }  }
   
 /* Returns true if there is not too much data to write to the connection. */  /* Returns true if there is not too much data to write to the connection. */
Line 1617 
Line 1680 
 int  int
 packet_not_very_much_data_to_write(void)  packet_not_very_much_data_to_write(void)
 {  {
         if (interactive_mode)          if (active_state->interactive_mode)
                 return buffer_len(&output) < 16384;                  return buffer_len(&active_state->output) < 16384;
         else          else
                 return buffer_len(&output) < 128 * 1024;                  return buffer_len(&active_state->output) < 128 * 1024;
 }  }
   
 static void  static void
Line 1631 
Line 1694 
         if (!packet_connection_is_on_socket() ||          if (!packet_connection_is_on_socket() ||
             !packet_connection_is_ipv4())              !packet_connection_is_ipv4())
                 return;                  return;
         if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,          if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
             sizeof(tos)) < 0)              sizeof(tos)) < 0)
                 error("setsockopt IP_TOS %d: %.100s:",                  error("setsockopt IP_TOS %d: %.100s:",
                     tos, strerror(errno));                      tos, strerror(errno));
Line 1649 
Line 1712 
         called = 1;          called = 1;
   
         /* Record that we are in interactive mode. */          /* Record that we are in interactive mode. */
         interactive_mode = interactive;          active_state->interactive_mode = interactive;
   
         /* Only set socket options if using a socket.  */          /* Only set socket options if using a socket.  */
         if (!packet_connection_is_on_socket())          if (!packet_connection_is_on_socket())
                 return;                  return;
         set_nodelay(connection_in);          set_nodelay(active_state->connection_in);
         packet_set_tos(interactive);          packet_set_tos(interactive);
 }  }
   
Line 1663 
Line 1726 
 int  int
 packet_is_interactive(void)  packet_is_interactive(void)
 {  {
         return interactive_mode;          return active_state->interactive_mode;
 }  }
   
 int  int
Line 1673 
Line 1736 
   
         if (called) {          if (called) {
                 logit("packet_set_maxsize: called twice: old %d new %d",                  logit("packet_set_maxsize: called twice: old %d new %d",
                     max_packet_size, s);                      active_state->max_packet_size, s);
                 return -1;                  return -1;
         }          }
         if (s < 4 * 1024 || s > 1024 * 1024) {          if (s < 4 * 1024 || s > 1024 * 1024) {
Line 1682 
Line 1745 
         }          }
         called = 1;          called = 1;
         debug("packet_set_maxsize: setting to %d", s);          debug("packet_set_maxsize: setting to %d", s);
         max_packet_size = s;          active_state->max_packet_size = s;
         return s;          return s;
 }  }
   
   int
   packet_inc_alive_timeouts(void)
   {
           return ++active_state->keep_alive_timeouts;
   }
   
   void
   packet_set_alive_timeouts(int ka)
   {
           active_state->keep_alive_timeouts = ka;
   }
   
   u_int
   packet_get_maxsize(void)
   {
           return active_state->max_packet_size;
   }
   
 /* roundup current message to pad bytes */  /* roundup current message to pad bytes */
 void  void
 packet_add_padding(u_char pad)  packet_add_padding(u_char pad)
 {  {
         extra_pad = pad;          active_state->extra_pad = pad;
 }  }
   
 /*  /*
Line 1727 
Line 1808 
         if (datafellows & SSH_BUG_NOREKEY)          if (datafellows & SSH_BUG_NOREKEY)
                 return 0;                  return 0;
         return          return
             (p_send.packets > MAX_PACKETS) ||              (active_state->p_send.packets > MAX_PACKETS) ||
             (p_read.packets > MAX_PACKETS) ||              (active_state->p_read.packets > MAX_PACKETS) ||
             (max_blocks_out && (p_send.blocks > max_blocks_out)) ||              (active_state->max_blocks_out &&
             (max_blocks_in  && (p_read.blocks > max_blocks_in));                  (active_state->p_send.blocks > active_state->max_blocks_out)) ||
               (active_state->max_blocks_in &&
                   (active_state->p_read.blocks > active_state->max_blocks_in));
 }  }
   
 void  void
 packet_set_rekey_limit(u_int32_t bytes)  packet_set_rekey_limit(u_int32_t bytes)
 {  {
         rekey_limit = bytes;          active_state->rekey_limit = bytes;
 }  }
   
 void  void
 packet_set_server(void)  packet_set_server(void)
 {  {
         server_side = 1;          active_state->server_side = 1;
 }  }
   
 void  void
 packet_set_authenticated(void)  packet_set_authenticated(void)
 {  {
         after_authentication = 1;          active_state->after_authentication = 1;
   }
   
   void *
   packet_get_input(void)
   {
           return (void *)&active_state->input;
   }
   
   void *
   packet_get_output(void)
   {
           return (void *)&active_state->output;
   }
   
   void *
   packet_get_newkeys(int mode)
   {
           return (void *)active_state->newkeys[mode];
 }  }

Legend:
Removed from v.1.160  
changed lines
  Added in v.1.161