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

Diff for /src/usr.bin/ssh/ssh.c between version 1.399 and 1.400

version 1.399, 2014/02/04 00:24:29 version 1.400, 2014/02/23 20:11:36
Line 218 
Line 218 
         }          }
 }  }
   
   /*
    * Attempt to resolve a host name / port to a set of addresses and
    * optionally return any CNAMEs encountered along the way.
    * Returns NULL on failure.
    * NB. this function must operate with a options having undefined members.
    */
 static struct addrinfo *  static struct addrinfo *
 resolve_host(const char *name, u_int port, int logerr, char *cname, size_t clen)  resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
 {  {
         char strport[NI_MAXSERV];          char strport[NI_MAXSERV];
         struct addrinfo hints, *res;          struct addrinfo hints, *res;
         int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1;          int gaierr, loglevel = SYSLOG_LEVEL_DEBUG1;
   
           if (port <= 0)
                   port = default_ssh_port();
   
         snprintf(strport, sizeof strport, "%u", port);          snprintf(strport, sizeof strport, "%u", port);
         memset(&hints, 0, sizeof(hints));          memset(&hints, 0, sizeof(hints));
         hints.ai_family = options.address_family;          hints.ai_family = options.address_family == -1 ?
               AF_UNSPEC : options.address_family;
         hints.ai_socktype = SOCK_STREAM;          hints.ai_socktype = SOCK_STREAM;
         if (cname != NULL)          if (cname != NULL)
                 hints.ai_flags = AI_CANONNAME;                  hints.ai_flags = AI_CANONNAME;
Line 252 
Line 262 
 /*  /*
  * Check whether the cname is a permitted replacement for the hostname   * Check whether the cname is a permitted replacement for the hostname
  * and perform the replacement if it is.   * and perform the replacement if it is.
    * NB. this function must operate with a options having undefined members.
  */   */
 static int  static int
 check_follow_cname(char **namep, const char *cname)  check_follow_cname(char **namep, const char *cname)
Line 268 
Line 279 
          * Don't attempt to canonicalize names that will be interpreted by           * Don't attempt to canonicalize names that will be interpreted by
          * a proxy unless the user specifically requests so.           * a proxy unless the user specifically requests so.
          */           */
         if (options.proxy_command != NULL &&          if (!option_clear_or_none(options.proxy_command) &&
             options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)              options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
                 return 0;                  return 0;
         debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname);          debug3("%s: check \"%s\" CNAME \"%s\"", __func__, *namep, cname);
Line 292 
Line 303 
  * Attempt to resolve the supplied hostname after applying the user's   * Attempt to resolve the supplied hostname after applying the user's
  * canonicalization rules. Returns the address list for the host or NULL   * canonicalization rules. Returns the address list for the host or NULL
  * if no name was found after canonicalization.   * if no name was found after canonicalization.
    * NB. this function must operate with a options having undefined members.
  */   */
 static struct addrinfo *  static struct addrinfo *
 resolve_canonicalize(char **hostp, u_int port)  resolve_canonicalize(char **hostp, int port)
 {  {
         int i, ndots;          int i, ndots;
         char *cp, *fullhost, cname_target[NI_MAXHOST];          char *cp, *fullhost, cname_target[NI_MAXHOST];
Line 302 
Line 314 
   
         if (options.canonicalize_hostname == SSH_CANONICALISE_NO)          if (options.canonicalize_hostname == SSH_CANONICALISE_NO)
                 return NULL;                  return NULL;
   
         /*          /*
          * Don't attempt to canonicalize names that will be interpreted by           * Don't attempt to canonicalize names that will be interpreted by
          * a proxy unless the user specifically requests so.           * a proxy unless the user specifically requests so.
          */           */
         if (options.proxy_command != NULL &&          if (!option_clear_or_none(options.proxy_command) &&
             options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)              options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS)
                 return NULL;                  return NULL;
   
         /* Don't apply canonicalization to sufficiently-qualified hostnames */          /* Don't apply canonicalization to sufficiently-qualified hostnames */
         ndots = 0;          ndots = 0;
         for (cp = *hostp; *cp != '\0'; cp++) {          for (cp = *hostp; *cp != '\0'; cp++) {
Line 325 
Line 339 
                 *cname_target = '\0';                  *cname_target = '\0';
                 xasprintf(&fullhost, "%s.%s.", *hostp,                  xasprintf(&fullhost, "%s.%s.", *hostp,
                     options.canonical_domains[i]);                      options.canonical_domains[i]);
                 if ((addrs = resolve_host(fullhost, options.port, 0,                  debug3("%s: attempting \"%s\" => \"%s\"", __func__,
                       *hostp, fullhost);
                   if ((addrs = resolve_host(fullhost, port, 0,
                     cname_target, sizeof(cname_target))) == NULL) {                      cname_target, sizeof(cname_target))) == NULL) {
                         free(fullhost);                          free(fullhost);
                         continue;                          continue;
Line 342 
Line 358 
                 return addrs;                  return addrs;
         }          }
         if (!options.canonicalize_fallback_local)          if (!options.canonicalize_fallback_local)
                 fatal("%s: Could not resolve host \"%s\"", __progname, host);                  fatal("%s: Could not resolve host \"%s\"", __progname, *hostp);
           debug2("%s: host %s not found in any suffix", __func__, *hostp);
         return NULL;          return NULL;
 }  }
   
 /*  /*
    * Read per-user configuration file.  Ignore the system wide config
    * file if the user specifies a config file on the command line.
    */
   static void
   process_config_files(struct passwd *pw)
   {
           char buf[MAXPATHLEN];
           int r;
   
           if (config != NULL) {
                   if (strcasecmp(config, "none") != 0 &&
                       !read_config_file(config, pw, host, &options,
                       SSHCONF_USERCONF))
                           fatal("Can't open user config file %.100s: "
                               "%.100s", config, strerror(errno));
           } else {
                   r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
                       _PATH_SSH_USER_CONFFILE);
                   if (r > 0 && (size_t)r < sizeof(buf))
                           (void)read_config_file(buf, pw, host, &options,
                                SSHCONF_CHECKPERM|SSHCONF_USERCONF);
   
                   /* Read systemwide configuration file after user config. */
                   (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host,
                       &options, 0);
           }
   }
   
   /*
  * Main program for the ssh client.   * Main program for the ssh client.
  */   */
 int  int
Line 804 
Line 850 
         if (debug_flag)          if (debug_flag)
                 logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION));                  logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
   
           /* Parse the configuration files */
           process_config_files(pw);
   
           /* Hostname canonicalisation needs a few options filled. */
           fill_default_options_for_canonicalization(&options);
   
           /* If the user has replaced the hostname then take it into use now */
           if (options.hostname != NULL) {
                   /* NB. Please keep in sync with readconf.c:match_cfg_line() */
                   cp = percent_expand(options.hostname,
                       "h", host, (char *)NULL);
                   free(host);
                   host = cp;
           }
   
           /* If canonicalization requested then try to apply it */
           lowercase(host);
           if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
                   addrs = resolve_canonicalize(&host, options.port);
   
         /*          /*
          * Read per-user configuration file.  Ignore the system wide config           * If canonicalization not requested, or if it failed then try to
          * file if the user specifies a config file on the command line.           * resolve the bare hostname name using the system resolver's usual
            * search rules. Skip the lookup if a ProxyCommand is being used
            * unless the user has specifically requested canonicalisation.
          */           */
         if (config != NULL) {          if (addrs == NULL && (option_clear_or_none(options.proxy_command) ||
                 if (strcasecmp(config, "none") != 0 &&              options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {
                     !read_config_file(config, pw, host, &options,                  if ((addrs = resolve_host(host, options.port, 1,
                     SSHCONF_USERCONF))                      cname, sizeof(cname))) == NULL)
                         fatal("Can't open user config file %.100s: "                          cleanup_exit(255); /* resolve_host logs the error */
                             "%.100s", config, strerror(errno));                  check_follow_cname(&host, cname);
         } else {          }
                 r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,  
                     _PATH_SSH_USER_CONFFILE);  
                 if (r > 0 && (size_t)r < sizeof(buf))  
                         (void)read_config_file(buf, pw, host, &options,  
                              SSHCONF_CHECKPERM|SSHCONF_USERCONF);  
   
                 /* Read systemwide configuration file after user config. */          /*
                 (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host,           * If the target hostname has changed as a result of canonicalisation
                     &options, 0);           * then re-parse the configuration files as new stanzas may match.
            */
           if (strcasecmp(host_arg, host) != 0) {
                   debug("Hostname has changed; re-reading configuration");
                   process_config_files(pw);
         }          }
   
         /* Fill configuration defaults. */          /* Fill configuration defaults. */
         fill_default_options(&options);          fill_default_options(&options);
   
           if (options.port == 0)
                   options.port = default_ssh_port();
         channel_set_af(options.address_family);          channel_set_af(options.address_family);
   
         /* Tidy and check options */          /* Tidy and check options */
Line 866 
Line 935 
   
         if (options.user == NULL)          if (options.user == NULL)
                 options.user = xstrdup(pw->pw_name);                  options.user = xstrdup(pw->pw_name);
   
         /* Get default port if port has not been set. */  
         if (options.port == 0)  
                 options.port = default_ssh_port();  
   
         /* preserve host name given on command line for %n expansion */  
         if (options.hostname != NULL) {  
                 /* NB. Please keep in sync with readconf.c:match_cfg_line() */  
                 cp = percent_expand(options.hostname,  
                     "h", host, (char *)NULL);  
                 free(host);  
                 host = cp;  
         }  
   
         /* If canonicalization requested then try to apply it */  
         lowercase(host);  
         if (options.canonicalize_hostname != SSH_CANONICALISE_NO)  
                 addrs = resolve_canonicalize(&host, options.port);  
         /*  
          * If canonicalization not requested, or if it failed then try to  
          * resolve the bare hostname name using the system resolver's usual  
          * search rules. Skip the lookup if a ProxyCommand is being used  
          * unless the user has specifically requested canonicalisation.  
          */  
         if (addrs == NULL && (options.proxy_command == NULL ||  
             options.canonicalize_hostname == SSH_CANONICALISE_ALWAYS)) {  
                 if ((addrs = resolve_host(host, options.port, 1,  
                     cname, sizeof(cname))) == NULL)  
                         cleanup_exit(255); /* resolve_host logs the error */  
                 check_follow_cname(&host, cname);  
         }  
   
         if (gethostname(thishost, sizeof(thishost)) == -1)          if (gethostname(thishost, sizeof(thishost)) == -1)
                 fatal("gethostname: %s", strerror(errno));                  fatal("gethostname: %s", strerror(errno));

Legend:
Removed from v.1.399  
changed lines
  Added in v.1.400