[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.32 and 1.32.4.1

version 1.32, 2003/11/10 16:23:41 version 1.32.4.1, 2005/03/10 16:28:27
Line 38 
Line 38 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
   #include <resolv.h>
   #include <openssl/hmac.h>
   #include <openssl/sha.h>
   
 #include "packet.h"  #include "packet.h"
 #include "match.h"  #include "match.h"
 #include "key.h"  #include "key.h"
 #include "hostfile.h"  #include "hostfile.h"
 #include "log.h"  #include "log.h"
   #include "xmalloc.h"
   
   static int
   extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
   {
           char *p, *b64salt;
           u_int b64len;
           int ret;
   
           if (l < sizeof(HASH_MAGIC) - 1) {
                   debug2("extract_salt: string too short");
                   return (-1);
           }
           if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) {
                   debug2("extract_salt: invalid magic identifier");
                   return (-1);
           }
           s += sizeof(HASH_MAGIC) - 1;
           l -= sizeof(HASH_MAGIC) - 1;
           if ((p = memchr(s, HASH_DELIM, l)) == NULL) {
                   debug2("extract_salt: missing salt termination character");
                   return (-1);
           }
   
           b64len = p - s;
           /* Sanity check */
           if (b64len == 0 || b64len > 1024) {
                   debug2("extract_salt: bad encoded salt length %u", b64len);
                   return (-1);
           }
           b64salt = xmalloc(1 + b64len);
           memcpy(b64salt, s, b64len);
           b64salt[b64len] = '\0';
   
           ret = __b64_pton(b64salt, salt, salt_len);
           xfree(b64salt);
           if (ret == -1) {
                   debug2("extract_salt: salt decode error");
                   return (-1);
           }
           if (ret != SHA_DIGEST_LENGTH) {
                   debug2("extract_salt: expected salt len %u, got %u",
                       salt_len, ret);
                   return (-1);
           }
   
           return (0);
   }
   
   char *
   host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
   {
           const EVP_MD *md = EVP_sha1();
           HMAC_CTX mac_ctx;
           char salt[256], result[256], uu_salt[512], uu_result[512];
           static char encoded[1024];
           u_int i, len;
   
           len = EVP_MD_size(md);
   
           if (name_from_hostfile == NULL) {
                   /* Create new salt */
                   for (i = 0; i < len; i++)
                           salt[i] = arc4random();
           } else {
                   /* Extract salt from known host entry */
                   if (extract_salt(name_from_hostfile, src_len, salt,
                       sizeof(salt)) == -1)
                           return (NULL);
           }
   
           HMAC_Init(&mac_ctx, salt, len, md);
           HMAC_Update(&mac_ctx, host, strlen(host));
           HMAC_Final(&mac_ctx, result, NULL);
           HMAC_cleanup(&mac_ctx);
   
           if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
               __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
                   fatal("host_hash: __b64_ntop failed");
   
           snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
               HASH_DELIM, uu_result);
   
           return (encoded);
   }
   
 /*  /*
  * Parses an RSA (number of bits, e, n) or DSA key from a string.  Moves the   * Parses an RSA (number of bits, e, n) or DSA key from a string.  Moves the
  * pointer over the key.  Skips any whitespace at the beginning and at end.   * pointer over the key.  Skips any whitespace at the beginning and at end.
Line 104 
Line 193 
         char line[8192];          char line[8192];
         int linenum = 0;          int linenum = 0;
         u_int kbits;          u_int kbits;
         char *cp, *cp2;          char *cp, *cp2, *hashed_host;
         HostStatus end_return;          HostStatus end_return;
   
         debug3("check_host_in_hostfile: filename %s", filename);          debug3("check_host_in_hostfile: filename %s", filename);
Line 137 
Line 226 
                         ;                          ;
   
                 /* Check if the host name matches. */                  /* Check if the host name matches. */
                 if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1)                  if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
                         continue;                          if (*cp != HASH_DELIM)
                                   continue;
                           hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
                           if (hashed_host == NULL) {
                                   debug("Invalid hashed host line %d of %s",
                                       linenum, filename);
                                   continue;
                           }
                           if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
                                   continue;
                   }
   
                 /* Got a match.  Skip host name. */                  /* Got a match.  Skip host name. */
                 cp = cp2;                  cp = cp2;
Line 211 
Line 310 
  */   */
   
 int  int
 add_host_to_hostfile(const char *filename, const char *host, const Key *key)  add_host_to_hostfile(const char *filename, const char *host, const Key *key,
       int store_hash)
 {  {
         FILE *f;          FILE *f;
         int success = 0;          int success = 0;
           char *hashed_host;
   
         if (key == NULL)          if (key == NULL)
                 return 1;       /* XXX ? */                  return 1;       /* XXX ? */
         f = fopen(filename, "a");          f = fopen(filename, "a");
         if (!f)          if (!f)
                 return 0;                  return 0;
         fprintf(f, "%s ", host);  
           if (store_hash) {
                   if ((hashed_host = host_hash(host, NULL, 0)) == NULL) {
                           error("add_host_to_hostfile: host_hash failed");
                           fclose(f);
                           return 0;
                   }
           }
           fprintf(f, "%s ", store_hash ? hashed_host : host);
   
         if (key_write(key, f)) {          if (key_write(key, f)) {
                 success = 1;                  success = 1;
         } else {          } else {

Legend:
Removed from v.1.32  
changed lines
  Added in v.1.32.4.1