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

Diff for /src/usr.bin/ssh/ssh-keygen.c between version 1.7 and 1.11

version 1.7, 1999/11/16 22:27:54 version 1.11, 1999/11/21 21:58:31
Line 19 
Line 19 
 #include "rsa.h"  #include "rsa.h"
 #include "ssh.h"  #include "ssh.h"
 #include "xmalloc.h"  #include "xmalloc.h"
   #include "fingerprint.h"
   
 /* Generated private key. */  /* Generated private key. */
 RSA *private_key;  RSA *private_key;
Line 40 
Line 41 
   
 int quiet = 0;  int quiet = 0;
   
 /* This is set to the identity file name if given on the command line. */  /* Flag indicating that we just want to see the key fingerprint */
 char *identity_file = NULL;  int print_fingerprint = 0;
   
   /* The identity file name, given on the command line or entered by the user. */
   char identity_file[1024];
   int have_identity = 0;
   
 /* This is set to the passphrase if given on the command line. */  /* This is set to the passphrase if given on the command line. */
 char *identity_passphrase = NULL;  char *identity_passphrase = NULL;
   
Line 52 
Line 57 
 /* This is set to the new comment if given on the command line. */  /* This is set to the new comment if given on the command line. */
 char *identity_comment = NULL;  char *identity_comment = NULL;
   
 /* Perform changing a passphrase.  The argument is the passwd structure  /* argv0 */
    for the current user. */  extern char *__progname;
   
 char *  void
 get_filename(struct passwd *pw, const char *prompt)  ask_filename(struct passwd *pw, const char *prompt)
 {  {
   char buf[1024], default_file[1024];    char buf[1024];
     snprintf(identity_file, sizeof(identity_file), "%s/%s",
              pw->pw_dir, SSH_CLIENT_IDENTITY);
     printf("%s (%s): ", prompt, identity_file);
     fflush(stdout);
     if (fgets(buf, sizeof(buf), stdin) == NULL)
       exit(1);
     if (strchr(buf, '\n'))
       *strchr(buf, '\n') = 0;
     if (strcmp(buf, "") != 0)
       strlcpy(identity_file, buf, sizeof(identity_file));
     have_identity = 1;
   }
   
   /* Read key file name. */  void
   if (identity_file != NULL) {  do_fingerprint(struct passwd *pw)
     return xstrdup(identity_file);  {
   } else {    char *comment;
     snprintf(default_file, sizeof default_file, "%s/%s",    RSA *public_key;
              pw->pw_dir, SSH_CLIENT_IDENTITY);    struct stat st;
     printf("%s (%s): ", prompt, default_file);  
     fflush(stdout);    if (!have_identity)
     if (fgets(buf, sizeof(buf), stdin) == NULL)      ask_filename(pw, "Enter file in which the key is");
     if (stat(identity_file, &st) < 0)
       {
         perror(identity_file);
       exit(1);        exit(1);
     if (strchr(buf, '\n'))      }
       *strchr(buf, '\n') = 0;    public_key = RSA_new();
     if (strcmp(buf, "") == 0)    if (!load_public_key(identity_file, public_key, &comment)) {
       return xstrdup(default_file);      char *cp, line[1024];
       BIGNUM *e, *n;
       int dummy, invalid = 0;
       FILE *f = fopen(identity_file, "r");
       n = BN_new();
       e = BN_new();
       if (f && fgets(line, sizeof(line), f)) {
         cp = line;
         line[strlen(line)-1] = '\0';
         if (auth_rsa_read_key(&cp, &dummy, e, n)) {
           public_key->e = e;
           public_key->n = n;
           comment = xstrdup(cp ? cp : "no comment");
         } else {
           invalid = 1;
         }
       } else {
         invalid = 1;
       }
       if (invalid) {
         printf("%s is not a valid key file.\n", identity_file);
         BN_free(e);
         BN_free(n);
         exit(1);
       }
   }    }
   return xstrdup(buf);  
     printf("%d %s %s\n", BN_num_bits(public_key->n),
            fingerprint(public_key->e, public_key->n),
            comment);
     RSA_free(public_key);
     exit(0);
 }  }
   
   /* Perform changing a passphrase.  The argument is the passwd structure
      for the current user. */
   
 void  void
 do_change_passphrase(struct passwd *pw)  do_change_passphrase(struct passwd *pw)
 {  {
   char *file, *comment;    char *comment;
   char *old_passphrase, *passphrase1, *passphrase2;    char *old_passphrase, *passphrase1, *passphrase2;
   struct stat st;    struct stat st;
   RSA *private_key;    RSA *private_key;
   
   file = get_filename(pw, "Enter file in which the key is");    if (!have_identity)
       ask_filename(pw, "Enter file in which the key is");
   /* Check if the file exists. */    /* Check if the file exists. */
   if (stat(file, &st) < 0)    if (stat(identity_file, &st) < 0)
     {      {
       perror(file);        perror(identity_file);
       exit(1);        exit(1);
     }      }
   
   /* Try to load the public key from the file the verify that it is    /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */       readable and of the proper format. */
   public_key = RSA_new();    public_key = RSA_new();
   if (!load_public_key(file, public_key, NULL))    if (!load_public_key(identity_file, public_key, NULL))
     {      {
       printf("%s is not a valid key file.\n", file);        printf("%s is not a valid key file.\n", identity_file);
       exit(1);        exit(1);
     }      }
   /* Clear the public key since we are just about to load the whole file. */    /* Clear the public key since we are just about to load the whole file. */
Line 107 
Line 160 
   
   /* Try to load the file with empty passphrase. */    /* Try to load the file with empty passphrase. */
   private_key = RSA_new();    private_key = RSA_new();
   if (!load_private_key(file, "", private_key, &comment)) {    if (!load_private_key(identity_file, "", private_key, &comment)) {
     /* Read passphrase from the user. */      /* Read passphrase from the user. */
     if (identity_passphrase)      if (identity_passphrase)
       old_passphrase = xstrdup(identity_passphrase);        old_passphrase = xstrdup(identity_passphrase);
     else      else
       old_passphrase = read_passphrase("Enter old passphrase: ", 1);        old_passphrase = read_passphrase("Enter old passphrase: ", 1);
     /* Try to load using the passphrase. */      /* Try to load using the passphrase. */
     if (!load_private_key(file, old_passphrase, private_key, &comment))      if (!load_private_key(identity_file, old_passphrase, private_key, &comment))
       {        {
         memset(old_passphrase, 0, strlen(old_passphrase));          memset(old_passphrase, 0, strlen(old_passphrase));
         xfree(old_passphrase);          xfree(old_passphrase);
Line 155 
Line 208 
     }      }
   
   /* Save the file using the new passphrase. */    /* Save the file using the new passphrase. */
   if (!save_private_key(file, passphrase1, private_key, comment))    if (!save_private_key(identity_file, passphrase1, private_key, comment))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              file, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));        memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);        xfree(passphrase1);
       RSA_free(private_key);        RSA_free(private_key);
Line 180 
Line 233 
 void  void
 do_change_comment(struct passwd *pw)  do_change_comment(struct passwd *pw)
 {  {
   char new_comment[1024], *file, *comment;    char new_comment[1024], *comment;
   RSA *private_key;    RSA *private_key;
   char *passphrase;    char *passphrase;
   struct stat st;    struct stat st;
   FILE *f;    FILE *f;
   char *tmpbuf;    char *tmpbuf;
   
   file = get_filename(pw, "Enter file in which the key is");    if (!have_identity)
       ask_filename(pw, "Enter file in which the key is");
   /* Check if the file exists. */    /* Check if the file exists. */
   if (stat(file, &st) < 0)    if (stat(identity_file, &st) < 0)
     {      {
       perror(file);        perror(identity_file);
       exit(1);        exit(1);
     }      }
   
   /* Try to load the public key from the file the verify that it is    /* Try to load the public key from the file the verify that it is
      readable and of the proper format. */       readable and of the proper format. */
   public_key = RSA_new();    public_key = RSA_new();
   if (!load_public_key(file, public_key, NULL))    if (!load_public_key(identity_file, public_key, NULL))
     {      {
       printf("%s is not a valid key file.\n", file);        printf("%s is not a valid key file.\n", identity_file);
       exit(1);        exit(1);
     }      }
   
   private_key = RSA_new();    private_key = RSA_new();
   /* Try to load the file with empty passphrase. */    /* Try to load the file with empty passphrase. */
   if (load_private_key(file, "", private_key, &comment))    if (load_private_key(identity_file, "", private_key, &comment))
     passphrase = xstrdup("");      passphrase = xstrdup("");
   else    else
     {      {
Line 219 
Line 273 
         else          else
           passphrase = read_passphrase("Enter passphrase: ", 1);            passphrase = read_passphrase("Enter passphrase: ", 1);
       /* Try to load using the passphrase. */        /* Try to load using the passphrase. */
       if (!load_private_key(file, passphrase, private_key, &comment))        if (!load_private_key(identity_file, passphrase, private_key, &comment))
         {          {
           memset(passphrase, 0, strlen(passphrase));            memset(passphrase, 0, strlen(passphrase));
           xfree(passphrase);            xfree(passphrase);
Line 250 
Line 304 
     }      }
   
   /* Save the file using the new passphrase. */    /* Save the file using the new passphrase. */
   if (!save_private_key(file, passphrase, private_key, new_comment))    if (!save_private_key(identity_file, passphrase, private_key, new_comment))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              file, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase, 0, strlen(passphrase));        memset(passphrase, 0, strlen(passphrase));
       xfree(passphrase);        xfree(passphrase);
       RSA_free(private_key);        RSA_free(private_key);
Line 268 
Line 322 
   
   /* Save the public key in text format in a file with the same name but    /* Save the public key in text format in a file with the same name but
      .pub appended. */       .pub appended. */
   strcat(file, ".pub");    strlcat(identity_file, ".pub", sizeof(identity_file));
   f = fopen(file, "w");    f = fopen(identity_file, "w");
   if (!f)    if (!f)
     {      {
       printf("Could not save your public key in %s\n", file);        printf("Could not save your public key in %s\n", identity_file);
       exit(1);        exit(1);
     }      }
   fprintf(f, "%d ", BN_num_bits(public_key->n));    fprintf(f, "%d ", BN_num_bits(public_key->n));
Line 290 
Line 344 
   exit(0);    exit(0);
 }  }
   
   void
   usage(void)
   {
     printf("ssh-keygen version %s\n", SSH_VERSION);
     printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", __progname);
     exit(1);
   }
   
 /* Main program for key management. */  /* Main program for key management. */
   
 int  int
 main(int ac, char **av)  main(int ac, char **av)
 {  {
   char buf[16384], buf2[1024], *passphrase1, *passphrase2;    char dotsshdir[16*1024], comment[1024], *passphrase1, *passphrase2;
   struct passwd *pw;    struct passwd *pw;
   char *file, *tmpbuf;    char *tmpbuf;
   int opt;    int opt;
   struct stat st;    struct stat st;
   FILE *f;    FILE *f;
Line 323 
Line 385 
       exit(1);        exit(1);
     }      }
   
   /* Create ~/.ssh directory if it doesn\'t already exist. */  
   snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_USER_DIR);  
   if (stat(buf, &st) < 0)  
     if (mkdir(buf, 0755) < 0)  
       error("Could not create directory '%s'.", buf);  
   
   /* Parse command line arguments. */    /* Parse command line arguments. */
   while ((opt = getopt(ac, av, "qpcb:f:P:N:C:")) != EOF)    while ((opt = getopt(ac, av, "qpclb:f:P:N:C:")) != EOF)
     {      {
       switch (opt)        switch (opt)
         {          {
Line 343 
Line 399 
             }              }
           break;            break;
   
           case 'l':
             print_fingerprint = 1;
             break;
   
         case 'p':          case 'p':
           change_passphrase = 1;            change_passphrase = 1;
           break;            break;
Line 352 
Line 412 
           break;            break;
   
         case 'f':          case 'f':
           identity_file = optarg;            strlcpy(identity_file, optarg, sizeof(identity_file));
             have_identity = 1;
           break;            break;
   
         case 'P':          case 'P':
Line 373 
Line 434 
   
         case '?':          case '?':
         default:          default:
           printf("ssh-keygen version %s\n", SSH_VERSION);            usage();
           printf("Usage: %s [-b bits] [-p] [-c] [-f file] [-P pass] [-N new-pass] [-C comment]\n", av[0]);  
           exit(1);  
         }          }
     }      }
   if (optind < ac)    if (optind < ac)
     {      {
       printf("Too many arguments.\n");        printf("Too many arguments.\n");
       exit(1);        usage();
     }      }
   if (change_passphrase && change_comment)    if (change_passphrase && change_comment)
     {      {
       printf("Can only have one of -p and -c.\n");        printf("Can only have one of -p and -c.\n");
       exit(1);        usage();
     }      }
   
     if (print_fingerprint)
       do_fingerprint(pw);
   
   /* If the user requested to change the passphrase, do it now.  This    /* If the user requested to change the passphrase, do it now.  This
      function never returns. */       function never returns. */
   if (change_passphrase)    if (change_passphrase)
Line 409 
Line 471 
   public_key = RSA_new();    public_key = RSA_new();
   rsa_generate_key(private_key, public_key, bits);    rsa_generate_key(private_key, public_key, bits);
   
  ask_file_again:    if (!have_identity)
       ask_filename(pw, "Enter file in which to save the key");
   
   file = get_filename(pw, "Enter file in which to save the key");    /* Create ~/.ssh directory if it doesn\'t already exist. */
     snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, SSH_USER_DIR);
     if (strstr(identity_file, dotsshdir) != NULL &&
         stat(dotsshdir, &st) < 0) {
       if (mkdir(dotsshdir, 0755) < 0)
         error("Could not create directory '%s'.", dotsshdir);
       else if(!quiet)
         printf("Created directory '%s'.\n", dotsshdir);
    }
   
   /* If the file aready exists, ask the user to confirm. */    /* If the file already exists, ask the user to confirm. */
   if (stat(file, &st) >= 0)    if (stat(identity_file, &st) >= 0)
     {      {
       printf("%s already exists.\n", file);        char yesno[3];
         printf("%s already exists.\n", identity_file);
       printf("Overwrite (y/n)? ");        printf("Overwrite (y/n)? ");
       fflush(stdout);        fflush(stdout);
       if (fgets(buf2, sizeof(buf2), stdin) == NULL)        if (fgets(yesno, sizeof(yesno), stdin) == NULL)
         exit(1);          exit(1);
       if (buf2[0] != 'y' && buf2[0] != 'Y')        if (yesno[0] != 'y' && yesno[0] != 'Y')
         exit(1);          exit(1);
     }      }
   
Line 456 
Line 528 
      edit this field. */       edit this field. */
   if (identity_comment)    if (identity_comment)
     {      {
       strlcpy(buf2, identity_comment, sizeof(buf2));        strlcpy(comment, identity_comment, sizeof(comment));
     }      }
   else    else
     {      {
Line 465 
Line 537 
           perror("gethostname");            perror("gethostname");
           exit(1);            exit(1);
         }          }
       snprintf(buf2, sizeof buf2, "%s@%s", pw->pw_name, hostname);        snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname);
     }      }
   
   /* Save the key with the given passphrase and comment. */    /* Save the key with the given passphrase and comment. */
   if (!save_private_key(file, passphrase1, private_key, buf2))    if (!save_private_key(identity_file, passphrase1, private_key, comment))
     {      {
       printf("Saving the key failed: %s: %s.\n",        printf("Saving the key failed: %s: %s.\n",
              file, strerror(errno));               identity_file, strerror(errno));
       memset(passphrase1, 0, strlen(passphrase1));        memset(passphrase1, 0, strlen(passphrase1));
       xfree(passphrase1);        xfree(passphrase1);
       xfree(file);        exit(1);
       goto ask_file_again;  
     }      }
   /* Clear the passphrase. */    /* Clear the passphrase. */
   memset(passphrase1, 0, strlen(passphrase1));    memset(passphrase1, 0, strlen(passphrase1));
Line 487 
Line 558 
   arc4random_stir();    arc4random_stir();
   
   if (!quiet)    if (!quiet)
     printf("Your identification has been saved in %s.\n", file);      printf("Your identification has been saved in %s.\n", identity_file);
   
   /* Display the public key on the screen. */  
   if (!quiet) {  
     printf("Your public key is:\n");  
     printf("%d ", BN_num_bits(public_key->n));  
     tmpbuf = BN_bn2dec(public_key->e);  
     printf("%s ", tmpbuf);  
     free(tmpbuf);  
     tmpbuf = BN_bn2dec(public_key->n);  
     printf("%s %s\n", tmpbuf, buf2);  
     free(tmpbuf);  
   }  
   
   /* Save the public key in text format in a file with the same name but    /* Save the public key in text format in a file with the same name but
      .pub appended. */       .pub appended. */
   strcat(file, ".pub");    strlcat(identity_file, ".pub", sizeof(identity_file));
   f = fopen(file, "w");    f = fopen(identity_file, "w");
   if (!f)    if (!f)
     {      {
       printf("Could not save your public key in %s\n", file);        printf("Could not save your public key in %s\n", identity_file);
       exit(1);        exit(1);
     }      }
   fprintf(f, "%d ", BN_num_bits(public_key->n));    fprintf(f, "%d ", BN_num_bits(public_key->n));
Line 515 
Line 574 
   fprintf(f, "%s ", tmpbuf);    fprintf(f, "%s ", tmpbuf);
   free(tmpbuf);    free(tmpbuf);
   tmpbuf = BN_bn2dec(public_key->n);    tmpbuf = BN_bn2dec(public_key->n);
   fprintf(f, "%s %s\n", tmpbuf, buf2);    fprintf(f, "%s %s\n", tmpbuf, comment);
   free(tmpbuf);    free(tmpbuf);
   fclose(f);    fclose(f);
   
   if (!quiet)    if (!quiet) {
     printf("Your public key has been saved in %s\n", file);      printf("Your public key has been saved in %s.\n", identity_file);
       printf("The key fingerprint is:\n");
       printf("%d %s %s\n", BN_num_bits(public_key->n),
              fingerprint(public_key->e, public_key->n),
              comment);
     }
   
   exit(0);    exit(0);
 }  }

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.11