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

Diff for /src/usr.bin/ssh/kex.c between version 1.159 and 1.160

version 1.159, 2020/07/05 23:59:45 version 1.160, 2020/10/18 11:32:01
Line 347 
Line 347 
                 goto out;                  goto out;
         }          }
         if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */          if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) { /* skip cookie */
                 error("%s: consume cookie: %s", __func__, ssh_err(r));                  error_fr(r, "consume cookie");
                 goto out;                  goto out;
         }          }
         /* extract kex init proposal strings */          /* extract kex init proposal strings */
         for (i = 0; i < PROPOSAL_MAX; i++) {          for (i = 0; i < PROPOSAL_MAX; i++) {
                 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {                  if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) {
                         error("%s: parse proposal %u: %s", __func__,                          error_fr(r, "parse proposal %u", i);
                             i, ssh_err(r));  
                         goto out;                          goto out;
                 }                  }
                 debug2("%s: %s", proposal_names[i], proposal[i]);                  debug2("%s: %s", proposal_names[i], proposal[i]);
Line 362 
Line 361 
         /* first kex follows / reserved */          /* first kex follows / reserved */
         if ((r = sshbuf_get_u8(b, &v)) != 0 ||  /* first_kex_follows */          if ((r = sshbuf_get_u8(b, &v)) != 0 ||  /* first_kex_follows */
             (r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */              (r = sshbuf_get_u32(b, &i)) != 0) { /* reserved */
                 error("%s: parse: %s", __func__, ssh_err(r));                  error_fr(r, "parse");
                 goto out;                  goto out;
         }          }
         if (first_kex_follows != NULL)          if (first_kex_follows != NULL)
Line 426 
Line 425 
             (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||              (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
             (r = sshpkt_put_cstring(ssh, algs)) != 0 ||              (r = sshpkt_put_cstring(ssh, algs)) != 0 ||
             (r = sshpkt_send(ssh)) != 0) {              (r = sshpkt_send(ssh)) != 0) {
                 error("%s: compose: %s", __func__, ssh_err(r));                  error_fr(r, "compose");
                 goto out;                  goto out;
         }          }
         /* success */          /* success */
Line 478 
Line 477 
                 if (strcmp(name, "server-sig-algs") == 0) {                  if (strcmp(name, "server-sig-algs") == 0) {
                         /* Ensure no \0 lurking in value */                          /* Ensure no \0 lurking in value */
                         if (memchr(val, '\0', vlen) != NULL) {                          if (memchr(val, '\0', vlen) != NULL) {
                                 error("%s: nul byte in %s", __func__, name);                                  error_f("nul byte in %s", name);
                                 return SSH_ERR_INVALID_FORMAT;                                  return SSH_ERR_INVALID_FORMAT;
                         }                          }
                         debug("%s: %s=<%s>", __func__, name, val);                          debug_f("%s=<%s>", name, val);
                         kex->server_sig_algs = val;                          kex->server_sig_algs = val;
                         val = NULL;                          val = NULL;
                 } else                  } else
                         debug("%s: %s (unrecognised)", __func__, name);                          debug_f("%s (unrecognised)", name);
                 free(name);                  free(name);
                 free(val);                  free(val);
         }          }
Line 523 
Line 522 
         int r;          int r;
   
         if (kex == NULL) {          if (kex == NULL) {
                 error("%s: no hex", __func__);                  error_f("no hex");
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         if (kex->flags & KEX_INIT_SENT)          if (kex->flags & KEX_INIT_SENT)
Line 532 
Line 531 
   
         /* generate a random cookie */          /* generate a random cookie */
         if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {          if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) {
                 error("%s: bad kex length: %zu < %d", __func__,                  error_f("bad kex length: %zu < %d",
                     sshbuf_len(kex->my), KEX_COOKIE_LEN);                      sshbuf_len(kex->my), KEX_COOKIE_LEN);
                 return SSH_ERR_INVALID_FORMAT;                  return SSH_ERR_INVALID_FORMAT;
         }          }
         if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {          if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) {
                 error("%s: buffer error", __func__);                  error_f("buffer error");
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         arc4random_buf(cookie, KEX_COOKIE_LEN);          arc4random_buf(cookie, KEX_COOKIE_LEN);
Line 545 
Line 544 
         if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
             (r = sshpkt_putb(ssh, kex->my)) != 0 ||              (r = sshpkt_putb(ssh, kex->my)) != 0 ||
             (r = sshpkt_send(ssh)) != 0) {              (r = sshpkt_send(ssh)) != 0) {
                 error("%s: compose reply: %s", __func__, ssh_err(r));                  error_fr(r, "compose reply");
                 return r;                  return r;
         }          }
         debug("SSH2_MSG_KEXINIT sent");          debug("SSH2_MSG_KEXINIT sent");
Line 565 
Line 564 
   
         debug("SSH2_MSG_KEXINIT received");          debug("SSH2_MSG_KEXINIT received");
         if (kex == NULL) {          if (kex == NULL) {
                 error("%s: no hex", __func__);                  error_f("no hex");
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);          ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
Line 576 
Line 575 
         /* discard packet */          /* discard packet */
         for (i = 0; i < KEX_COOKIE_LEN; i++) {          for (i = 0; i < KEX_COOKIE_LEN; i++) {
                 if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {                  if ((r = sshpkt_get_u8(ssh, NULL)) != 0) {
                         error("%s: discard cookie: %s", __func__, ssh_err(r));                          error_fr(r, "discard cookie");
                         return r;                          return r;
                 }                  }
         }          }
         for (i = 0; i < PROPOSAL_MAX; i++) {          for (i = 0; i < PROPOSAL_MAX; i++) {
                 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {                  if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
                         error("%s: discard proposal: %s", __func__, ssh_err(r));                          error_fr(r, "discard proposal");
                         return r;                          return r;
                 }                  }
         }          }
Line 610 
Line 609 
         if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)          if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
                 return (kex->kex[kex->kex_type])(ssh);                  return (kex->kex[kex->kex_type])(ssh);
   
         error("%s: unknown kex type %u", __func__, kex->kex_type);          error_f("unknown kex type %u", kex->kex_type);
         return SSH_ERR_INTERNAL_ERROR;          return SSH_ERR_INTERNAL_ERROR;
 }  }
   
Line 724 
Line 723 
 kex_start_rekex(struct ssh *ssh)  kex_start_rekex(struct ssh *ssh)
 {  {
         if (ssh->kex == NULL) {          if (ssh->kex == NULL) {
                 error("%s: no kex", __func__);                  error_f("no kex");
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         if (ssh->kex->done == 0) {          if (ssh->kex->done == 0) {
                 error("%s: requested twice", __func__);                  error_f("requested twice");
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         ssh->kex->done = 0;          ssh->kex->done = 0;
Line 743 
Line 742 
         if (name == NULL)          if (name == NULL)
                 return SSH_ERR_NO_CIPHER_ALG_MATCH;                  return SSH_ERR_NO_CIPHER_ALG_MATCH;
         if ((enc->cipher = cipher_by_name(name)) == NULL) {          if ((enc->cipher = cipher_by_name(name)) == NULL) {
                 error("%s: unsupported cipher %s", __func__, name);                  error_f("unsupported cipher %s", name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 765 
Line 764 
         if (name == NULL)          if (name == NULL)
                 return SSH_ERR_NO_MAC_ALG_MATCH;                  return SSH_ERR_NO_MAC_ALG_MATCH;
         if (mac_setup(mac, name) < 0) {          if (mac_setup(mac, name) < 0) {
                 error("%s: unsupported MAC %s", __func__, name);                  error_f("unsupported MAC %s", name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 792 
Line 791 
         if (strcmp(name, "none") == 0) {          if (strcmp(name, "none") == 0) {
                 comp->type = COMP_NONE;                  comp->type = COMP_NONE;
         } else {          } else {
                 error("%s: unsupported compression scheme %s", __func__, name);                  error_f("unsupported compression scheme %s", name);
                 free(name);                  free(name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
Line 811 
Line 810 
         if (k->name == NULL)          if (k->name == NULL)
                 return SSH_ERR_NO_KEX_ALG_MATCH;                  return SSH_ERR_NO_KEX_ALG_MATCH;
         if ((kexalg = kex_alg_by_name(k->name)) == NULL) {          if ((kexalg = kex_alg_by_name(k->name)) == NULL) {
                 error("%s: unsupported KEX method %s", __func__, k->name);                  error_f("unsupported KEX method %s", k->name);
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         k->kex_type = kexalg->type;          k->kex_type = kexalg->type;
Line 831 
Line 830 
                 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;                  return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
         k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);          k->hostkey_type = sshkey_type_from_name(k->hostkey_alg);
         if (k->hostkey_type == KEY_UNSPEC) {          if (k->hostkey_type == KEY_UNSPEC) {
                 error("%s: unsupported hostkey algorithm %s", __func__,                  error_f("unsupported hostkey algorithm %s", k->hostkey_alg);
                     k->hostkey_alg);  
                 return SSH_ERR_INTERNAL_ERROR;                  return SSH_ERR_INTERNAL_ERROR;
         }          }
         k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);          k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg);
Line 1003 
Line 1001 
             kex->session_id_len) != 0 ||              kex->session_id_len) != 0 ||
             ssh_digest_final(hashctx, digest, mdsz) != 0) {              ssh_digest_final(hashctx, digest, mdsz) != 0) {
                 r = SSH_ERR_LIBCRYPTO_ERROR;                  r = SSH_ERR_LIBCRYPTO_ERROR;
                 error("%s: KEX hash failed", __func__);                  error_f("KEX hash failed");
                 goto out;                  goto out;
         }          }
         ssh_digest_free(hashctx);          ssh_digest_free(hashctx);
Line 1020 
Line 1018 
                     ssh_digest_update(hashctx, hash, hashlen) != 0 ||                      ssh_digest_update(hashctx, hash, hashlen) != 0 ||
                     ssh_digest_update(hashctx, digest, have) != 0 ||                      ssh_digest_update(hashctx, digest, have) != 0 ||
                     ssh_digest_final(hashctx, digest + have, mdsz) != 0) {                      ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
                         error("%s: KDF failed", __func__);                          error_f("KDF failed");
                         r = SSH_ERR_LIBCRYPTO_ERROR;                          r = SSH_ERR_LIBCRYPTO_ERROR;
                         goto out;                          goto out;
                 }                  }
Line 1085 
Line 1083 
         *prvp = NULL;          *prvp = NULL;
         if (kex->load_host_public_key == NULL ||          if (kex->load_host_public_key == NULL ||
             kex->load_host_private_key == NULL) {              kex->load_host_private_key == NULL) {
                 error("%s: missing hostkey loader", __func__);                  error_f("missing hostkey loader");
                 return SSH_ERR_INVALID_ARGUMENT;                  return SSH_ERR_INVALID_ARGUMENT;
         }          }
         *pubp = kex->load_host_public_key(kex->hostkey_type,          *pubp = kex->load_host_public_key(kex->hostkey_type,
Line 1103 
Line 1101 
         struct kex *kex = ssh->kex;          struct kex *kex = ssh->kex;
   
         if (kex->verify_host_key == NULL) {          if (kex->verify_host_key == NULL) {
                 error("%s: missing hostkey verifier", __func__);                  error_f("missing hostkey verifier");
                 return SSH_ERR_INVALID_ARGUMENT;                  return SSH_ERR_INVALID_ARGUMENT;
         }          }
         if (server_host_key->type != kex->hostkey_type ||          if (server_host_key->type != kex->hostkey_type ||
Line 1140 
Line 1138 
             msg, strlen(msg)) != strlen(msg) ||              msg, strlen(msg)) != strlen(msg) ||
             atomicio(vwrite, ssh_packet_get_connection_out(ssh),              atomicio(vwrite, ssh_packet_get_connection_out(ssh),
             crnl, strlen(crnl)) != strlen(crnl))              crnl, strlen(crnl)) != strlen(crnl))
                 error("%s: write: %.100s", __func__, strerror(errno));                  error_f("write: %.100s", strerror(errno));
 }  }
   
 /*  /*
Line 1172 
Line 1170 
             version_addendum == NULL ? "" : " ",              version_addendum == NULL ? "" : " ",
             version_addendum == NULL ? "" : version_addendum)) != 0) {              version_addendum == NULL ? "" : version_addendum)) != 0) {
                 oerrno = errno;                  oerrno = errno;
                 error("%s: sshbuf_putf: %s", __func__, ssh_err(r));                  error_fr(r, "sshbuf_putf");
                 goto out;                  goto out;
         }          }
   
Line 1180 
Line 1178 
             sshbuf_mutable_ptr(our_version),              sshbuf_mutable_ptr(our_version),
             sshbuf_len(our_version)) != sshbuf_len(our_version)) {              sshbuf_len(our_version)) != sshbuf_len(our_version)) {
                 oerrno = errno;                  oerrno = errno;
                 debug("%s: write: %.100s", __func__, strerror(errno));                  debug_f("write: %.100s", strerror(errno));
                 r = SSH_ERR_SYSTEM_ERROR;                  r = SSH_ERR_SYSTEM_ERROR;
                 goto out;                  goto out;
         }          }
         if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */          if ((r = sshbuf_consume_end(our_version, 2)) != 0) { /* trim \r\n */
                 oerrno = errno;                  oerrno = errno;
                 error("%s: sshbuf_consume_end: %s", __func__, ssh_err(r));                  error_fr(r, "sshbuf_consume_end");
                 goto out;                  goto out;
         }          }
         our_version_string = sshbuf_dup_string(our_version);          our_version_string = sshbuf_dup_string(our_version);
         if (our_version_string == NULL) {          if (our_version_string == NULL) {
                 error("%s: sshbuf_dup_string failed", __func__);                  error_f("sshbuf_dup_string failed");
                 r = SSH_ERR_ALLOC_FAIL;                  r = SSH_ERR_ALLOC_FAIL;
                 goto out;                  goto out;
         }          }
Line 1202 
Line 1200 
                 if (n >= SSH_MAX_PRE_BANNER_LINES) {                  if (n >= SSH_MAX_PRE_BANNER_LINES) {
                         send_error(ssh, "No SSH identification string "                          send_error(ssh, "No SSH identification string "
                             "received.");                              "received.");
                         error("%s: No SSH version received in first %u lines "                          error_f("No SSH version received in first %u lines "
                             "from server", __func__, SSH_MAX_PRE_BANNER_LINES);                              "from server", SSH_MAX_PRE_BANNER_LINES);
                         r = SSH_ERR_INVALID_FORMAT;                          r = SSH_ERR_INVALID_FORMAT;
                         goto out;                          goto out;
                 }                  }
Line 1222 
Line 1220 
                                         goto out;                                          goto out;
                                 } else if (r == -1) {                                  } else if (r == -1) {
                                         oerrno = errno;                                          oerrno = errno;
                                         error("%s: %s",                                          error_f("%s", strerror(errno));
                                             __func__, strerror(errno));  
                                         r = SSH_ERR_SYSTEM_ERROR;                                          r = SSH_ERR_SYSTEM_ERROR;
                                         goto out;                                          goto out;
                                 }                                  }
Line 1232 
Line 1229 
                         len = atomicio(read, ssh_packet_get_connection_in(ssh),                          len = atomicio(read, ssh_packet_get_connection_in(ssh),
                             &c, 1);                              &c, 1);
                         if (len != 1 && errno == EPIPE) {                          if (len != 1 && errno == EPIPE) {
                                 error("%s: Connection closed by remote host",                                  error_f("Connection closed by remote host");
                                     __func__);  
                                 r = SSH_ERR_CONN_CLOSED;                                  r = SSH_ERR_CONN_CLOSED;
                                 goto out;                                  goto out;
                         } else if (len != 1) {                          } else if (len != 1) {
                                 oerrno = errno;                                  oerrno = errno;
                                 error("%s: read: %.100s",                                  error_f("read: %.100s", strerror(errno));
                                     __func__, strerror(errno));  
                                 r = SSH_ERR_SYSTEM_ERROR;                                  r = SSH_ERR_SYSTEM_ERROR;
                                 goto out;                                  goto out;
                         }                          }
Line 1250 
Line 1245 
                         if (c == '\n')                          if (c == '\n')
                                 break;                                  break;
                         if (c == '\0' || expect_nl) {                          if (c == '\0' || expect_nl) {
                                 error("%s: banner line contains invalid "                                  error_f("banner line contains invalid "
                                     "characters", __func__);                                      "characters");
                                 goto invalid;                                  goto invalid;
                         }                          }
                         if ((r = sshbuf_put_u8(peer_version, c)) != 0) {                          if ((r = sshbuf_put_u8(peer_version, c)) != 0) {
                                 oerrno = errno;                                  oerrno = errno;
                                 error("%s: sshbuf_put: %s",                                  error_fr(r, "sshbuf_put");
                                     __func__, ssh_err(r));  
                                 goto out;                                  goto out;
                         }                          }
                         if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {                          if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
                                 error("%s: banner line too long", __func__);                                  error_f("banner line too long");
                                 goto invalid;                                  goto invalid;
                         }                          }
                 }                  }
Line 1271 
Line 1265 
                         break;                          break;
                 /* If not, then just log the line and continue */                  /* If not, then just log the line and continue */
                 if ((cp = sshbuf_dup_string(peer_version)) == NULL) {                  if ((cp = sshbuf_dup_string(peer_version)) == NULL) {
                         error("%s: sshbuf_dup_string failed", __func__);                          error_f("sshbuf_dup_string failed");
                         r = SSH_ERR_ALLOC_FAIL;                          r = SSH_ERR_ALLOC_FAIL;
                         goto out;                          goto out;
                 }                  }
                 /* Do not accept lines before the SSH ident from a client */                  /* Do not accept lines before the SSH ident from a client */
                 if (ssh->kex->server) {                  if (ssh->kex->server) {
                         error("%s: client sent invalid protocol identifier "                          error_f("client sent invalid protocol identifier "
                             "\"%.256s\"", __func__, cp);                              "\"%.256s\"", cp);
                         free(cp);                          free(cp);
                         goto invalid;                          goto invalid;
                 }                  }
                 debug("%s: banner line %zu: %s", __func__, n, cp);                  debug_f("banner line %zu: %s", n, cp);
                 free(cp);                  free(cp);
         }          }
         peer_version_string = sshbuf_dup_string(peer_version);          peer_version_string = sshbuf_dup_string(peer_version);
         if (peer_version_string == NULL)          if (peer_version_string == NULL)
                 error("%s: sshbuf_dup_string failed", __func__);                  error_f("sshbuf_dup_string failed");
         /* XXX must be same size for sscanf */          /* XXX must be same size for sscanf */
         if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {          if ((remote_version = calloc(1, sshbuf_len(peer_version))) == NULL) {
                 error("%s: calloc failed", __func__);                  error_f("calloc failed");
                 r = SSH_ERR_ALLOC_FAIL;                  r = SSH_ERR_ALLOC_FAIL;
                 goto out;                  goto out;
         }          }

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