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

Diff for /src/usr.bin/ssh/sshconnect.c between version 1.218 and 1.219

version 1.218, 2010/01/13 00:19:04 version 1.219, 2010/02/26 20:29:54
Line 49 
Line 49 
 #include "misc.h"  #include "misc.h"
 #include "dns.h"  #include "dns.h"
 #include "roaming.h"  #include "roaming.h"
   #include "ssh2.h"
 #include "version.h"  #include "version.h"
   
 char *client_version_string = NULL;  char *client_version_string = NULL;
Line 567 
Line 568 
         }          }
 }  }
   
   static int
   check_host_cert(const char *host, const Key *host_key)
   {
           const char *reason;
   
           if (key_cert_check_authority(host_key, 1, 0, host, &reason) != 0) {
                   error("%s", reason);
                   return 0;
           }
           if (buffer_len(&host_key->cert->constraints) != 0) {
                   error("Certificate for %s contains unsupported constraint(s)",
                       host);
                   return 0;
           }
           return 1;
   }
   
 /*  /*
  * check whether the supplied host key is valid, return -1 if the key   * check whether the supplied host key is valid, return -1 if the key
  * is not valid. the user_hostfile will not be updated if 'readonly' is true.   * is not valid. the user_hostfile will not be updated if 'readonly' is true.
Line 579 
Line 597 
     Key *host_key, int readonly, const char *user_hostfile,      Key *host_key, int readonly, const char *user_hostfile,
     const char *system_hostfile)      const char *system_hostfile)
 {  {
         Key *file_key;          Key *file_key, *raw_key = NULL;
         const char *type = key_type(host_key);          const char *type;
         char *ip = NULL, *host = NULL;          char *ip = NULL, *host = NULL;
         char hostline[1000], *hostp, *fp, *ra;          char hostline[1000], *hostp, *fp, *ra;
         HostStatus host_status;          HostStatus host_status;
         HostStatus ip_status;          HostStatus ip_status;
         int r, local = 0, host_ip_differ = 0;          int r, want_cert, local = 0, host_ip_differ = 0;
         char ntop[NI_MAXHOST];          char ntop[NI_MAXHOST];
         char msg[1024];          char msg[1024];
         int len, host_line, ip_line, cancelled_forwarding = 0;          int len, host_line, ip_line, cancelled_forwarding = 0;
Line 654 
Line 672 
                 host = put_host_port(hostname, port);                  host = put_host_port(hostname, port);
         }          }
   
    retry:
           want_cert = key_is_cert(host_key);
           type = key_type(host_key);
   
         /*          /*
          * Store the host key from the known host file in here so that we can           * Store the host key from the known host file in here so that we can
          * compare it with the key for the IP address.           * compare it with the key for the IP address.
          */           */
         file_key = key_new(host_key->type);          file_key = key_new(key_is_cert(host_key) ? KEY_UNSPEC : host_key->type);
   
         /*          /*
          * Check if the host key is present in the user's list of known           * Check if the host key is present in the user's list of known
Line 674 
Line 696 
         }          }
         /*          /*
          * Also perform check for the ip address, skip the check if we are           * Also perform check for the ip address, skip the check if we are
          * localhost or the hostname was an ip address to begin with           * localhost, looking for a certificate, or the hostname was an ip
            * address to begin with.
          */           */
         if (options.check_host_ip) {          if (!want_cert && options.check_host_ip) {
                 Key *ip_key = key_new(host_key->type);                  Key *ip_key = key_new(host_key->type);
   
                 ip_file = user_hostfile;                  ip_file = user_hostfile;
Line 700 
Line 723 
         switch (host_status) {          switch (host_status) {
         case HOST_OK:          case HOST_OK:
                 /* The host is known and the key matches. */                  /* The host is known and the key matches. */
                 debug("Host '%.200s' is known and matches the %s host key.",                  debug("Host '%.200s' is known and matches the %s host %s.",
                     host, type);                      host, type, want_cert ? "certificate" : "key");
                 debug("Found key in %s:%d", host_file, host_line);                  debug("Found %s in %s:%d",
                       want_cert ? "certificate" : "key", host_file, host_line);
                   if (want_cert && !check_host_cert(hostname, host_key))
                           goto fail;
                 if (options.check_host_ip && ip_status == HOST_NEW) {                  if (options.check_host_ip && ip_status == HOST_NEW) {
                         if (readonly)                          if (readonly || want_cert)
                                 logit("%s host key for IP address "                                  logit("%s host key for IP address "
                                     "'%.128s' not in list of known hosts.",                                      "'%.128s' not in list of known hosts.",
                                     type, ip);                                      type, ip);
Line 736 
Line 762 
                                 break;                                  break;
                         }                          }
                 }                  }
                 if (readonly)                  if (readonly || want_cert)
                         goto fail;                          goto fail;
                 /* The host is new. */                  /* The host is new. */
                 if (options.strict_host_key_checking == 1) {                  if (options.strict_host_key_checking == 1) {
Line 821 
Line 847 
                             "list of known hosts.", hostp, type);                              "list of known hosts.", hostp, type);
                 break;                  break;
         case HOST_CHANGED:          case HOST_CHANGED:
                   if (want_cert) {
                           /*
                            * This is only a debug() since it is valid to have
                            * CAs with wildcard DNS matches that don't match
                            * all hosts that one might visit.
                            */
                           debug("Host certificate authority does not "
                               "match %s in %s:%d", CA_MARKER,
                               host_file, host_line);
                           goto fail;
                   }
                 if (readonly == ROQUIET)                  if (readonly == ROQUIET)
                         goto fail;                          goto fail;
                 if (options.check_host_ip && host_ip_differ) {                  if (options.check_host_ip && host_ip_differ) {
Line 957 
Line 994 
         return 0;          return 0;
   
 fail:  fail:
           if (want_cert) {
                   /*
                    * No matching certificate. Downgrade cert to raw key and
                    * search normally.
                    */
                   debug("No matching CA found. Retry with plain key");
                   raw_key = key_from_private(host_key);
                   if (key_drop_cert(raw_key) != 0)
                           fatal("Couldn't drop certificate");
                   host_key = raw_key;
                   goto retry;
           }
           if (raw_key != NULL)
                   key_free(raw_key);
         xfree(ip);          xfree(ip);
         xfree(host);          xfree(host);
         return -1;          return -1;
Line 969 
Line 1020 
         struct stat st;          struct stat st;
         int flags = 0;          int flags = 0;
   
         if (options.verify_host_key_dns &&          /* XXX certs are not yet supported for DNS */
           if (!key_is_cert(host_key) && options.verify_host_key_dns &&
             verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {              verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
   
                 if (flags & DNS_VERIFY_FOUND) {                  if (flags & DNS_VERIFY_FOUND) {

Legend:
Removed from v.1.218  
changed lines
  Added in v.1.219