[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.182 and 1.183

version 1.182, 2023/10/11 04:46:29 version 1.183, 2023/12/18 14:45:17
Line 60 
Line 60 
 #include "xmalloc.h"  #include "xmalloc.h"
   
 /* prototype */  /* prototype */
 static int kex_choose_conf(struct ssh *);  static int kex_choose_conf(struct ssh *, uint32_t seq);
 static int kex_input_newkeys(int, u_int32_t, struct ssh *);  static int kex_input_newkeys(int, u_int32_t, struct ssh *);
   
 static const char * const proposal_names[PROPOSAL_MAX] = {  static const char * const proposal_names[PROPOSAL_MAX] = {
Line 162 
Line 162 
         return 1;          return 1;
 }  }
   
   /* returns non-zero if proposal contains any algorithm from algs */
   static int
   has_any_alg(const char *proposal, const char *algs)
   {
           char *cp;
   
           if ((cp = match_list(proposal, algs, NULL)) == NULL)
                   return 0;
           free(cp);
           return 1;
   }
   
 /*  /*
  * Concatenate algorithm names, avoiding duplicates in the process.   * Concatenate algorithm names, avoiding duplicates in the process.
  * Caller must free returned string.   * Caller must free returned string.
Line 169 
Line 181 
 char *  char *
 kex_names_cat(const char *a, const char *b)  kex_names_cat(const char *a, const char *b)
 {  {
         char *ret = NULL, *tmp = NULL, *cp, *p, *m;          char *ret = NULL, *tmp = NULL, *cp, *p;
         size_t len;          size_t len;
   
         if (a == NULL || *a == '\0')          if (a == NULL || *a == '\0')
Line 186 
Line 198 
         }          }
         strlcpy(ret, a, len);          strlcpy(ret, a, len);
         for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {          for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
                 if ((m = match_list(ret, p, NULL)) != NULL) {                  if (has_any_alg(ret, p))
                         free(m);  
                         continue; /* Algorithm already present */                          continue; /* Algorithm already present */
                 }  
                 if (strlcat(ret, ",", len) >= len ||                  if (strlcat(ret, ",", len) >= len ||
                     strlcat(ret, p, len) >= len) {                      strlcat(ret, p, len) >= len) {
                         free(tmp);                          free(tmp);
Line 319 
Line 329 
         const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT };          const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT };
         const char **defprop = ssh->kex->server ? defpropserver : defpropclient;          const char **defprop = ssh->kex->server ? defpropserver : defpropclient;
         u_int i;          u_int i;
           char *cp;
   
         if (prop == NULL)          if (prop == NULL)
                 fatal_f("proposal missing");                  fatal_f("proposal missing");
   
           /* Append EXT_INFO signalling to KexAlgorithms */
           if (kexalgos == NULL)
                   kexalgos = defprop[PROPOSAL_KEX_ALGS];
           if ((cp = kex_names_cat(kexalgos, ssh->kex->server ?
               "kex-strict-s-v00@openssh.com" :
               "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
                   fatal_f("kex_names_cat");
   
         for (i = 0; i < PROPOSAL_MAX; i++) {          for (i = 0; i < PROPOSAL_MAX; i++) {
                 switch(i) {                  switch(i) {
                 case PROPOSAL_KEX_ALGS:                  case PROPOSAL_KEX_ALGS:
                         prop[i] = compat_kex_proposal(ssh,                          prop[i] = compat_kex_proposal(ssh, cp);
                             kexalgos ? kexalgos : defprop[i]);  
                         break;                          break;
                 case PROPOSAL_ENC_ALGS_CTOS:                  case PROPOSAL_ENC_ALGS_CTOS:
                 case PROPOSAL_ENC_ALGS_STOC:                  case PROPOSAL_ENC_ALGS_STOC:
Line 348 
Line 366 
                         prop[i] = xstrdup(defprop[i]);                          prop[i] = xstrdup(defprop[i]);
                 }                  }
         }          }
           free(cp);
 }  }
   
 void  void
Line 451 
Line 470 
 {  {
         int r;          int r;
   
         error("kex protocol error: type %d seq %u", type, seq);          /* If in strict mode, any unexpected message is an error */
           if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) {
                   ssh_packet_disconnect(ssh, "strict KEX violation: "
                       "unexpected packet type %u (seqnr %u)", type, seq);
           }
           error_f("type %u seq %u", type, seq);
         if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||          if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
             (r = sshpkt_put_u32(ssh, seq)) != 0 ||              (r = sshpkt_put_u32(ssh, seq)) != 0 ||
             (r = sshpkt_send(ssh)) != 0)              (r = sshpkt_send(ssh)) != 0)
Line 548 
Line 572 
         if (ninfo >= 1024) {          if (ninfo >= 1024) {
                 error("SSH2_MSG_EXT_INFO with too many entries, expected "                  error("SSH2_MSG_EXT_INFO with too many entries, expected "
                     "<=1024, received %u", ninfo);                      "<=1024, received %u", ninfo);
                 return SSH_ERR_INVALID_FORMAT;                  return dispatch_protocol_error(type, seq, ssh);
         }          }
         for (i = 0; i < ninfo; i++) {          for (i = 0; i < ninfo; i++) {
                 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)                  if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
Line 666 
Line 690 
                 error_f("no kex");                  error_f("no kex");
                 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, &kex_protocol_error);
         ptr = sshpkt_ptr(ssh, &dlen);          ptr = sshpkt_ptr(ssh, &dlen);
         if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)          if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
                 return r;                  return r;
Line 702 
Line 726 
         if (!(kex->flags & KEX_INIT_SENT))          if (!(kex->flags & KEX_INIT_SENT))
                 if ((r = kex_send_kexinit(ssh)) != 0)                  if ((r = kex_send_kexinit(ssh)) != 0)
                         return r;                          return r;
         if ((r = kex_choose_conf(ssh)) != 0)          if ((r = kex_choose_conf(ssh, seq)) != 0)
                 return r;                  return r;
   
         if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)          if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
Line 964 
Line 988 
         return (1);          return (1);
 }  }
   
 /* returns non-zero if proposal contains any algorithm from algs */  
 static int  static int
 has_any_alg(const char *proposal, const char *algs)  kexalgs_contains(char **peer, const char *ext)
 {  {
         char *cp;          return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
   
         if ((cp = match_list(proposal, algs, NULL)) == NULL)  
                 return 0;  
         free(cp);  
         return 1;  
 }  }
   
 static int  static int
 kex_choose_conf(struct ssh *ssh)  kex_choose_conf(struct ssh *ssh, uint32_t seq)
 {  {
         struct kex *kex = ssh->kex;          struct kex *kex = ssh->kex;
         struct newkeys *newkeys;          struct newkeys *newkeys;
Line 1002 
Line 1020 
                 sprop=peer;                  sprop=peer;
         }          }
   
         /* Check whether client supports ext_info_c */          /* Check whether peer supports ext_info/kex_strict */
         if (kex->server && (kex->flags & KEX_INITIAL)) {          if ((kex->flags & KEX_INITIAL) != 0) {
                 char *ext;                  if (kex->server) {
                           kex->ext_info_c = kexalgs_contains(peer, "ext-info-c");
                 ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);                          kex->kex_strict = kexalgs_contains(peer,
                 kex->ext_info_c = (ext != NULL);                              "kex-strict-c-v00@openssh.com");
                 free(ext);                  } else {
                           kex->kex_strict = kexalgs_contains(peer,
                               "kex-strict-s-v00@openssh.com");
                   }
                   if (kex->kex_strict) {
                           debug3_f("will use strict KEX ordering");
                           if (seq != 0)
                                   ssh_packet_disconnect(ssh,
                                       "strict KEX violation: "
                                       "KEXINIT was not the first packet");
                   }
         }          }
   
         /* Check whether client supports rsa-sha2 algorithms */          /* Check whether client supports rsa-sha2 algorithms */

Legend:
Removed from v.1.182  
changed lines
  Added in v.1.183