[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.103 and 1.104

version 1.103, 2003/04/01 10:10:23 version 1.104, 2003/04/01 10:22:21
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 118 
Line 116 
   
 /* Session key information for Encryption and MAC */  /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];  Newkeys *newkeys[MODE_MAX];
 static struct packet_state {  static u_int32_t read_seqnr = 0;
         u_int32_t seqnr;  static u_int32_t send_seqnr = 0;
         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 134 
Line 126 
 /* 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 163 
Line 148 
                 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 270 
Line 254 
         return (cipher_get_number(receive_context.cipher));          return (cipher_get_number(receive_context.cipher));
 }  }
   
 void  
 packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)  
 {  
         struct packet_state *state;  
   
         state = (mode == MODE_IN) ? &p_read : &p_send;  u_int32_t
         *seqnr = state->seqnr;  packet_get_seqnr(int mode)
         *blocks = state->blocks;  {
         *packets = state->packets;          return (mode == MODE_IN ? read_seqnr : send_seqnr);
 }  }
   
 void  void
 packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)  packet_set_seqnr(int mode, u_int32_t seqnr)
 {  {
         struct packet_state *state;          if (mode == MODE_IN)
                   read_seqnr = seqnr;
         state = (mode == MODE_IN) ? &p_read : &p_send;          else if (mode == MODE_OUT)
         state->seqnr = seqnr;                  send_seqnr = seqnr;
         state->blocks = blocks;          else
         state->packets = packets;                  fatal("packet_set_seqnr: bad mode %d", mode);
 }  }
   
 /* returns 1 if connection is via ipv4 */  /* returns 1 if connection is via ipv4 */
Line 577 
Line 557 
         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 585 
Line 564 
         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 630 
Line 605 
                         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_wrapped(void)  packet_send2(void)
 {  {
         u_char type, *cp, *macbuf = NULL;          u_char type, *cp, *macbuf = NULL;
         u_char padlen, pad;          u_char padlen, pad;
Line 721 
Line 693 
   
         /* 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, 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", p_send.seqnr));                  DBG(debug("done calc MAC out #%d", 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 738 
Line 710 
         buffer_dump(&output);          buffer_dump(&output);
 #endif  #endif
         /* increment sequence number for outgoing packets */          /* increment sequence number for outgoing packets */
         if (++p_send.seqnr == 0)          if (++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 1039 
Line 961 
          * 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, 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", p_read.seqnr));                  DBG(debug("MAC #%d ok", read_seqnr));
                 buffer_consume(&input, mac->mac_len);                  buffer_consume(&input, mac->mac_len);
         }          }
         if (seqnr_p != NULL)          if (seqnr_p != NULL)
                 *seqnr_p = p_read.seqnr;                  *seqnr_p = read_seqnr;
         if (++p_read.seqnr == 0)          if (++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 1487 
Line 1405 
                 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.103  
changed lines
  Added in v.1.104