[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.13 and 1.14

version 1.13, 2000/02/18 10:20:20 version 1.14, 2000/03/23 22:15:33
Line 17 
Line 17 
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include "packet.h"  #include "packet.h"
   #include "match.h"
 #include "ssh.h"  #include "ssh.h"
   #include <ssl/rsa.h>
   #include <ssl/dsa.h>
   #include "key.h"
   #include "hostfile.h"
   
 /*  /*
  * Reads a multiple-precision integer in decimal from the buffer, and advances   * Parses an RSA (number of bits, e, n) or DSA key from a string.  Moves the
  * the pointer.  The integer must already be initialized.  This function is   * pointer over the key.  Skips any whitespace at the beginning and at end.
  * permitted to modify the buffer.  This leaves *cpp to point just beyond the  
  * last processed (and maybe modified) character.  Note that this may modify  
  * the buffer containing the number.  
  */   */
   
 int  int
 auth_rsa_read_bignum(char **cpp, BIGNUM * value)  hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
 {  {
         char *cp = *cpp;  
         int old;  
   
         /* Skip any leading whitespace. */  
         for (; *cp == ' ' || *cp == '\t'; cp++)  
                 ;  
   
         /* Check that it begins with a decimal digit. */  
         if (*cp < '0' || *cp > '9')  
                 return 0;  
   
         /* Save starting position. */  
         *cpp = cp;  
   
         /* Move forward until all decimal digits skipped. */  
         for (; *cp >= '0' && *cp <= '9'; cp++)  
                 ;  
   
         /* Save the old terminating character, and replace it by \0. */  
         old = *cp;  
         *cp = 0;  
   
         /* Parse the number. */  
         if (BN_dec2bn(&value, *cpp) == 0)  
                 return 0;  
   
         /* Restore old terminating character. */  
         *cp = old;  
   
         /* Move beyond the number and return success. */  
         *cpp = cp;  
         return 1;  
 }  
   
 /*  
  * Parses an RSA key (number of bits, e, n) from a string.  Moves the pointer  
  * over the key.  Skips any whitespace at the beginning and at end.  
  */  
   
 int  
 auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)  
 {  
         unsigned int bits;          unsigned int bits;
         char *cp;          char *cp;
   
Line 85 
Line 45 
         for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)          for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
                 bits = 10 * bits + *cp - '0';                  bits = 10 * bits + *cp - '0';
   
         /* Get public exponent. */          if (!key_read(ret, bits, &cp))
         if (!auth_rsa_read_bignum(&cp, e))  
                 return 0;                  return 0;
   
         /* Get public modulus. */  
         if (!auth_rsa_read_bignum(&cp, n))  
                 return 0;  
   
         /* Skip trailing whitespace. */          /* Skip trailing whitespace. */
         for (; *cp == ' ' || *cp == '\t'; cp++)          for (; *cp == ' ' || *cp == '\t'; cp++)
                 ;                  ;
Line 103 
Line 58 
         return 1;          return 1;
 }  }
   
 /*  
  * Tries to match the host name (which must be in all lowercase) against the  
  * comma-separated sequence of subpatterns (each possibly preceded by ! to  
  * indicate negation).  Returns true if there is a positive match; zero  
  * otherwise.  
  */  
   
 int  int
 match_hostname(const char *host, const char *pattern, unsigned int len)  auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
 {  {
         char sub[1024];          Key *k = key_new(KEY_RSA);
         int negated;          int ret = hostfile_read_key(cpp, bitsp, k);
         int got_positive;          BN_copy(e, k->rsa->e);
         unsigned int i, subi;          BN_copy(n, k->rsa->n);
           key_free(k);
           return ret;
   }
   
         got_positive = 0;  int
         for (i = 0; i < len;) {  hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
                 /* Check if the subpattern is negated. */  {
                 if (pattern[i] == '!') {          if (key == NULL || key->type != KEY_RSA || key->rsa == NULL)
                         negated = 1;                  return 1;
                         i++;          if (bits != BN_num_bits(key->rsa->n)) {
                 } else                  error("Warning: %s, line %d: keysize mismatch for host %s: "
                         negated = 0;                      "actual %d vs. announced %d.",
                       filename, linenum, host, BN_num_bits(key->rsa->n), bits);
                 /*                  error("Warning: replace %d with %d in %s, line %d.",
                  * Extract the subpattern up to a comma or end.  Convert the                      bits, BN_num_bits(key->rsa->n), filename, linenum);
                  * subpattern to lowercase.  
                  */  
                 for (subi = 0;  
                      i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';  
                      subi++, i++)  
                         sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];  
                 /* If subpattern too long, return failure (no match). */  
                 if (subi >= sizeof(sub) - 1)  
                         return 0;  
   
                 /* If the subpattern was terminated by a comma, skip the comma. */  
                 if (i < len && pattern[i] == ',')  
                         i++;  
   
                 /* Null-terminate the subpattern. */  
                 sub[subi] = '\0';  
   
                 /* Try to match the subpattern against the host name. */  
                 if (match_pattern(host, sub)) {  
                         if (negated)  
                                 return 0;       /* Fail */  
                         else  
                                 got_positive = 1;  
                 }  
         }          }
           return 1;
         /*  
          * Return success if got a positive match.  If there was a negative  
          * match, we have already returned zero and never get here.  
          */  
         return got_positive;  
 }  }
   
 /*  /*
Line 170 
Line 92 
  */   */
   
 HostStatus  HostStatus
 check_host_in_hostfile(const char *filename, const char *host,  check_host_in_hostfile(const char *filename, const char *host, Key *key, Key *found)
                        BIGNUM * e, BIGNUM * n, BIGNUM * ke, BIGNUM * kn)  
 {  {
         FILE *f;          FILE *f;
         char line[8192];          char line[8192];
Line 180 
Line 101 
         char *cp, *cp2;          char *cp, *cp2;
         HostStatus end_return;          HostStatus end_return;
   
           if (key == NULL)
                   fatal("no key to look up");
         /* Open the file containing the list of known hosts. */          /* Open the file containing the list of known hosts. */
         f = fopen(filename, "r");          f = fopen(filename, "r");
         if (!f)          if (!f)
Line 221 
Line 144 
                  * Extract the key from the line.  This will skip any leading                   * Extract the key from the line.  This will skip any leading
                  * whitespace.  Ignore badly formatted lines.                   * whitespace.  Ignore badly formatted lines.
                  */                   */
                 if (!auth_rsa_read_key(&cp, &kbits, ke, kn))                  if (!hostfile_read_key(&cp, &kbits, found))
                         continue;                          continue;
                   if (!hostfile_check_key(kbits, found, host, filename, linenum))
                           continue;
   
                 if (kbits != BN_num_bits(kn)) {  
                         error("Warning: %s, line %d: keysize mismatch for host %s: "  
                               "actual %d vs. announced %d.",  
                               filename, linenum, host, BN_num_bits(kn), kbits);  
                         error("Warning: replace %d with %d in %s, line %d.",  
                               kbits, BN_num_bits(kn), filename, linenum);  
                 }  
                 /* Check if the current key is the same as the given key. */                  /* Check if the current key is the same as the given key. */
                 if (BN_cmp(ke, e) == 0 && BN_cmp(kn, n) == 0) {                  if (key_equal(key, found)) {
                         /* Ok, they match. */                          /* Ok, they match. */
                         fclose(f);                          fclose(f);
                         return HOST_OK;                          return HOST_OK;
Line 260 
Line 178 
  */   */
   
 int  int
 add_host_to_hostfile(const char *filename, const char *host,  add_host_to_hostfile(const char *filename, const char *host, Key *key)
                      BIGNUM * e, BIGNUM * n)  
 {  {
         FILE *f;          FILE *f;
         char *buf;          int success = 0;
         unsigned int bits;  
   
           if (key == NULL)
                   return 1;
   
         /* Open the file for appending. */          /* Open the file for appending. */
         f = fopen(filename, "a");          f = fopen(filename, "a");
         if (!f)          if (!f)
                 return 0;                  return 0;
   
         /* size of modulus 'n' */          fprintf(f, "%s ", host);
         bits = BN_num_bits(n);          if (key_write(key, f)) {
                   fprintf(f, "\n");
         /* Print the host name and key to the file. */                  success = 1;
         fprintf(f, "%s %u ", host, bits);          } else {
         buf = BN_bn2dec(e);                  error("add_host_to_hostfile: saving key failed");
         if (buf == NULL) {  
                 error("add_host_to_hostfile: BN_bn2dec(e) failed");  
                 fclose(f);  
                 return 0;  
         }          }
         fprintf(f, "%s ", buf);  
         free(buf);  
         buf = BN_bn2dec(n);  
         if (buf == NULL) {  
                 error("add_host_to_hostfile: BN_bn2dec(n) failed");  
                 fclose(f);  
                 return 0;  
         }  
         fprintf(f, "%s\n", buf);  
         free(buf);  
   
         /* Close the file. */          /* Close the file. */
         fclose(f);          fclose(f);
         return 1;          return success;
 }  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14