diff options
author | Damien Miller <djm@mindrot.org> | 1999-11-17 17:29:08 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-11-17 17:29:08 +1100 |
commit | 10f6f6ba9ee14d306f8780edee8a10640c1643e0 (patch) | |
tree | 859600c705d582b147162d73746cb2f39b59ed58 /ssh-keygen.c | |
parent | d743bba481056ba3d1c229c18fd42c6bdc3f8d74 (diff) | |
download | openssh-git-10f6f6ba9ee14d306f8780edee8a10640c1643e0.tar.gz |
- Merged OpenBSD CVS changes
- [ChangeLog.Ylonen] noone needs this anymore
- [authfd.c] close-on-exec for auth-socket, ok deraadt
- [hostfile.c]
in known_hosts key lookup the entry for the bits does not need
to match, all the information is contained in n and e. This
solves the problem with buggy servers announcing the wrong
modulus length. markus and me.
- [serverloop.c]
bugfix: check for space if child has terminated, from:
iedowse@maths.tcd.ie
- [ssh-add.1 ssh-add.c ssh-keygen.1 ssh-keygen.c sshconnect.c]
[fingerprint.c fingerprint.h]
rsa key fingerprints, idea from Bjoern Groenvall <bg@sics.se>
- [ssh-agent.1] typo
- [ssh.1] add OpenSSH information to AUTHOR section. okay markus@
- [sshd.c]
force logging to stderr while loading private key file
(lost while converting to new log-levels)
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r-- | ssh-keygen.c | 198 |
1 files changed, 117 insertions, 81 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c index 10289cab..deb08dd9 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -14,11 +14,12 @@ Identity and host key generation and maintenance. */ #include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.4 1999/11/15 06:10:57 damien Exp $"); +RCSID("$Id: ssh-keygen.c,v 1.5 1999/11/17 06:29:08 damien Exp $"); #include "rsa.h" #include "ssh.h" #include "xmalloc.h" +#include "fingerprint.h" #ifdef HAVE___PROGNAME extern char *__progname; @@ -46,6 +47,9 @@ int change_comment = 0; int quiet = 0; +/* Flag indicating that we just want to see the key fingerprint */ +int print_fingerprint = 0; + /* This is set to the identity file name if given on the command line. */ char *identity_file = NULL; @@ -61,42 +65,101 @@ char *identity_comment = NULL; /* Perform changing a passphrase. The argument is the passwd structure for the current user. */ -void -do_change_passphrase(struct passwd *pw) +char * +get_filename(struct passwd *pw, const char *prompt) { - char buf[1024], *comment; - char *old_passphrase, *passphrase1, *passphrase2; - struct stat st; - RSA *private_key; + char buf[1024], default_file[1024]; /* Read key file name. */ if (identity_file != NULL) { - strncpy(buf, identity_file, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; + return xstrdup(identity_file); } else { - printf("Enter file in which the key is ($HOME/%s): ", SSH_CLIENT_IDENTITY); + snprintf(default_file, sizeof default_file, "%s/%s", + pw->pw_dir, SSH_CLIENT_IDENTITY); + printf("%s (%s): ", prompt, default_file); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) exit(1); if (strchr(buf, '\n')) *strchr(buf, '\n') = 0; if (strcmp(buf, "") == 0) - snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); + return xstrdup(default_file); } + return xstrdup(buf); +} +void +do_fingerprint(struct passwd *pw) +{ + char *file, *comment; + RSA *public_key; + struct stat st; + + file = get_filename(pw, "Enter file in which the key is"); + if (stat(file, &st) < 0) + { + perror(file); + exit(1); + } + public_key = RSA_new(); + if (!load_public_key(file, public_key, &comment)) { + char *cp, line[1024]; + BIGNUM *e, *n; + int dummy, invalid = 0; + FILE *f = fopen(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", file); + BN_free(e); + BN_free(n); + exit(1); + } + } + + 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); +} + + +void +do_change_passphrase(struct passwd *pw) +{ + char *file, *comment; + char *old_passphrase, *passphrase1, *passphrase2; + struct stat st; + RSA *private_key; + + file = get_filename(pw, "Enter file in which the key is"); /* Check if the file exists. */ - if (stat(buf, &st) < 0) + if (stat(file, &st) < 0) { - perror(buf); + perror(file); exit(1); } /* Try to load the public key from the file the verify that it is readable and of the proper format. */ public_key = RSA_new(); - if (!load_public_key(buf, public_key, NULL)) + if (!load_public_key(file, public_key, NULL)) { - printf("%s is not a valid key file.\n", buf); + printf("%s is not a valid key file.\n", file); exit(1); } /* Clear the public key since we are just about to load the whole file. */ @@ -104,14 +167,14 @@ do_change_passphrase(struct passwd *pw) /* Try to load the file with empty passphrase. */ private_key = RSA_new(); - if (!load_private_key(buf, "", private_key, &comment)) { + if (!load_private_key(file, "", private_key, &comment)) { /* Read passphrase from the user. */ if (identity_passphrase) old_passphrase = xstrdup(identity_passphrase); else old_passphrase = read_passphrase("Enter old passphrase: ", 1); /* Try to load using the passphrase. */ - if (!load_private_key(buf, old_passphrase, private_key, &comment)) + if (!load_private_key(file, old_passphrase, private_key, &comment)) { memset(old_passphrase, 0, strlen(old_passphrase)); xfree(old_passphrase); @@ -152,10 +215,10 @@ do_change_passphrase(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!save_private_key(buf, passphrase1, private_key, comment)) + if (!save_private_key(file, passphrase1, private_key, comment)) { printf("Saving the key failed: %s: %s.\n", - buf, strerror(errno)); + file, strerror(errno)); memset(passphrase1, 0, strlen(passphrase1)); xfree(passphrase1); RSA_free(private_key); @@ -177,51 +240,33 @@ do_change_passphrase(struct passwd *pw) void do_change_comment(struct passwd *pw) { - char buf[1024], new_comment[1024], *comment; + char new_comment[1024], *file, *comment; RSA *private_key; char *passphrase; struct stat st; FILE *f; char *tmpbuf; - /* Read key file name. */ - if (identity_file) - { - strncpy(buf, identity_file, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - } - else - { - printf("Enter file in which the key is ($HOME/%s): ", - SSH_CLIENT_IDENTITY); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) - exit(1); - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; - if (strcmp(buf, "") == 0) - snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); - } - + file = get_filename(pw, "Enter file in which the key is"); /* Check if the file exists. */ - if (stat(buf, &st) < 0) + if (stat(file, &st) < 0) { - perror(buf); + perror(file); exit(1); } /* Try to load the public key from the file the verify that it is readable and of the proper format. */ public_key = RSA_new(); - if (!load_public_key(buf, public_key, NULL)) + if (!load_public_key(file, public_key, NULL)) { - printf("%s is not a valid key file.\n", buf); + printf("%s is not a valid key file.\n", file); exit(1); } private_key = RSA_new(); /* Try to load the file with empty passphrase. */ - if (load_private_key(buf, "", private_key, &comment)) + if (load_private_key(file, "", private_key, &comment)) passphrase = xstrdup(""); else { @@ -234,7 +279,7 @@ do_change_comment(struct passwd *pw) else passphrase = read_passphrase("Enter passphrase: ", 1); /* Try to load using the passphrase. */ - if (!load_private_key(buf, passphrase, private_key, &comment)) + if (!load_private_key(file, passphrase, private_key, &comment)) { memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); @@ -246,8 +291,7 @@ do_change_comment(struct passwd *pw) if (identity_comment) { - strncpy(new_comment, identity_comment, sizeof(new_comment)); - new_comment[sizeof(new_comment) - 1] = '\0'; + strlcpy(new_comment, identity_comment, sizeof(new_comment)); } else { @@ -266,10 +310,10 @@ do_change_comment(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!save_private_key(buf, passphrase, private_key, new_comment)) + if (!save_private_key(file, passphrase, private_key, new_comment)) { printf("Saving the key failed: %s: %s.\n", - buf, strerror(errno)); + file, strerror(errno)); memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); RSA_free(private_key); @@ -284,11 +328,11 @@ do_change_comment(struct passwd *pw) /* Save the public key in text format in a file with the same name but .pub appended. */ - strcat(buf, ".pub"); - f = fopen(buf, "w"); + strcat(file, ".pub"); + f = fopen(file, "w"); if (!f) { - printf("Could not save your public key in %s\n", buf); + printf("Could not save your public key in %s\n", file); exit(1); } fprintf(f, "%d ", BN_num_bits(public_key->n)); @@ -313,7 +357,7 @@ main(int ac, char **av) { char buf[16384], buf2[1024], *passphrase1, *passphrase2; struct passwd *pw; - char *tmpbuf; + char *file, *tmpbuf; int opt; struct stat st; FILE *f; @@ -323,6 +367,7 @@ main(int ac, char **av) /* check if RSA support exists */ if (rsa_alive() == 0) { + extern char *__progname; fprintf(stderr, "%s: no RSA support in libssl and libcrypto. See ssl(8).\n", @@ -345,7 +390,7 @@ main(int ac, char **av) error("Could not create directory '%s'.", buf); /* 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) { @@ -358,6 +403,10 @@ main(int ac, char **av) } break; + case 'l': + print_fingerprint = 1; + break; + case 'p': change_passphrase = 1; break; @@ -404,6 +453,9 @@ main(int ac, char **av) exit(1); } + if (print_fingerprint) + do_fingerprint(pw); + /* If the user requested to change the passphrase, do it now. This function never returns. */ if (change_passphrase) @@ -426,29 +478,12 @@ main(int ac, char **av) ask_file_again: - /* Ask for a file to save the key in. */ - if (identity_file) - { - strncpy(buf, identity_file, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - } - else - { - printf("Enter file in which to save the key ($HOME/%s): ", - SSH_CLIENT_IDENTITY); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) - exit(1); - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; - if (strcmp(buf, "") == 0) - snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY); - } + file = get_filename(pw, "Enter file in which to save the key"); /* If the file aready exists, ask the user to confirm. */ - if (stat(buf, &st) >= 0) + if (stat(file, &st) >= 0) { - printf("%s already exists.\n", buf); + printf("%s already exists.\n", file); printf("Overwrite (y/n)? "); fflush(stdout); if (fgets(buf2, sizeof(buf2), stdin) == NULL) @@ -501,12 +536,13 @@ main(int ac, char **av) } /* Save the key with the given passphrase and comment. */ - if (!save_private_key(buf, passphrase1, private_key, buf2)) + if (!save_private_key(file, passphrase1, private_key, buf2)) { printf("Saving the key failed: %s: %s.\n", - buf, strerror(errno)); + file, strerror(errno)); memset(passphrase1, 0, strlen(passphrase1)); xfree(passphrase1); + xfree(file); goto ask_file_again; } /* Clear the passphrase. */ @@ -518,7 +554,7 @@ main(int ac, char **av) arc4random_stir(); if (!quiet) - printf("Your identification has been saved in %s.\n", buf); + printf("Your identification has been saved in %s.\n", file); /* Display the public key on the screen. */ if (!quiet) { @@ -534,11 +570,11 @@ main(int ac, char **av) /* Save the public key in text format in a file with the same name but .pub appended. */ - strcat(buf, ".pub"); - f = fopen(buf, "w"); + strcat(file, ".pub"); + f = fopen(file, "w"); if (!f) { - printf("Could not save your public key in %s\n", buf); + printf("Could not save your public key in %s\n", file); exit(1); } fprintf(f, "%d ", BN_num_bits(public_key->n)); @@ -551,7 +587,7 @@ main(int ac, char **av) fclose(f); if (!quiet) - printf("Your public key has been saved in %s\n", buf); + printf("Your public key has been saved in %s\n", file); exit(0); } |