]> andersk Git - openssh.git/blobdiff - ssh-keygen.c
- stevesk@cvs.openbsd.org 2006/07/17 01:31:10
[openssh.git] / ssh-keygen.c
index 89686f5acd60229b636e67a5b685dc75726faedd..56ad725d8607d1c032fe618dec2038f9bf782b4c 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh-keygen.c,v 1.149 2006/07/17 01:31:10 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.130 2005/10/07 11:13:57 markus Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 
+#include <errno.h>
+#include <fcntl.h>
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <pwd.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
 #include "key.h"
 #include "rsa.h"
@@ -29,11 +44,11 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.130 2005/10/07 11:13:57 markus Exp $");
 #include "misc.h"
 #include "match.h"
 #include "hostfile.h"
+#include "dns.h"
 
 #ifdef SMARTCARD
 #include "scard.h"
 #endif
-#include "dns.h"
 
 /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
 #define DEFAULT_BITS           2048
@@ -103,7 +118,7 @@ ask_filename(struct passwd *pw, const char *prompt)
 
        if (key_type_name == NULL)
                name = _PATH_SSH_CLIENT_ID_RSA;
-       else
+       else {
                switch (key_type_from_name(key_type_name)) {
                case KEY_RSA1:
                        name = _PATH_SSH_CLIENT_IDENTITY;
@@ -119,7 +134,7 @@ ask_filename(struct passwd *pw, const char *prompt)
                        exit(1);
                        break;
                }
-
+       }
        snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
        fprintf(stderr, "%s (%s): ", prompt, identity_file);
        if (fgets(buf, sizeof(buf), stdin) == NULL)
@@ -302,13 +317,44 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
        return key;
 }
 
+static int
+get_line(FILE *fp, char *line, size_t len)
+{
+       int c;
+       size_t pos = 0;
+
+       line[0] = '\0';
+       while ((c = fgetc(fp)) != EOF) {
+               if (pos >= len - 1) {
+                       fprintf(stderr, "input line too long.\n");
+                       exit(1);
+               }
+               switch (c) {
+               case '\r':
+                       c = fgetc(fp);
+                       if (c != EOF && c != '\n' && ungetc(c, fp) == EOF) {
+                               fprintf(stderr, "unget: %s\n", strerror(errno));
+                               exit(1);
+                       }
+                       return pos;
+               case '\n':
+                       return pos;
+               }
+               line[pos++] = c;
+               line[pos] = '\0';
+       }
+       if (c == EOF)
+               return -1;
+       return pos;
+}
+
 static void
 do_convert_from_ssh2(struct passwd *pw)
 {
        Key *k;
        int blen;
        u_int len;
-       char line[1024], *p;
+       char line[1024];
        u_char blob[8096];
        char encoded[8096];
        struct stat st;
@@ -327,12 +373,8 @@ do_convert_from_ssh2(struct passwd *pw)
                exit(1);
        }
        encoded[0] = '\0';
-       while (fgets(line, sizeof(line), fp)) {
-               if (!(p = strchr(line, '\n'))) {
-                       fprintf(stderr, "input line too long.\n");
-                       exit(1);
-               }
-               if (p > line && p[-1] == '\\')
+       while ((blen = get_line(fp, line, sizeof(line))) != -1) {
+               if (line[blen - 1] == '\\')
                        escaped++;
                if (strncmp(line, "----", 4) == 0 ||
                    strstr(line, ": ") != NULL) {
@@ -349,7 +391,6 @@ do_convert_from_ssh2(struct passwd *pw)
                        /* fprintf(stderr, "escaped: %s", line); */
                        continue;
                }
-               *p = '\0';
                strlcat(encoded, line, sizeof(encoded));
        }
        len = strlen(encoded);
@@ -485,8 +526,10 @@ do_fingerprint(struct passwd *pw)
                xfree(fp);
                exit(0);
        }
-       if (comment)
+       if (comment) {
                xfree(comment);
+               comment = NULL;
+       }
 
        f = fopen(identity_file, "r");
        if (f != NULL) {
@@ -832,30 +875,32 @@ do_change_passphrase(struct passwd *pw)
 /*
  * Print the SSHFP RR.
  */
-static void
-do_print_resource_record(struct passwd *pw, char *hname)
+static int
+do_print_resource_record(struct passwd *pw, char *fname, char *hname)
 {
        Key *public;
        char *comment = NULL;
        struct stat st;
 
-       if (!have_identity)
+       if (fname == NULL)
                ask_filename(pw, "Enter file in which the key is");
-       if (stat(identity_file, &st) < 0) {
-               perror(identity_file);
+       if (stat(fname, &st) < 0) {
+               if (errno == ENOENT)
+                       return 0;
+               perror(fname);
                exit(1);
        }
-       public = key_load_public(identity_file, &comment);
+       public = key_load_public(fname, &comment);
        if (public != NULL) {
                export_dns_rr(hname, public, stdout, print_generic);
                key_free(public);
                xfree(comment);
-               exit(0);
+               return 1;
        }
        if (comment)
                xfree(comment);
 
-       printf("failed to read v2 public key from %s.\n", identity_file);
+       printf("failed to read v2 public key from %s.\n", fname);
        exit(1);
 }
 
@@ -1046,7 +1091,7 @@ main(int ac, char **av)
            "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) {
                switch (opt) {
                case 'b':
-                       bits = strtonum(optarg, 512, 32768, &errstr);
+                       bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
                        if (errstr)
                                fatal("Bits has bad value %s (%s)",
                                        optarg, errstr);
@@ -1116,6 +1161,7 @@ main(int ac, char **av)
                        break;
                case 'D':
                        download = 1;
+                       /*FALLTHROUGH*/
                case 'U':
                        reader_id = optarg;
                        break;
@@ -1132,19 +1178,20 @@ main(int ac, char **av)
                        rr_hostname = optarg;
                        break;
                case 'W':
-                       generator_wanted = strtonum(optarg, 1, UINT_MAX, &errstr);
+                       generator_wanted = (u_int32_t)strtonum(optarg, 1,
+                           UINT_MAX, &errstr);
                        if (errstr)
                                fatal("Desired generator has bad value: %s (%s)",
                                        optarg, errstr);
                        break;
                case 'a':
-                       trials = strtonum(optarg, 1, UINT_MAX, &errstr);
+                       trials = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
                        if (errstr)
                                fatal("Invalid number of trials: %s (%s)",
                                        optarg, errstr);
                        break;
                case 'M':
-                       memory = strtonum(optarg, 1, UINT_MAX, &errstr);
+                       memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr);
                        if (errstr) {
                                fatal("Memory limit is %s: %s", errstr, optarg);
                        }
@@ -1198,7 +1245,27 @@ main(int ac, char **av)
        if (print_public)
                do_print_public(pw);
        if (rr_hostname != NULL) {
-               do_print_resource_record(pw, rr_hostname);
+               unsigned int n = 0;
+
+               if (have_identity) {
+                       n = do_print_resource_record(pw,
+                           identity_file, rr_hostname);
+                       if (n == 0) {
+                               perror(identity_file);
+                               exit(1);
+                       }
+                       exit(0);
+               } else {
+
+                       n += do_print_resource_record(pw,
+                           _PATH_HOST_RSA_KEY_FILE, rr_hostname);
+                       n += do_print_resource_record(pw,
+                           _PATH_HOST_DSA_KEY_FILE, rr_hostname);
+
+                       if (n == 0)
+                               fatal("no keys found.");
+                       exit(0);
+               }
        }
        if (reader_id != NULL) {
 #ifdef SMARTCARD
@@ -1222,7 +1289,7 @@ main(int ac, char **av)
                if (bits == 0)
                        bits = DEFAULT_BITS;
                if (gen_candidates(out, memory, bits, start) != 0)
-                       fatal("modulus candidate generation failed\n");
+                       fatal("modulus candidate generation failed");
 
                return (0);
        }
@@ -1245,25 +1312,26 @@ main(int ac, char **av)
                            out_file, strerror(errno));
                }
                if (prime_test(in, out, trials, generator_wanted) != 0)
-                       fatal("modulus screening failed\n");
+                       fatal("modulus screening failed");
                return (0);
        }
 
        arc4random_stir();
 
-       if (key_type_name == NULL) {
-               printf("You must specify a key type (-t).\n");
-               usage();
-       }
+       if (key_type_name == NULL)
+               key_type_name = "rsa";
+
        type = key_type_from_name(key_type_name);
        if (type == KEY_UNSPEC) {
                fprintf(stderr, "unknown key type %s\n", key_type_name);
                exit(1);
        }
-       if (!quiet)
-               printf("Generating public/private %s key pair.\n", key_type_name);
        if (bits == 0)
                bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
+       if (type == KEY_DSA && bits != 1024)
+               fatal("DSA keys must be 1024 bits");
+       if (!quiet)
+               printf("Generating public/private %s key pair.\n", key_type_name);
        private = key_generate(type, bits);
        if (private == NULL) {
                fprintf(stderr, "key_generate failed");
@@ -1274,7 +1342,7 @@ main(int ac, char **av)
        if (!have_identity)
                ask_filename(pw, "Enter file in which to save the key");
 
-       /* Create ~/.ssh directory if it doesn\'t already exist. */
+       /* Create ~/.ssh directory if it doesn't already exist. */
        snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, _PATH_SSH_USER_DIR);
        if (strstr(identity_file, dotsshdir) != NULL &&
            stat(dotsshdir, &st) < 0) {
This page took 0.222281 seconds and 4 git commands to generate.