From 431f66b68c98e9db87574860a0a29d8d8aa9b52c Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 21 Nov 1999 18:31:57 +1100 Subject: [PATCH] - [OVERVIEW README] typos; green@freebsd - [ssh-keygen.c] replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) exit if writing the key fails (no infinit loop) print usage() everytime we get bad options - [ssh-keygen.c] overflow, djm@mindrot.org - [sshd.c] fix sigchld race; cjc5@po.cwru.edu --- ChangeLog | 9 ++- OVERVIEW | 2 +- ssh-keygen.c | 158 ++++++++++++++++++++++++++------------------------- sshd.c | 7 ++- 4 files changed, 95 insertions(+), 81 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a7b120a0..21d6358a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,14 @@ [channels.c clientloop.c] SSH_CMSG_MAX_PACKET_SIZE, some clients use this, some need this, niels@ [hope this time my ISP stays alive during commit] - + - [OVERVIEW README] typos; green@freebsd + - [ssh-keygen.c] + replace xstrdup+strcat with strlcat+fixed buffer, fixes OF (bad me) + exit if writing the key fails (no infinit loop) + print usage() everytime we get bad options + - [ssh-keygen.c] overflow, djm@mindrot.org + - [sshd.c] fix sigchld race; cjc5@po.cwru.edu + 19991120 - Merged more Solaris support from Marc G. Fournier diff --git a/OVERVIEW b/OVERVIEW index a8b67e4e2..7f34ac45b 100644 --- a/OVERVIEW +++ b/OVERVIEW @@ -1,4 +1,4 @@ -This document is inteded for those who wish to read the ssh source +This document is intended for those who wish to read the ssh source code. This tries to give an overview of the structure of the code. Copyright (c) 1995 Tatu Ylonen diff --git a/ssh-keygen.c b/ssh-keygen.c index 21b61b44b..596da76fb 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -14,7 +14,7 @@ Identity and host key generation and maintenance. */ #include "includes.h" -RCSID("$Id: ssh-keygen.c,v 1.6 1999/11/20 06:02:56 damien Exp $"); +RCSID("$Id: ssh-keygen.c,v 1.7 1999/11/21 07:31:57 damien Exp $"); #include "rsa.h" #include "ssh.h" @@ -50,8 +50,9 @@ 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; +/* 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. */ char *identity_passphrase = NULL; @@ -62,51 +63,46 @@ char *identity_new_passphrase = NULL; /* This is set to the new comment if given on the command line. */ char *identity_comment = NULL; -/* Perform changing a passphrase. The argument is the passwd structure - for the current user. */ +/* argv0 */ +extern char *__progname; -char * -get_filename(struct passwd *pw, const char *prompt) +void +ask_filename(struct passwd *pw, const char *prompt) { - char buf[1024], default_file[1024]; - - /* Read key file name. */ - if (identity_file != NULL) { - return xstrdup(identity_file); - } else { - 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) - return xstrdup(default_file); - } - return xstrdup(buf); + 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; } void do_fingerprint(struct passwd *pw) { - char *file, *comment; + char *comment; RSA *public_key; struct stat st; - file = get_filename(pw, "Enter file in which the key is"); - if (stat(file, &st) < 0) + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { - perror(file); + perror(identity_file); exit(1); } public_key = RSA_new(); - if (!load_public_key(file, public_key, &comment)) { + if (!load_public_key(identity_file, public_key, &comment)) { char *cp, line[1024]; BIGNUM *e, *n; int dummy, invalid = 0; - FILE *f = fopen(file, "r"); + FILE *f = fopen(identity_file, "r"); n = BN_new(); e = BN_new(); if (f && fgets(line, sizeof(line), f)) { @@ -123,7 +119,7 @@ do_fingerprint(struct passwd *pw) invalid = 1; } if (invalid) { - printf("%s is not a valid key file.\n", file); + printf("%s is not a valid key file.\n", identity_file); BN_free(e); BN_free(n); exit(1); @@ -137,29 +133,32 @@ do_fingerprint(struct passwd *pw) exit(0); } +/* Perform changing a passphrase. The argument is the passwd structure + for the current user. */ void do_change_passphrase(struct passwd *pw) { - char *file, *comment; + char *comment; char *old_passphrase, *passphrase1, *passphrase2; struct stat st; 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. */ - if (stat(file, &st) < 0) + if (stat(identity_file, &st) < 0) { - perror(file); + perror(identity_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(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); } /* Clear the public key since we are just about to load the whole file. */ @@ -167,14 +166,14 @@ do_change_passphrase(struct passwd *pw) /* Try to load the file with empty passphrase. */ 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. */ 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(file, old_passphrase, private_key, &comment)) + if (!load_private_key(identity_file, old_passphrase, private_key, &comment)) { memset(old_passphrase, 0, strlen(old_passphrase)); xfree(old_passphrase); @@ -215,10 +214,10 @@ do_change_passphrase(struct passwd *pw) } /* 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", - file, strerror(errno)); + identity_file, strerror(errno)); memset(passphrase1, 0, strlen(passphrase1)); xfree(passphrase1); RSA_free(private_key); @@ -240,33 +239,34 @@ do_change_passphrase(struct passwd *pw) void do_change_comment(struct passwd *pw) { - char new_comment[1024], *file, *comment; + char new_comment[1024], *comment; RSA *private_key; char *passphrase; struct stat st; FILE *f; 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. */ - if (stat(file, &st) < 0) + if (stat(identity_file, &st) < 0) { - perror(file); + perror(identity_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(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); } private_key = RSA_new(); /* 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(""); else { @@ -279,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(file, passphrase, private_key, &comment)) + if (!load_private_key(identity_file, passphrase, private_key, &comment)) { memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); @@ -310,10 +310,10 @@ do_change_comment(struct passwd *pw) } /* 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", - file, strerror(errno)); + identity_file, strerror(errno)); memset(passphrase, 0, strlen(passphrase)); xfree(passphrase); RSA_free(private_key); @@ -328,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(file, ".pub"); - f = fopen(file, "w"); + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); 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); } fprintf(f, "%d ", BN_num_bits(public_key->n)); @@ -350,6 +350,14 @@ do_change_comment(struct passwd *pw) 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. */ int @@ -357,7 +365,7 @@ main(int ac, char **av) { char buf[16384], buf2[1024], *passphrase1, *passphrase2; struct passwd *pw; - char *file, *tmpbuf; + char *tmpbuf; int opt; struct stat st; FILE *f; @@ -416,7 +424,8 @@ main(int ac, char **av) break; case 'f': - identity_file = optarg; + strlcpy(identity_file, optarg, sizeof(identity_file)); + have_identity = 1; break; case 'P': @@ -437,20 +446,18 @@ main(int ac, char **av) case '?': default: - 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", av[0]); - exit(1); + usage(); } } if (optind < ac) { printf("Too many arguments.\n"); - exit(1); + usage(); } if (change_passphrase && change_comment) { printf("Can only have one of -p and -c.\n"); - exit(1); + usage(); } if (print_fingerprint) @@ -476,14 +483,13 @@ main(int ac, char **av) public_key = RSA_new(); rsa_generate_key(private_key, public_key, bits); - ask_file_again: - - file = get_filename(pw, "Enter file in which to save the key"); + if (!have_identity) + ask_filename(pw, "Enter file in which to save the key"); /* If the file aready exists, ask the user to confirm. */ - if (stat(file, &st) >= 0) + if (stat(identity_file, &st) >= 0) { - printf("%s already exists.\n", file); + printf("%s already exists.\n", identity_file); printf("Overwrite (y/n)? "); fflush(stdout); if (fgets(buf2, sizeof(buf2), stdin) == NULL) @@ -536,14 +542,13 @@ main(int ac, char **av) } /* 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, buf2)) { printf("Saving the key failed: %s: %s.\n", - file, strerror(errno)); + identity_file, strerror(errno)); memset(passphrase1, 0, strlen(passphrase1)); xfree(passphrase1); - xfree(file); - goto ask_file_again; + exit(1); } /* Clear the passphrase. */ memset(passphrase1, 0, strlen(passphrase1)); @@ -554,7 +559,7 @@ main(int ac, char **av) arc4random_stir(); 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) { @@ -570,12 +575,11 @@ main(int ac, char **av) /* Save the public key in text format in a file with the same name but .pub appended. */ - file = xrealloc(file, strlen(file) + 5); - strcat(file, ".pub"); - f = fopen(file, "w"); + strlcat(identity_file, ".pub", sizeof(identity_file)); + f = fopen(identity_file, "w"); 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); } fprintf(f, "%d ", BN_num_bits(public_key->n)); @@ -588,7 +592,7 @@ main(int ac, char **av) fclose(f); 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); exit(0); } diff --git a/sshd.c b/sshd.c index ad51dacd4..5d8fa6dbe 100644 --- a/sshd.c +++ b/sshd.c @@ -18,7 +18,7 @@ agent connections. */ #include "includes.h" -RCSID("$Id: sshd.c,v 1.26 1999/11/21 02:23:53 damien Exp $"); +RCSID("$Id: sshd.c,v 1.27 1999/11/21 07:31:57 damien Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -316,7 +316,10 @@ void main_sigchld_handler(int sig) { int save_errno = errno; int status; - wait(&status); + + while (waitpid(-1, &status, WNOHANG) > 0) + ; + signal(SIGCHLD, main_sigchld_handler); errno = save_errno; }