[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.256 and 1.257

version 1.256, 2017/05/08 06:03:39 version 1.257, 2017/05/31 08:09:45
Line 548 
Line 548 
   
 /* Closes the connection and clears and frees internal data structures. */  /* Closes the connection and clears and frees internal data structures. */
   
 void  static void
 ssh_packet_close(struct ssh *ssh)  ssh_packet_close_internal(struct ssh *ssh, int do_close)
 {  {
         struct session_state *state = ssh->state;          struct session_state *state = ssh->state;
         u_int mode;          u_int mode;
Line 557 
Line 557 
         if (!state->initialized)          if (!state->initialized)
                 return;                  return;
         state->initialized = 0;          state->initialized = 0;
         if (state->connection_in == state->connection_out) {          if (do_close) {
                 shutdown(state->connection_out, SHUT_RDWR);                  if (state->connection_in == state->connection_out) {
                 close(state->connection_out);                          shutdown(state->connection_out, SHUT_RDWR);
         } else {                          close(state->connection_out);
                 close(state->connection_in);                  } else {
                 close(state->connection_out);                          close(state->connection_in);
                           close(state->connection_out);
                   }
         }          }
         sshbuf_free(state->input);          sshbuf_free(state->input);
         sshbuf_free(state->output);          sshbuf_free(state->output);
         sshbuf_free(state->outgoing_packet);          sshbuf_free(state->outgoing_packet);
         sshbuf_free(state->incoming_packet);          sshbuf_free(state->incoming_packet);
         for (mode = 0; mode < MODE_MAX; mode++)          for (mode = 0; mode < MODE_MAX; mode++) {
                 kex_free_newkeys(state->newkeys[mode]);                  kex_free_newkeys(state->newkeys[mode]); /* current keys */
         if (state->compression_buffer) {                  state->newkeys[mode] = NULL;
                   ssh_clear_newkeys(ssh, mode);           /* next keys */
           }
           /* comression state is in shared mem, so we can only release it once */
           if (do_close && state->compression_buffer) {
                 sshbuf_free(state->compression_buffer);                  sshbuf_free(state->compression_buffer);
                 if (state->compression_out_started) {                  if (state->compression_out_started) {
                         z_streamp stream = &state->compression_out_stream;                          z_streamp stream = &state->compression_out_stream;
Line 598 
Line 604 
         cipher_free(state->send_context);          cipher_free(state->send_context);
         cipher_free(state->receive_context);          cipher_free(state->receive_context);
         state->send_context = state->receive_context = NULL;          state->send_context = state->receive_context = NULL;
         free(ssh->remote_ipaddr);          if (do_close) {
         ssh->remote_ipaddr = NULL;                  free(ssh->remote_ipaddr);
         free(ssh->state);                  ssh->remote_ipaddr = NULL;
         ssh->state = NULL;                  free(ssh->state);
                   ssh->state = NULL;
           }
 }  }
   
   void
   ssh_packet_close(struct ssh *ssh)
   {
           ssh_packet_close_internal(ssh, 1);
   }
   
   void
   ssh_packet_clear_keys(struct ssh *ssh)
   {
           ssh_packet_close_internal(ssh, 0);
   }
   
 /* Sets remote side protocol flags. */  /* Sets remote side protocol flags. */
   
 void  void
Line 780 
Line 800 
         /* NOTREACHED */          /* NOTREACHED */
 }  }
   
   void
   ssh_clear_newkeys(struct ssh *ssh, int mode)
   {
           if (ssh->kex && ssh->kex->newkeys) {
                   kex_free_newkeys(ssh->kex->newkeys[mode]);
                   ssh->kex->newkeys[mode] = NULL;
           }
   }
   
 int  int
 ssh_set_newkeys(struct ssh *ssh, int mode)  ssh_set_newkeys(struct ssh *ssh, int mode)
 {  {
Line 809 
Line 838 
                 max_blocks = &state->max_blocks_in;                  max_blocks = &state->max_blocks_in;
         }          }
         if (state->newkeys[mode] != NULL) {          if (state->newkeys[mode] != NULL) {
                 debug("%s: rekeying after %llu %s blocks"                  debug("set_newkeys: rekeying, input %llu bytes %llu blocks, "
                     " (%llu bytes total)", __func__,                     "output %llu bytes %llu blocks",
                     (unsigned long long)ps->blocks, dir,                     (unsigned long long)state->p_read.bytes,
                     (unsigned long long)ps->bytes);                     (unsigned long long)state->p_read.blocks,
                      (unsigned long long)state->p_send.bytes,
                      (unsigned long long)state->p_send.blocks);
                 cipher_free(*ccp);                  cipher_free(*ccp);
                 *ccp = NULL;                  *ccp = NULL;
                 enc  = &state->newkeys[mode]->enc;                  kex_free_newkeys(state->newkeys[mode]);
                 mac  = &state->newkeys[mode]->mac;                  state->newkeys[mode] = NULL;
                 comp = &state->newkeys[mode]->comp;  
                 mac_clear(mac);  
                 explicit_bzero(enc->iv,  enc->iv_len);  
                 explicit_bzero(enc->key, enc->key_len);  
                 explicit_bzero(mac->key, mac->key_len);  
                 free(enc->name);  
                 free(enc->iv);  
                 free(enc->key);  
                 free(mac->name);  
                 free(mac->key);  
                 free(comp->name);  
                 free(state->newkeys[mode]);  
         }          }
         /* note that both bytes and the seqnr are not reset */          /* note that both bytes and the seqnr are not reset */
         ps->packets = ps->blocks = 0;          ps->packets = ps->blocks = 0;
Line 1772 
Line 1791 
   
         switch (r) {          switch (r) {
         case SSH_ERR_CONN_CLOSED:          case SSH_ERR_CONN_CLOSED:
                   ssh_packet_clear_keys(ssh);
                 logdie("Connection closed by %s", remote_id);                  logdie("Connection closed by %s", remote_id);
         case SSH_ERR_CONN_TIMEOUT:          case SSH_ERR_CONN_TIMEOUT:
                   ssh_packet_clear_keys(ssh);
                 logdie("Connection %s %s timed out",                  logdie("Connection %s %s timed out",
                     ssh->state->server_side ? "from" : "to", remote_id);                      ssh->state->server_side ? "from" : "to", remote_id);
         case SSH_ERR_DISCONNECTED:          case SSH_ERR_DISCONNECTED:
                   ssh_packet_clear_keys(ssh);
                 logdie("Disconnected from %s", remote_id);                  logdie("Disconnected from %s", remote_id);
         case SSH_ERR_SYSTEM_ERROR:          case SSH_ERR_SYSTEM_ERROR:
                 if (errno == ECONNRESET)                  if (errno == ECONNRESET) {
                           ssh_packet_clear_keys(ssh);
                         logdie("Connection reset by %s", remote_id);                          logdie("Connection reset by %s", remote_id);
                   }
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case SSH_ERR_NO_CIPHER_ALG_MATCH:          case SSH_ERR_NO_CIPHER_ALG_MATCH:
         case SSH_ERR_NO_MAC_ALG_MATCH:          case SSH_ERR_NO_MAC_ALG_MATCH:
Line 1788 
Line 1812 
         case SSH_ERR_NO_KEX_ALG_MATCH:          case SSH_ERR_NO_KEX_ALG_MATCH:
         case SSH_ERR_NO_HOSTKEY_ALG_MATCH:          case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
                 if (ssh && ssh->kex && ssh->kex->failed_choice) {                  if (ssh && ssh->kex && ssh->kex->failed_choice) {
                           ssh_packet_clear_keys(ssh);
                         logdie("Unable to negotiate with %s: %s. "                          logdie("Unable to negotiate with %s: %s. "
                             "Their offer: %s", remote_id, ssh_err(r),                              "Their offer: %s", remote_id, ssh_err(r),
                             ssh->kex->failed_choice);                              ssh->kex->failed_choice);
                 }                  }
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         default:          default:
                   ssh_packet_clear_keys(ssh);
                 logdie("%s%sConnection %s %s: %s",                  logdie("%s%sConnection %s %s: %s",
                     tag != NULL ? tag : "", tag != NULL ? ": " : "",                      tag != NULL ? tag : "", tag != NULL ? ": " : "",
                     ssh->state->server_side ? "from" : "to",                      ssh->state->server_side ? "from" : "to",

Legend:
Removed from v.1.256  
changed lines
  Added in v.1.257