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

Diff for /src/usr.bin/ssh/hostfile.c between version 1.59 and 1.60

version 1.59, 2015/01/15 09:40:00 version 1.60, 2015/01/18 21:40:23
Line 40 
Line 40 
   
 #include <netinet/in.h>  #include <netinet/in.h>
   
   #include <errno.h>
 #include <resolv.h>  #include <resolv.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 61 
Line 62 
         u_int num_entries;          u_int num_entries;
 };  };
   
   /* XXX hmac is too easy to dictionary attack; use bcrypt? */
   
 static int  static int
 extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)  extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len)
 {  {
Line 493 
Line 496 
                     __func__, filename, ssh_err(r));                      __func__, filename, ssh_err(r));
         } else          } else
                 success = 1;                  success = 1;
         fputs("\n", f);          fputc('\n', f);
         fclose(f);          fclose(f);
         return success;          return success;
   }
   
   static int
   match_maybe_hashed(const char *host, const char *names, int *was_hashed)
   {
           int hashed = *names == HASH_DELIM;
           const char *hashed_host;
           size_t nlen = strlen(names);
   
           if (was_hashed != NULL)
                   *was_hashed = hashed;
           if (hashed) {
                   if ((hashed_host = host_hash(host, names, nlen)) == NULL)
                           return -1;
                   return nlen == strlen(hashed_host) &&
                       strncmp(hashed_host, names, nlen) == 0;
           }
           return match_hostname(host, names, nlen) == 1;
   }
   
   int
   hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
       const char *host, u_int options)
   {
           FILE *f;
           char line[8192], oline[8192];
           u_long linenum = 0;
           char *cp, *cp2;
           u_int kbits;
           int s, r = 0;
           struct hostkey_foreach_line lineinfo;
   
           memset(&lineinfo, 0, sizeof(lineinfo));
           if (host == NULL && (options & HKF_WANT_MATCH_HOST) != 0)
                   return SSH_ERR_INVALID_ARGUMENT;
           if ((f = fopen(path, "r")) == NULL)
                   return SSH_ERR_SYSTEM_ERROR;
   
           debug3("%s: reading file \"%s\"", __func__, path);
           while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) {
                   line[strcspn(line, "\n")] = '\0';
                   strlcpy(oline, line, sizeof(oline));
   
                   sshkey_free(lineinfo.key);
                   memset(&lineinfo, 0, sizeof(lineinfo));
                   lineinfo.path = path;
                   lineinfo.linenum = linenum;
                   lineinfo.line = oline;
                   lineinfo.status = HKF_STATUS_OK;
   
                   /* Skip any leading whitespace, comments and empty lines. */
                   for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
                           ;
                   if (!*cp || *cp == '#' || *cp == '\n') {
                           if ((options & HKF_WANT_MATCH_HOST) == 0) {
                                   lineinfo.status = HKF_STATUS_COMMENT;
                                   if ((r = callback(&lineinfo, ctx)) != 0)
                                           break;
                           }
                           continue;
                   }
   
                   if ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) {
                           verbose("%s: invalid marker at %s:%lu",
                               __func__, path, linenum);
                           if ((options & HKF_WANT_MATCH_HOST) == 0)
                                   goto bad;
                           continue;
                   }
   
                   /* Find the end of the host name portion. */
                   for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
                           ;
                   lineinfo.hosts = cp;
                   *cp2++ = '\0';
   
                   /* Check if the host name matches. */
                   if (host != NULL) {
                           s = match_maybe_hashed(host, lineinfo.hosts,
                               &lineinfo.was_hashed);
                           if (s == 1)
                                   lineinfo.status = HKF_STATUS_HOST_MATCHED;
                           else if ((options & HKF_WANT_MATCH_HOST) != 0)
                                   continue;
                           else if (s == -1) {
                                   debug2("%s: %s:%ld: bad host hash \"%.32s\"",
                                       __func__, path, linenum, lineinfo.hosts);
                                   goto bad;
                           }
                   }
   
                   /* Got a match.  Skip host name and any following whitespace */
                   for (; *cp2 == ' ' || *cp2 == '\t'; cp2++)
                           ;
                   if (*cp2 == '\0' || *cp2 == '#') {
                           debug2("%s:%ld: truncated before key", path, linenum);
                           goto bad;
                   }
                   lineinfo.rawkey = cp = cp2;
   
                   if ((options & HKF_WANT_PARSE_KEY) != 0) {
                           /*
                            * Extract the key from the line.  This will skip
                            * any leading whitespace.  Ignore badly formatted
                            * lines.
                            */
                           if ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) {
                                   error("%s: sshkey_new failed", __func__);
                                   return SSH_ERR_ALLOC_FAIL;
                           }
                           if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) {
   #ifdef WITH_SSH1
                                   sshkey_free(lineinfo.key);
                                   lineinfo.key = sshkey_new(KEY_RSA1);
                                   if (lineinfo.key  == NULL) {
                                           error("%s: sshkey_new fail", __func__);
                                           return SSH_ERR_ALLOC_FAIL;
                                   }
                                   if (!hostfile_read_key(&cp, &kbits,
                                       lineinfo.key))
                                           goto bad;
   #else
                                   goto bad;
   #endif
                           }
                           if (!hostfile_check_key(kbits, lineinfo.key, host,
                               path, linenum)) {
    bad:
                                   lineinfo.status = HKF_STATUS_INVALID;
                                   if ((r = callback(&lineinfo, ctx)) != 0)
                                           break;
                                   continue;
                           }
                   }
                   if ((r = callback(&lineinfo, ctx)) != 0)
                           break;
           }
           sshkey_free(lineinfo.key);
           fclose(f);
           return r;
 }  }

Legend:
Removed from v.1.59  
changed lines
  Added in v.1.60