[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.102 and 1.103

version 1.102, 2002/12/10 19:47:14 version 1.103, 2003/04/01 10:10:23
Line 39 
Line 39 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
   #include <sys/queue.h>
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "buffer.h"  #include "buffer.h"
 #include "packet.h"  #include "packet.h"
Line 116 
Line 118 
   
 /* Session key information for Encryption and MAC */  /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];  Newkeys *newkeys[MODE_MAX];
 static u_int32_t read_seqnr = 0;  static struct packet_state {
 static u_int32_t send_seqnr = 0;          u_int32_t seqnr;
           u_int32_t packets;
           u_int64_t blocks;
   } p_read, p_send;
   
   static u_int64_t max_blocks_in, max_blocks_out;
   static u_int32_t rekey_limit;
   
 /* Session key for protocol v1 */  /* Session key for protocol v1 */
 static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];  static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
 static u_int ssh1_keylen;  static u_int ssh1_keylen;
Line 126 
Line 134 
 /* roundup current message to extra_pad bytes */  /* roundup current message to extra_pad bytes */
 static u_char extra_pad = 0;  static u_char extra_pad = 0;
   
   struct packet {
           TAILQ_ENTRY(packet) next;
           u_char type;
           Buffer payload;
   };
   TAILQ_HEAD(, packet) outgoing;
   
 /*  /*
  * 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 148 
Line 163 
                 buffer_init(&output);                  buffer_init(&output);
                 buffer_init(&outgoing_packet);                  buffer_init(&outgoing_packet);
                 buffer_init(&incoming_packet);                  buffer_init(&incoming_packet);
                   TAILQ_INIT(&outgoing);
         }          }
         /* Kludge: arrange the close function to be called from fatal(). */          /* Kludge: arrange the close function to be called from fatal(). */
         fatal_add_cleanup((void (*) (void *)) packet_close, NULL);          fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
Line 254 
Line 270 
         return (cipher_get_number(receive_context.cipher));          return (cipher_get_number(receive_context.cipher));
 }  }
   
   void
 u_int32_t  packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)
 packet_get_seqnr(int mode)  
 {  {
         return (mode == MODE_IN ? read_seqnr : send_seqnr);          struct packet_state *state;
   
           state = (mode == MODE_IN) ? &p_read : &p_send;
           *seqnr = state->seqnr;
           *blocks = state->blocks;
           *packets = state->packets;
 }  }
   
 void  void
 packet_set_seqnr(int mode, u_int32_t seqnr)  packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)
 {  {
         if (mode == MODE_IN)          struct packet_state *state;
                 read_seqnr = seqnr;  
         else if (mode == MODE_OUT)          state = (mode == MODE_IN) ? &p_read : &p_send;
                 send_seqnr = seqnr;          state->seqnr = seqnr;
         else          state->blocks = blocks;
                 fatal("packet_set_seqnr: bad mode %d", mode);          state->packets = packets;
 }  }
   
 /* returns 1 if connection is via ipv4 */  /* returns 1 if connection is via ipv4 */
Line 557 
Line 577 
         Mac *mac;          Mac *mac;
         Comp *comp;          Comp *comp;
         CipherContext *cc;          CipherContext *cc;
           u_int64_t *max_blocks;
         int encrypt;          int encrypt;
   
         debug2("set_newkeys: mode %d", mode);          debug2("set_newkeys: mode %d", mode);
Line 564 
Line 585 
         if (mode == MODE_OUT) {          if (mode == MODE_OUT) {
                 cc = &send_context;                  cc = &send_context;
                 encrypt = CIPHER_ENCRYPT;                  encrypt = CIPHER_ENCRYPT;
                   p_send.packets = p_send.blocks = 0;
                   max_blocks = &max_blocks_out;
         } else {          } else {
                 cc = &receive_context;                  cc = &receive_context;
                 encrypt = CIPHER_DECRYPT;                  encrypt = CIPHER_DECRYPT;
                   p_read.packets = p_read.blocks = 0;
                   max_blocks = &max_blocks_in;
         }          }
         if (newkeys[mode] != NULL) {          if (newkeys[mode] != NULL) {
                 debug("set_newkeys: rekeying");                  debug("set_newkeys: rekeying");
Line 605 
Line 630 
                         buffer_compress_init_recv();                          buffer_compress_init_recv();
                 comp->enabled = 1;                  comp->enabled = 1;
         }          }
           *max_blocks = ((u_int64_t)1 << (enc->block_size*2));
           if (rekey_limit)
                   *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
 }  }
   
 /*  /*
  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)   * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
  */   */
 static void  static void
 packet_send2(void)  packet_send2_wrapped(void)
 {  {
         u_char type, *cp, *macbuf = NULL;          u_char type, *cp, *macbuf = NULL;
         u_char padlen, pad;          u_char padlen, pad;
Line 693 
Line 721 
   
         /* 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, send_seqnr,                  macbuf = mac_compute(mac, p_send.seqnr,
                     buffer_ptr(&outgoing_packet),                      buffer_ptr(&outgoing_packet),
                     buffer_len(&outgoing_packet));                      buffer_len(&outgoing_packet));
                 DBG(debug("done calc MAC out #%d", send_seqnr));                  DBG(debug("done calc MAC out #%d", 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(&output, buffer_len(&outgoing_packet));
Line 710 
Line 738 
         buffer_dump(&output);          buffer_dump(&output);
 #endif  #endif
         /* increment sequence number for outgoing packets */          /* increment sequence number for outgoing packets */
         if (++send_seqnr == 0)          if (++p_send.seqnr == 0)
                 log("outgoing seqnr wraps around");                  log("outgoing seqnr wraps around");
           if (++p_send.packets == 0)
                   if (!(datafellows & SSH_BUG_NOREKEY))
                           fatal("XXX too many packets with same key");
           p_send.blocks += (packet_length + 4) / block_size;
         buffer_clear(&outgoing_packet);          buffer_clear(&outgoing_packet);
   
         if (type == SSH2_MSG_NEWKEYS)          if (type == SSH2_MSG_NEWKEYS)
                 set_newkeys(MODE_OUT);                  set_newkeys(MODE_OUT);
 }  }
   
   static void
   packet_send2(void)
   {
           static int rekeying = 0;
           struct packet *p;
           u_char type, *cp;
   
           cp = buffer_ptr(&outgoing_packet);
           type = cp[5];
   
           /* during rekeying we can only send key exchange messages */
           if (rekeying) {
                   if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
                       (type <= SSH2_MSG_TRANSPORT_MAX))) {
                           debug("enqueue packet: %u", type);
                           p = xmalloc(sizeof(*p));
                           p->type = type;
                           memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
                           buffer_init(&outgoing_packet);
                           TAILQ_INSERT_TAIL(&outgoing, p, next);
                           return;
                   }
           }
   
           /* rekeying starts with sending KEXINIT */
           if (type == SSH2_MSG_KEXINIT)
                   rekeying = 1;
   
           packet_send2_wrapped();
   
           /* after a NEWKEYS message we can send the complete queue */
           if (type == SSH2_MSG_NEWKEYS) {
                   rekeying = 0;
                   while ((p = TAILQ_FIRST(&outgoing))) {
                           type = p->type;
                           debug("dequeue packet: %u", type);
                           buffer_free(&outgoing_packet);
                           memcpy(&outgoing_packet, &p->payload,
                               sizeof(Buffer));
                           TAILQ_REMOVE(&outgoing, p, next);
                           xfree(p);
                           packet_send2_wrapped();
                   }
           }
   }
   
 void  void
 packet_send(void)  packet_send(void)
 {  {
Line 961 
Line 1039 
          * increment sequence number for incoming packet           * increment sequence number for incoming packet
          */           */
         if (mac && mac->enabled) {          if (mac && mac->enabled) {
                 macbuf = mac_compute(mac, read_seqnr,                  macbuf = mac_compute(mac, p_read.seqnr,
                     buffer_ptr(&incoming_packet),                      buffer_ptr(&incoming_packet),
                     buffer_len(&incoming_packet));                      buffer_len(&incoming_packet));
                 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)                  if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
                         packet_disconnect("Corrupted MAC on input.");                          packet_disconnect("Corrupted MAC on input.");
                 DBG(debug("MAC #%d ok", read_seqnr));                  DBG(debug("MAC #%d ok", p_read.seqnr));
                 buffer_consume(&input, mac->mac_len);                  buffer_consume(&input, mac->mac_len);
         }          }
         if (seqnr_p != NULL)          if (seqnr_p != NULL)
                 *seqnr_p = read_seqnr;                  *seqnr_p = p_read.seqnr;
         if (++read_seqnr == 0)          if (++p_read.seqnr == 0)
                 log("incoming seqnr wraps around");                  log("incoming seqnr wraps around");
           if (++p_read.packets == 0)
                   if (!(datafellows & SSH_BUG_NOREKEY))
                           fatal("XXX too many packets with same key");
           p_read.blocks += (packet_length + 4) / block_size;
   
         /* get padlen */          /* get padlen */
         cp = buffer_ptr(&incoming_packet);          cp = buffer_ptr(&incoming_packet);
Line 1405 
Line 1487 
                 packet_put_char(rand & 0xff);                  packet_put_char(rand & 0xff);
                 rand >>= 8;                  rand >>= 8;
         }          }
   }
   
   #define MAX_PACKETS     (1<<31)
   int
   packet_need_rekeying(void)
   {
           if (datafellows & SSH_BUG_NOREKEY)
                   return 0;
           return
               (p_send.packets > MAX_PACKETS) ||
               (p_read.packets > MAX_PACKETS) ||
               (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
               (max_blocks_in  && (p_read.blocks > max_blocks_in));
   }
   
   void
   packet_set_rekey_limit(u_int32_t bytes)
   {
           rekey_limit = bytes;
 }  }

Legend:
Removed from v.1.102  
changed lines
  Added in v.1.103