--- /dev/null
+typedef unsigned int __u_int;
+typedef unsigned long int __u_long;
+__extension__ typedef unsigned int __uid_t;
+__extension__ typedef long int __time_t;
+__extension__ typedef int __ssize_t;
+typedef __u_int u_int;
+typedef __u_long u_long;
+typedef __ssize_t ssize_t;
+typedef __time_t time_t;
+typedef unsigned int size_t;
+typedef unsigned int u_int32_t __attribute__ ((__mode__(__SI__)));
+typedef unsigned int u_int64_t __attribute__ ((__mode__(__DI__)));
+struct stat {
+};
+extern int *__errno_location(void) __attribute__ ((__nothrow__, __leaf__))
+ __attribute__ ((__const__));
+struct passwd {
+ char *pw_name;
+ __uid_t pw_uid;
+ char *pw_dir;
+};
+typedef struct _IO_FILE FILE;
+extern struct _IO_FILE *stdin;
+extern struct _IO_FILE *stdout;
+extern struct _IO_FILE *stderr;
+typedef struct {
+} Buffer;
+typedef struct bignum_st BIGNUM;
+extern ssize_t write(int __fd, const void *__buf, size_t __n)
+ __attribute__ ((__warn_unused_result__));
+typedef struct Key Key;
+enum types {
+ KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, KEY_ED25519, KEY_RSA_CERT,
+ KEY_DSA_CERT, KEY_ECDSA_CERT, KEY_ED25519_CERT, KEY_RSA_CERT_V00,
+ KEY_DSA_CERT_V00, KEY_UNSPEC
+};
+enum fp_type {
+ SSH_FP_SHA1, SSH_FP_MD5, SSH_FP_SHA256
+};
+enum fp_rep {
+ SSH_FP_HEX, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART
+};
+struct KeyCert {
+ u_int64_t serial;
+ char *key_id;
+ u_int nprincipals;
+ char **principals;
+ u_int64_t valid_after, valid_before;
+ Buffer critical;
+ Buffer extensions;
+ Key *signature_key;
+};
+struct Key {
+ int type;
+ struct KeyCert *cert;
+};
+typedef enum {
+ SYSLOG_FACILITY_DAEMON, SYSLOG_FACILITY_USER, SYSLOG_FACILITY_AUTH,
+ SYSLOG_FACILITY_LOCAL0, SYSLOG_FACILITY_LOCAL1,
+ SYSLOG_FACILITY_LOCAL2, SYSLOG_FACILITY_LOCAL3,
+ SYSLOG_FACILITY_LOCAL4, SYSLOG_FACILITY_LOCAL5,
+ SYSLOG_FACILITY_LOCAL6, SYSLOG_FACILITY_LOCAL7,
+ SYSLOG_FACILITY_NOT_SET = -1
+} SyslogFacility;
+typedef enum {
+ SYSLOG_LEVEL_QUIET, SYSLOG_LEVEL_FATAL, SYSLOG_LEVEL_ERROR,
+ SYSLOG_LEVEL_INFO, SYSLOG_LEVEL_VERBOSE, SYSLOG_LEVEL_DEBUG1,
+ SYSLOG_LEVEL_DEBUG2, SYSLOG_LEVEL_DEBUG3, SYSLOG_LEVEL_NOT_SET = -1
+} LogLevel;
+u_int32_t bits = 0;
+int change_passphrase = 0;
+int change_comment = 0;
+int quiet = 0;
+int log_level = SYSLOG_LEVEL_INFO;
+int hash_hosts = 0;
+int find_host = 0;
+int delete_host = 0;
+int show_cert = 0;
+int print_fingerprint = 0;
+int print_bubblebabble = 0;
+char identity_file[1024];
+int have_identity = 0;
+char *identity_passphrase = ((void *)0);
+char *identity_new_passphrase = ((void *)0);
+char *identity_comment = ((void *)0);
+char *ca_key_path = ((void *)0);
+unsigned long long cert_serial = 0;
+u_int cert_key_type = 1;
+char *cert_key_id = ((void *)0);
+char *cert_principals = ((void *)0);
+u_int32_t certflags_flags = ((1) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4));
+int convert_to = 0;
+int convert_from = 0;
+enum {
+ FMT_RFC4716, FMT_PKCS8, FMT_PEM
+} convert_format = FMT_RFC4716;
+int print_public = 0;
+int print_generic = 0;
+char *key_type_name = ((void *)0);
+char *pkcs11provider = ((void *)0);
+int use_new_format = 0;
+char *new_format_cipher = ((void *)0);
+int rounds = 0;
+extern char *__progname;
+char hostname[64];
+static void do_download(struct passwd *pw)
+{
+ Key **keys = ((void *)0);
+ int i, nkeys;
+ enum fp_rep rep;
+ enum fp_type fptype;
+ char *fp, *ra;
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
+ rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
+ pkcs11_init(0);
+ nkeys = pkcs11_add_provider(pkcs11provider, ((void *)0), &keys);
+ if (nkeys <= 0)
+ fatal("cannot read public key from pkcs11");
+ for (i = 0; i < nkeys; i++) {
+ if (print_fingerprint) {
+ fp = key_fingerprint(keys[i], fptype, rep);
+ ra = key_fingerprint(keys[i], SSH_FP_MD5,
+ SSH_FP_RANDOMART);
+ printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), fp,
+ key_type(keys[i]));
+ if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ printf("%s\n", ra);
+ free(ra);
+ free(fp);
+ key_write(keys[i], stdout);
+ fprintf(stdout, "\n");
+ }
+ key_free(keys[i]);
+ }
+ free(keys);
+ exit(0);
+}
+
+static void do_fingerprint(struct passwd *pw)
+{
+ FILE *f;
+ Key *public;
+ char *comment = ((void *)0), *cp, *ep, line[16 * 1024], *fp, *ra;
+ int i, skip = 0, num = 0, invalid = 1;
+ enum fp_rep rep;
+ enum fp_type fptype;
+ struct stat st;
+ fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
+ rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0) {
+ perror(identity_file);
+ exit(1);
+ }
+ public = key_load_public(identity_file, &comment);
+ if (public != ((void *)0)) {
+ fp = key_fingerprint(public, fptype, rep);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
+ printf("%u %s %s (%s)\n", key_size(public), fp, comment,
+ key_type(public));
+ if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ printf("%s\n", ra);
+ key_free(public);
+ free(comment);
+ free(ra);
+ free(fp);
+ exit(0);
+ }
+ if (comment) {
+ free(comment);
+ }
+ if ((f = fopen(identity_file, "r")) == ((void *)0))
+ fatal("%s: %s: %s", __progname, identity_file,
+ strerror((*__errno_location())));
+ while (fgets(line, sizeof(line), f)) {
+ if ((cp =
+ (__extension__
+ (__builtin_constant_p('\n') && !__builtin_constant_p(line)
+ && ('\n') == '\0' ? (char *)__rawmemchr(line,
+ '\n') :
+ __builtin_strchr(line, '\n')))) == ((void *)0)) {
+ error("line %d too long: %.40s...", num + 1, line);
+ skip = 1;
+ }
+ num++;
+ if (skip) {
+ continue;
+ }
+ *cp = '\0';
+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ;
+ if (!*cp || *cp == '\n' || *cp == '#')
+ continue;
+ i = strtol(cp, &ep, 10);
+ if (i == 0 || ep == ((void *)0) || (*ep != ' ' && *ep != '\t')) {
+ int quoted = 0;
+ comment = cp;
+ for (;
+ *cp && (quoted || (*cp != ' ' && *cp != '\t'));
+ cp++) {
+ if (*cp == '\\' && cp[1] == '"')
+ cp++;
+ else if (*cp == '"')
+ quoted = !quoted;
+ }
+ if (!*cp)
+ continue;
+ *cp++ = '\0';
+ }
+ ep = cp;
+ public = key_new(KEY_RSA1);
+ if (key_read(public, &cp) != 1) {
+ cp = ep;
+ key_free(public);
+ public = key_new(KEY_UNSPEC);
+ if (key_read(public, &cp) != 1) {
+ key_free(public);
+ }
+ }
+ comment = *cp ? cp : comment;
+ fp = key_fingerprint(public, fptype, rep);
+ ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
+ printf("%u %s %s (%s)\n", key_size(public), fp,
+ comment ? comment : "no comment", key_type(public));
+ if (log_level >= SYSLOG_LEVEL_VERBOSE)
+ printf("%s\n", ra);
+ free(ra);
+ free(fp);
+ key_free(public);
+ invalid = 0;
+ }
+ fclose(f);
+ if (invalid) {
+ printf("%s is not a public key file.\n", identity_file);
+ exit(1);
+ }
+}
+
+static void do_gen_all_hostkeys(struct passwd *pw)
+{
+ struct {
+ char *key_type;
+ char *key_type_display;
+ char *path;
+ } key_types[] = {
+ {
+ "rsa1", "RSA1", "/etc/ssh" "/ssh_host_key"}
+ , {
+ "rsa", "RSA", "/etc/ssh" "/ssh_host_rsa_key"}
+ , {
+ ((void *)0), ((void *)0), ((void *)0)}
+ };
+ int first = 0;
+ struct stat st;
+ Key *private, *public;
+ char comment[1024];
+ int i, type, fd;
+ FILE *f;
+ for (i = 0; key_types[i].key_type; i++) {
+ if (stat(key_types[i].path, &st) == 0)
+ continue;
+ if ((*__errno_location()) != 2) {
+ printf("Could not stat %s: %s", key_types[i].path,
+ strerror((*__errno_location())));
+ }
+ if (first == 0) {
+ first = 1;
+ printf("%s: generating new host keys: ", __progname);
+ }
+ printf("%s ", key_types[i].key_type_display);
+ fflush(stdout);
+ type = key_type_from_name(key_types[i].key_type);
+ strlcpy(identity_file, key_types[i].path,
+ sizeof(identity_file));
+ bits = 0;
+ type_bits_valid(type, &bits);
+ private = key_generate(type, bits);
+ if (private == ((void *)0)) {
+ fprintf(stderr, "key_generate failed\n");
+ }
+ public = key_from_private(private);
+ snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
+ hostname);
+ if (!key_save_private
+ (private, identity_file, "", comment, use_new_format,
+ new_format_cipher, rounds)) {
+ printf("Saving the key failed: %s.\n", identity_file);
+ key_free(private);
+ key_free(public);
+ }
+ key_free(private);
+ strlcat(identity_file, ".pub", sizeof(identity_file));
+ fd = open(identity_file, 01 | 00000400 | 01000, 0644);
+ if (fd == -1) {
+ printf("Could not save your public key in %s\n",
+ identity_file);
+ key_free(public);
+ }
+ f = fdopen(fd, "w");
+ if (f == ((void *)0)) {
+ printf("fdopen %s failed\n", identity_file);
+ key_free(public);
+ }
+ if (!key_write(public, f)) {
+ fprintf(stderr, "write key failed\n");
+ key_free(public);
+ }
+ fprintf(f, " %s\n", comment);
+ fclose(f);
+ key_free(public);
+ }
+ if (first != 0)
+ printf("\n");
+}
+
+static void do_known_hosts(struct passwd *pw, const char *name)
+{
+ FILE *in, *out = stdout;
+ Key *pub;
+ char *cp, *cp2, *kp, *kp2;
+ char line[16 * 1024], tmp[4096], old[4096];
+ int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
+ int ca;
+ int found_key = 0;
+ if (!have_identity) {
+ cp = tilde_expand_filename("~/" ".ssh" "/known_hosts",
+ pw->pw_uid);
+ if (strlcpy(identity_file, cp, sizeof(identity_file)) >=
+ sizeof(identity_file))
+ fatal("Specified known hosts path too long");
+ free(cp);
+ }
+ if ((in = fopen(identity_file, "r")) == ((void *)0))
+ fatal("%s: %s: %s", __progname, identity_file,
+ strerror((*__errno_location())));
+ if (!find_host && (hash_hosts || delete_host)) {
+ if (strlcpy(tmp, identity_file, sizeof(tmp)) >= sizeof(tmp)
+ || strlcat(tmp, ".XXXXXXXXXX", sizeof(tmp)) >= sizeof(tmp)
+ || strlcpy(old, identity_file, sizeof(old)) >= sizeof(old)
+ || strlcat(old, ".old", sizeof(old)) >= sizeof(old))
+ fatal("known_hosts path too long");
+ umask(077);
+ if ((c = mkstemp(tmp)) == -1)
+ fatal("mkstemp: %s", strerror((*__errno_location())));
+ if ((out = fdopen(c, "w")) == ((void *)0)) {
+ c = (*__errno_location());
+ unlink(tmp);
+ fatal("fdopen: %s", strerror(c));
+ }
+ inplace = 1;
+ }
+ while (fgets(line, sizeof(line), in)) {
+ if ((cp =
+ (__extension__
+ (__builtin_constant_p('\n') && !__builtin_constant_p(line)
+ && ('\n') == '\0' ? (char *)__rawmemchr(line,
+ '\n') :
+ __builtin_strchr(line, '\n')))) == ((void *)0)) {
+ error("line %d too long: %.40s...", num + 1, line);
+ skip = 1;
+ invalid = 1;
+ continue;
+ }
+ num++;
+ if (skip) {
+ continue;
+ }
+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ;
+ if (!*cp || *cp == '\n' || *cp == '#') {
+ if (inplace)
+ fprintf(out, "%s\n", cp);
+ }
+ if (strncasecmp
+ (cp, "@cert-authority", sizeof("@cert-authority") - 1) == 0
+ && (cp[sizeof("@cert-authority") - 1] == ' '
+ || cp[sizeof("@cert-authority") - 1] == '\t')) {
+ ca = 1;
+ cp += sizeof("@cert-authority");
+ } else
+ ca = 0;
+ for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) ;
+ if (*kp == '\0' || *(kp + 1) == '\0') {
+ error("line %d missing key: %.40s...", num, line);
+ }
+ *kp++ = '\0';
+ pub = key_new(KEY_RSA1);
+ if (key_read(pub, &kp) != 1) {
+ kp = kp2;
+ key_free(pub);
+ pub = key_new(KEY_UNSPEC);
+ if (key_read(pub, &kp) != 1) {
+ error("line %d invalid key: %.40s...", num,
+ line);
+ key_free(pub);
+ }
+ }
+ if (*cp == '|') {
+ if (find_host || delete_host) {
+ cp2 = host_hash(name, cp, strlen(cp));
+ if (cp2 == ((void *)0)) {
+ error("line %d: invalid hashed "
+ "name: %.64s...", num, line);
+ }
+ c = (__extension__( {
+ size_t __s1_len, __s2_len;
+ (__builtin_constant_p(cp2)
+ && __builtin_constant_p(cp)
+ && (__s1_len =
+ strlen(cp2), __s2_len =
+ strlen(cp),
+ (!((size_t)
+ (const void *)((cp2)
+ + 1) -
+ (size_t) (const void
+ *)(cp2) ==
+ 1) || __s1_len >= 4)
+ &&
+ (!((size_t)
+ (const void *)((cp) +
+ 1) -
+ (size_t) (const void
+ *)(cp) ==
+ 1)
+ || __s2_len >=
+ 4)) ?
+ __builtin_strcmp(cp2,
+ cp)
+ : (__builtin_constant_p(cp2)
+ &&
+ ((size_t) (const void *)
+ ((cp2) + 1) -
+ (size_t) (const void
+ *)(cp2) == 1)
+ && (__s1_len =
+ strlen(cp2),
+ __s1_len <
+ 4)
+ ? (__builtin_constant_p
+ (cp)
+ &&
+ ((size_t)
+ (const void *)((cp) +
+ 1) -
+ (size_t) (const void
+ *)(cp) ==
+ 1) ?
+ __builtin_strcmp(cp2,
+ cp)
+ : (__extension__( {
+ const
+ unsigned
+ char
+ *__s2
+ =
+ (const
+ unsigned
+ char
+ *)
+ (const
+ char
+ *)
+ (cp);
+ register
+ int
+ __result
+ =
+ (((const unsigned char *)(const char *)(cp2))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) {
+ }
+ __result;}
+ ))):
+ (__builtin_constant_p(cp)
+ &&
+ ((size_t) (const void *)
+ ((cp) + 1) -
+ (size_t) (const void
+ *)(cp) == 1)
+ && (__s2_len =
+ strlen(cp),
+ __s2_len <
+ 4)
+ ? (__builtin_constant_p
+ (cp2)
+ &&
+ ((size_t)
+ (const void *)((cp2)
+ +
+ 1) -
+ (size_t) (const void
+ *)(cp2) ==
+ 1) ?
+ __builtin_strcmp(cp2,
+ cp)
+ : (__extension__( {
+ const
+ unsigned
+ char
+ *__s1
+ =
+ (const
+ unsigned
+ char
+ *)
+ (const
+ char
+ *)
+ (cp2);
+ register
+ int
+ __result
+ =
+ __s1
+ [0]
+ -
+ ((const unsigned char *)(const char *)(cp))[0]; __result;}
+ ))):
+ __builtin_strcmp(cp2,
+ cp))));}
+ ) == 0) ;
+ if (find_host && c) {
+ if (!quiet)
+ printf("# Host %s found: "
+ "line %d type %s%s\n",
+ name, num, key_type(pub),
+ ca ? " (CA key)" : "");
+ printhost(out, cp, pub, ca, 0);
+ found_key = 1;
+ }
+ if (delete_host) {
+ if (!c && !ca)
+ printhost(out, cp, pub, ca, 0);
+ else
+ printf("# Host %s found: "
+ "line %d type %s\n",
+ name, num,
+ key_type(pub));
+ }
+ } else if (hash_hosts)
+ printhost(out, cp, pub, ca, 0);
+ if (find_host || delete_host) {
+ c = (match_hostname(name, cp, strlen(cp)) == 1);
+ if (find_host && c) {
+ if (!quiet)
+ printf("# Host %s found: "
+ "line %d type %s%s\n",
+ name, num, key_type(pub),
+ ca ? " (CA key)" : "");
+ printhost(out, name, pub, ca, hash_hosts
+ && !ca);
+ }
+ if (delete_host) {
+ if (!c && !ca)
+ printhost(out, cp, pub, ca, 0);
+ else
+ printf("# Host %s found: "
+ "line %d type %s\n",
+ name, num,
+ key_type(pub));
+ }
+ } else if (hash_hosts) {
+ for (cp2 = __extension__( {
+ char __r0, __r1, __r2;
+ (__builtin_constant_p
+ (",")
+ &&
+ ((size_t)
+ (const void *)((",")
+ + 1) -
+ (size_t) (const void
+ *)(",") ==
+ 1)
+ && (__r0 =
+ ((const char
+ *)(","))[0],
+ ((const char
+ *)(","))[0] !=
+ '\0') ? ((__r1 =
+ ((const
+ char
+ *)
+ (","))
+ [1],
+ ((const
+ char
+ *)
+ (","))
+ [1] ==
+ '\0') ?
+ __strsep_1c
+ (&cp,
+ __r0)
+ : ((__r2
+ =
+ ((const char *)(","))[2], __r2 == '\0') ? __strsep_2c(&cp, __r0, __r1) : (((const char *)(","))[3] == '\0' ? __strsep_3c(&cp, __r0, __r1, __r2) : __strsep_g(&cp, ",")))) : __strsep_g(&cp, ","));}
+ ); cp2 != ((void *)0) && *cp2 != '\0';
+ cp2 = __extension__( {
+ char __r0, __r1, __r2;
+ (__builtin_constant_p
+ (",")
+ &&
+ ((size_t)
+ (const void *)((",")
+ + 1) -
+ (size_t) (const void
+ *)(",") ==
+ 1)
+ && (__r0 =
+ ((const char
+ *)(","))[0],
+ ((const char
+ *)(","))[0] !=
+ '\0') ? ((__r1 =
+ ((const
+ char
+ *)
+ (","))
+ [1],
+ ((const
+ char
+ *)
+ (","))
+ [1] ==
+ '\0') ?
+ __strsep_1c
+ (&cp,
+ __r0)
+ : ((__r2
+ =
+ ((const char *)(","))[2], __r2 == '\0') ? __strsep_2c(&cp, __r0, __r1) : (((const char *)(","))[3] == '\0' ? __strsep_3c(&cp, __r0, __r1, __r2) : __strsep_g(&cp, ",")))) : __strsep_g(&cp, ","));}
+ )) {
+ if (ca) {
+ fprintf(stderr,
+ "Warning: "
+ "ignoring CA key for host: "
+ "%.64s\n", cp2);
+ printhost(out, cp2, pub, ca, 0);
+ } else if (__extension__( {
+ char __r0,
+ __r1, __r2;
+ (__builtin_constant_p
+ ("*?!")
+ &&
+ ((size_t)
+ (const void
+ *)(("*?!") +
+ 1) -
+ (size_t)
+ (const void
+ *)("*?!") ==
+ 1)
+ ? ((__builtin_constant_p(cp2) && ((size_t) (const void *)((cp2) + 1) - (size_t) (const void *)(cp2) == 1)) ? __builtin_strcspn(cp2, "*?!") : ((__r0 = ((const char *)("*?!"))[0], __r0 == '\0') ? strlen(cp2) : ((__r1 = ((const char *)("*?!"))[1], __r1 == '\0') ? __strcspn_c1(cp2, __r0) : ((__r2 = ((const char *)("*?!"))[2], __r2 == '\0') ? __strcspn_c2(cp2, __r0, __r1) : (((const char *)("*?!"))[3] == '\0' ? __strcspn_c3(cp2, __r0, __r1, __r2) : __builtin_strcspn(cp2, "*?!")))))) : __builtin_strcspn(cp2, "*?!"));}
+ ) != strlen(cp2)) {
+ fprintf(stderr,
+ "Warning: "
+ "ignoring host name with "
+ "metacharacters: %.64s\n",
+ cp2);
+ printhost(out, cp2, pub, ca, 0);
+ } else
+ printhost(out, cp2, pub, ca, 1);
+ }
+ has_unhashed = 1;
+ }
+ }
+ key_free(pub);
+ }
+ fclose(in);
+ if (invalid) {
+ fprintf(stderr, "%s is not a valid known_hosts file.\n",
+ identity_file);
+ if (inplace) {
+ fprintf(stderr,
+ "Not replacing existing known_hosts "
+ "file because of errors\n");
+ fclose(out);
+ unlink(tmp);
+ }
+ exit(1);
+ }
+ if (inplace) {
+ fclose(out);
+ if (unlink(old) == -1 && (*__errno_location()) != 2)
+ fatal("unlink %.100s: %s", old,
+ strerror((*__errno_location())));
+ if (link(identity_file, old) == -1)
+ fatal("link %.100s to %.100s: %s", identity_file, old,
+ strerror((*__errno_location())));
+ if (rename(tmp, identity_file) == -1) {
+ error("rename\"%s\" to \"%s\": %s", tmp, identity_file,
+ strerror((*__errno_location())));
+ unlink(tmp);
+ unlink(old);
+ exit(1);
+ }
+ fprintf(stderr, "%s updated.\n", identity_file);
+ fprintf(stderr, "Original contents retained as %s\n", old);
+ if (has_unhashed) {
+ fprintf(stderr,
+ "WARNING: %s contains unhashed " "entries\n",
+ old);
+ fprintf(stderr,
+ "Delete this file to ensure privacy "
+ "of hostnames\n");
+ }
+ }
+ exit(find_host && !found_key);
+}
+
+static void do_change_passphrase(struct passwd *pw)
+{
+ char *comment;
+ char *old_passphrase, *passphrase1, *passphrase2;
+ struct stat st;
+ Key *private;
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0) {
+ perror(identity_file);
+ exit(1);
+ }
+ private = key_load_private(identity_file, "", &comment);
+ if (private == ((void *)0)) {
+ if (identity_passphrase)
+ old_passphrase = xstrdup(identity_passphrase);
+ else
+ old_passphrase =
+ read_passphrase("Enter old passphrase: ", 0x0002);
+ private =
+ key_load_private(identity_file, old_passphrase, &comment);
+ explicit_bzero(old_passphrase, strlen(old_passphrase));
+ free(old_passphrase);
+ if (private == ((void *)0)) {
+ printf("Bad passphrase.\n");
+ exit(1);
+ }
+ }
+ printf("Key has comment '%s'\n", comment);
+ if (identity_new_passphrase) {
+ passphrase1 = xstrdup(identity_new_passphrase);
+ } else {
+ passphrase1 =
+ read_passphrase("Enter new passphrase (empty for no "
+ "passphrase): ", 0x0002);
+ passphrase2 =
+ read_passphrase("Enter same passphrase again: ", 0x0002);
+ if (__extension__( {
+ size_t __s1_len, __s2_len;
+ (__builtin_constant_p(passphrase1)
+ && __builtin_constant_p(passphrase2)
+ && (__s1_len =
+ strlen(passphrase1), __s2_len =
+ strlen(passphrase2),
+ (!((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void *)(passphrase1)
+ == 1) || __s1_len >= 4)
+ &&
+ (!((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void *)(passphrase2)
+ == 1)
+ || __s2_len >=
+ 4)) ? __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__builtin_constant_p(passphrase1)
+ &&
+ ((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void *)(passphrase1) ==
+ 1)
+ && (__s1_len =
+ strlen(passphrase1),
+ __s1_len <
+ 4)
+ ? (__builtin_constant_p(passphrase2)
+ &&
+ ((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void *)(passphrase2)
+ == 1) ? __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__extension__( {
+ const unsigned char
+ *__s2 =
+ (const unsigned char
+ *)(const char
+ *)(passphrase2);
+ register int __result
+ =
+ (((const unsigned char
+ *)(const char
+ *)(passphrase1))
+ [0] - __s2[0]);
+ __result;}
+ ))): (__builtin_constant_p(passphrase2)
+ &&
+ ((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void
+ *)(passphrase2) == 1)
+ && (__s2_len =
+ strlen(passphrase2),
+ __s2_len <
+ 4)
+ ? (__builtin_constant_p
+ (passphrase1)
+ &&
+ ((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void
+ *)(passphrase1) ==
+ 1) ?
+ __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__extension__( {
+ const unsigned
+ char *__s1 =
+ (const unsigned
+ char *)(const
+ char
+ *)
+ (passphrase1);
+ register int
+ __result =
+ __s1[0] -
+ ((const
+ unsigned char
+ *)(const char
+ *)
+ (passphrase2))
+ [0];
+ if (__s2_len >
+ 0
+ && __result
+ == 0) {
+ }
+ __result;}
+ ))): __builtin_strcmp(passphrase1,
+ passphrase2))));}
+ ) != 0) {
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ explicit_bzero(passphrase2, strlen(passphrase2));
+ free(passphrase1);
+ free(passphrase2);
+ printf("Pass phrases do not match. Try again.\n");
+ exit(1);
+ }
+ explicit_bzero(passphrase2, strlen(passphrase2));
+ free(passphrase2);
+ }
+ if (!key_save_private
+ (private, identity_file, passphrase1, comment, use_new_format,
+ new_format_cipher, rounds)) {
+ printf("Saving the key failed: %s.\n", identity_file);
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ free(passphrase1);
+ key_free(private);
+ free(comment);
+ exit(1);
+ }
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ free(passphrase1);
+ key_free(private);
+ free(comment);
+ printf("Your identification has been saved with the new passphrase.\n");
+ exit(0);
+}
+
+static void do_change_comment(struct passwd *pw)
+{
+ char new_comment[1024], *comment, *passphrase;
+ Key *private;
+ Key *public;
+ struct stat st;
+ FILE *f;
+ int fd;
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0) {
+ perror(identity_file);
+ exit(1);
+ }
+ private = key_load_private(identity_file, "", &comment);
+ if (private == ((void *)0)) {
+ if (identity_passphrase)
+ passphrase = xstrdup(identity_passphrase);
+ else if (identity_new_passphrase)
+ passphrase = xstrdup(identity_new_passphrase);
+ else
+ passphrase =
+ read_passphrase("Enter passphrase: ", 0x0002);
+ private = key_load_private(identity_file, passphrase, &comment);
+ if (private == ((void *)0)) {
+ explicit_bzero(passphrase, strlen(passphrase));
+ free(passphrase);
+ printf("Bad passphrase.\n");
+ exit(1);
+ }
+ passphrase = xstrdup("");
+ }
+ if (private->type != KEY_RSA1) {
+ fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
+ key_free(private);
+ exit(1);
+ }
+ printf("Key now has comment '%s'\n", comment);
+ if (identity_comment) {
+ strlcpy(new_comment, identity_comment, sizeof(new_comment));
+ printf("Enter new comment: ");
+ fflush(stdout);
+ if (!fgets(new_comment, sizeof(new_comment), stdin)) {
+ explicit_bzero(passphrase, strlen(passphrase));
+ key_free(private);
+ exit(1);
+ }
+ new_comment[__extension__( {
+ char __r0, __r1, __r2;
+ (__builtin_constant_p("\n")
+ &&
+ ((size_t) (const void *)(("\n") + 1)
+ - (size_t) (const void *)("\n") ==
+ 1)
+ ? ((__builtin_constant_p(new_comment)
+ &&
+ ((size_t) (const void *)
+ ((new_comment) + 1) -
+ (size_t) (const void
+ *)(new_comment) ==
+ 1)) ?
+ __builtin_strcspn(new_comment,
+ "\n") : ((__r0 =
+ ((const char *)("\n"))[0], __r0 == '\0') ? strlen(new_comment) : ((__r1 = ((const char *)("\n"))[1], __r1 == '\0') ? __strcspn_c1(new_comment, __r0) : ((__r2 = ((const char *)("\n"))[2], __r2 == '\0') ? __strcspn_c2(new_comment, __r0, __r1) : (((const char *)("\n"))[3] == '\0' ? __strcspn_c3(new_comment, __r0, __r1, __r2) : __builtin_strcspn(new_comment, "\n")))))) : __builtin_strcspn(new_comment, "\n"));}
+ )] = '\0';
+ }
+ if (!key_save_private
+ (private, identity_file, passphrase, new_comment, use_new_format,
+ new_format_cipher, rounds)) {
+ printf("Saving the key failed: %s.\n", identity_file);
+ explicit_bzero(passphrase, strlen(passphrase));
+ free(passphrase);
+ key_free(private);
+ free(comment);
+ exit(1);
+ }
+ explicit_bzero(passphrase, strlen(passphrase));
+ free(passphrase);
+ public = key_from_private(private);
+ key_free(private);
+ strlcat(identity_file, ".pub", sizeof(identity_file));
+ fd = open(identity_file, 01 | 00000400 | 01000, 0644);
+ if (fd == -1) {
+ printf("Could not save your public key in %s\n", identity_file);
+ exit(1);
+ }
+ f = fdopen(fd, "w");
+ if (f == ((void *)0)) {
+ printf("fdopen %s failed\n", identity_file);
+ exit(1);
+ }
+ if (!key_write(public, f))
+ fprintf(stderr, "write key failed\n");
+ key_free(public);
+ fprintf(f, " %s\n", new_comment);
+ fclose(f);
+ free(comment);
+ printf("The comment in your key file has been changed.\n");
+ exit(0);
+}
+
+static const char *fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
+{
+ char from[32], to[32];
+ static char ret[64];
+ time_t tt;
+ struct tm *tm;
+ *from = *to = '\0';
+ if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
+ return "forever";
+ if (valid_from != 0) {
+ tt = valid_from > 2147483647 ? 2147483647 : valid_from;
+ tm = localtime(&tt);
+ strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
+ }
+ if (valid_to != 0xffffffffffffffffULL) {
+ tt = valid_to > 2147483647 ? 2147483647 : valid_to;
+ tm = localtime(&tt);
+ strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
+ }
+ if (valid_from == 0) {
+ snprintf(ret, sizeof(ret), "before %s", to);
+ }
+ if (valid_to == 0xffffffffffffffffULL) {
+ snprintf(ret, sizeof(ret), "after %s", from);
+ }
+ snprintf(ret, sizeof(ret), "from %s to %s", from, to);
+}
+
+static void do_show_cert(struct passwd *pw)
+{
+ Key *key;
+ struct stat st;
+ char *key_fp, *ca_fp;
+ u_int i, v00;
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0)
+ fatal("%s: %s: %s", __progname, identity_file,
+ strerror((*__errno_location())));
+ if ((key = key_load_public(identity_file, ((void *)0))) == ((void *)0))
+ fatal("%s is not a public key", identity_file);
+ if (!key_is_cert(key))
+ fatal("%s is not a certificate", identity_file);
+ v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00;
+ key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+ ca_fp =
+ key_fingerprint(key->cert->signature_key, SSH_FP_MD5, SSH_FP_HEX);
+ printf("%s:\n", identity_file);
+ printf(" Type: %s %s certificate\n", key_ssh_name(key),
+ key_cert_type(key));
+ printf(" Public key: %s %s\n", key_type(key), key_fp);
+ printf(" Signing CA: %s %s\n",
+ key_type(key->cert->signature_key), ca_fp);
+ printf(" Key ID: \"%s\"\n", key->cert->key_id);
+ if (!v00) {
+ printf(" Serial: %llu\n",
+ (unsigned long long)key->cert->serial);
+ }
+ printf(" Valid: %s\n",
+ fmt_validity(key->cert->valid_after, key->cert->valid_before));
+ printf(" Principals: ");
+ if (key->cert->nprincipals == 0)
+ printf("(none)\n");
+ else {
+ for (i = 0; i < key->cert->nprincipals; i++)
+ printf("\n %s",
+ key->cert->principals[i]);
+ printf("\n");
+ }
+ printf(" Critical Options: ");
+ if (buffer_len(&key->cert->critical) == 0)
+ printf("(none)\n");
+ else {
+ printf("\n");
+ show_options(&key->cert->critical, v00, 1);
+ }
+ if (!v00) {
+ printf(" Extensions: ");
+ if (buffer_len(&key->cert->extensions) == 0)
+ printf("(none)\n");
+ else {
+ printf("\n");
+ show_options(&key->cert->extensions, v00, 0);
+ }
+ }
+ exit(0);
+}
+
+static void do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
+{
+ struct ssh_krl *krl;
+ struct stat sb;
+ Key *ca = ((void *)0);
+ int fd, i;
+ char *tmp;
+ Buffer kbuf;
+ if (*identity_file == '\0')
+ fatal("KRL generation requires an output file");
+ if (stat(identity_file, &sb) == -1) {
+ if ((*__errno_location()) != 2)
+ fatal("Cannot access KRL \"%s\": %s", identity_file,
+ strerror((*__errno_location())));
+ if (updating)
+ fatal("KRL \"%s\" does not exist", identity_file);
+ }
+ if (ca_key_path != ((void *)0)) {
+ tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
+ if ((ca = key_load_public(tmp, ((void *)0))) == ((void *)0))
+ fatal("Cannot load CA public key %s", tmp);
+ free(tmp);
+ }
+ if (updating)
+ load_krl(identity_file, &krl);
+ else if ((krl = ssh_krl_init()) == ((void *)0))
+ fatal("couldn't create KRL");
+ if (cert_serial != 0)
+ ssh_krl_set_version(krl, cert_serial);
+ if (identity_comment != ((void *)0))
+ ssh_krl_set_comment(krl, identity_comment);
+ for (i = 0; i < argc; i++)
+ update_krl_from_file(pw, argv[i], ca, krl);
+ buffer_init(&kbuf);
+ if (ssh_krl_to_blob(krl, &kbuf, ((void *)0), 0) != 0)
+ fatal("Couldn't generate KRL");
+ if ((fd = open(identity_file, 01 | 00000400 | 01000, 0644)) == -1)
+ fatal("open %s: %s", identity_file,
+ strerror((*__errno_location())));
+ if (atomicio
+ ((ssize_t(*)(int, void *, size_t))write, fd, buffer_ptr(&kbuf),
+ buffer_len(&kbuf)) != buffer_len(&kbuf))
+ fatal("write %s: %s", identity_file,
+ strerror((*__errno_location())));
+ close(fd);
+ buffer_free(&kbuf);
+ ssh_krl_free(krl);
+ if (ca != ((void *)0))
+ key_free(ca);
+}
+
+static void usage(void)
+{
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ char dotsshdir[4096], comment[1024], *passphrase1, *passphrase2;
+ char *checkpoint = ((void *)0);
+ char out_file[4096], *ep, *rr_hostname = ((void *)0);
+ Key *private, *public;
+ struct passwd *pw;
+ struct stat st;
+ int opt, type, fd;
+ u_int32_t memory = 0, generator_wanted = 0;
+ int do_gen_candidates = 0, do_screen_candidates = 0;
+ int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
+ unsigned long start_lineno = 0, lines_to_process = 0;
+ BIGNUM *start = ((void *)0);
+ FILE *f;
+ const char *errstr;
+ extern char *BSDoptarg;
+ sanitise_stdfd();
+ __progname = ssh_get_progname(argv[0]);
+ ssh_OpenSSL_add_all_algorithms();
+ log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
+ seed_rng();
+ pw = getpwuid(getuid());
+ if (!pw) {
+ printf("No user exists for uid %lu\n", (u_long) getuid());
+ exit(1);
+ }
+ if (gethostname(hostname, sizeof(hostname)) < 0) {
+ perror("gethostname");
+ exit(1);
+ }
+ while ((opt =
+ BSDgetopt(argc, argv,
+ "ABHLQXceghiklopquvxy"
+ "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:"))
+ != -1) {
+ switch (opt) {
+ case 'A':
+ gen_all_hostkeys = 1;
+ case 'b':
+ bits =
+ (u_int32_t) strtonum(BSDoptarg, 256, 32768,
+ &errstr);
+ if (errstr)
+ fatal("Bits has bad value %s (%s)", BSDoptarg,
+ errstr);
+ case 'F':
+ find_host = 1;
+ rr_hostname = BSDoptarg;
+ break;
+ case 'H':
+ hash_hosts = 1;
+ case 'I':
+ cert_key_id = BSDoptarg;
+ case 'J':
+ lines_to_process = strtoul(BSDoptarg, ((void *)0), 10);
+ case 'j':
+ start_lineno = strtoul(BSDoptarg, ((void *)0), 10);
+ case 'R':
+ delete_host = 1;
+ rr_hostname = BSDoptarg;
+ break;
+ case 'L':
+ show_cert = 1;
+ case 'l':
+ print_fingerprint = 1;
+ case 'B':
+ print_bubblebabble = 1;
+ case 'm':
+ if (strcasecmp(BSDoptarg, "RFC4716") == 0
+ || strcasecmp(BSDoptarg, "ssh2") == 0) {
+ convert_format = FMT_RFC4716;
+ }
+ if (strcasecmp(BSDoptarg, "PKCS8") == 0) {
+ convert_format = FMT_PKCS8;
+ }
+ if (strcasecmp(BSDoptarg, "PEM") == 0) {
+ convert_format = FMT_PEM;
+ }
+ fatal("Unsupported conversion format \"%s\"",
+ BSDoptarg);
+ case 'n':
+ cert_principals = BSDoptarg;
+ case 'o':
+ use_new_format = 1;
+ case 'p':
+ change_passphrase = 1;
+ case 'c':
+ change_comment = 1;
+ case 'f':
+ if (strlcpy
+ (identity_file, BSDoptarg,
+ sizeof(identity_file)) >= sizeof(identity_file))
+ fatal("Identity filename too long");
+ have_identity = 1;
+ case 'g':
+ print_generic = 1;
+ case 'P':
+ identity_passphrase = BSDoptarg;
+ case 'N':
+ identity_new_passphrase = BSDoptarg;
+ case 'Q':
+ check_krl = 1;
+ case 'O':
+ add_cert_option(BSDoptarg);
+ case 'Z':
+ new_format_cipher = BSDoptarg;
+ case 'C':
+ identity_comment = BSDoptarg;
+ case 'q':
+ quiet = 1;
+ case 'e':
+ case 'x':
+ convert_to = 1;
+ case 'h':
+ cert_key_type = 2;
+ certflags_flags = 0;
+ case 'k':
+ gen_krl = 1;
+ case 'i':
+ case 'X':
+ convert_from = 1;
+ case 'y':
+ print_public = 1;
+ case 's':
+ ca_key_path = BSDoptarg;
+ case 't':
+ key_type_name = BSDoptarg;
+ case 'D':
+ pkcs11provider = BSDoptarg;
+ case 'u':
+ update_krl = 1;
+ case 'v':
+ if (log_level == SYSLOG_LEVEL_INFO)
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ else {
+ if (log_level >= SYSLOG_LEVEL_DEBUG1
+ && log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
+ }
+ case 'r':
+ rr_hostname = BSDoptarg;
+ case 'W':
+ generator_wanted =
+ (u_int32_t) strtonum(BSDoptarg, 1,
+ (2147483647 * 2U + 1U),
+ &errstr);
+ if (errstr)
+ fatal
+ ("Desired generator has bad value: %s (%s)",
+ BSDoptarg, errstr);
+ case 'a':
+ rounds =
+ (int)strtonum(BSDoptarg, 1, 2147483647, &errstr);
+ if (errstr)
+ fatal("Invalid number: %s (%s)", BSDoptarg,
+ errstr);
+ case 'M':
+ memory =
+ (u_int32_t) strtonum(BSDoptarg, 1,
+ (2147483647 * 2U + 1U),
+ &errstr);
+ if (errstr)
+ fatal("Memory limit is %s: %s", errstr,
+ BSDoptarg);
+ case 'G':
+ do_gen_candidates = 1;
+ if (strlcpy(out_file, BSDoptarg, sizeof(out_file)) >=
+ sizeof(out_file))
+ fatal("Output filename too long");
+ case 'T':
+ do_screen_candidates = 1;
+ if (strlcpy(out_file, BSDoptarg, sizeof(out_file)) >=
+ sizeof(out_file))
+ fatal("Output filename too long");
+ case 'K':
+ if (strlen(BSDoptarg) >= 4096)
+ fatal("Checkpoint filename too long");
+ checkpoint = xstrdup(BSDoptarg);
+ break;
+ case 'S':
+ if (BN_hex2bn(&start, BSDoptarg) == 0)
+ fatal("Invalid start point.");
+ case 'V':
+ parse_cert_times(BSDoptarg);
+ case 'z':
+ (*__errno_location()) = 0;
+ cert_serial = strtoull(BSDoptarg, &ep, 10);
+ if (*BSDoptarg < '0' || *BSDoptarg > '9' || *ep != '\0'
+ || ((*__errno_location()) == 34
+ && cert_serial ==
+ (9223372036854775807LL * 2ULL + 1)))
+ fatal("Invalid serial number \"%s\"",
+ BSDoptarg);
+ case '?':
+ default:
+ usage();
+ }
+ }
+ log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1);
+ if (ca_key_path != ((void *)0)) {
+ if (argc < 1 && !gen_krl) {
+ printf("Too few arguments.\n");
+ usage();
+ }
+ } else if (argc > 0 && !gen_krl && !check_krl) {
+ printf("Too many arguments.\n");
+ }
+ if (change_passphrase && change_comment) {
+ printf("Can only have one of -p and -c.\n");
+ usage();
+ }
+ if (print_fingerprint && (delete_host || hash_hosts)) {
+ printf("Cannot use -l with -H or -R.\n");
+ usage();
+ }
+ if (gen_krl) {
+ do_gen_krl(pw, update_krl, argc, argv);
+ return (0);
+ }
+ if (check_krl) {
+ do_check_krl(pw, argc, argv);
+ }
+ if (ca_key_path != ((void *)0)) {
+ if (cert_key_id == ((void *)0))
+ fatal("Must specify key id (-I) when certifying");
+ do_ca_sign(pw, argc, argv);
+ }
+ if (show_cert)
+ do_show_cert(pw);
+ if (delete_host || hash_hosts || find_host)
+ do_known_hosts(pw, rr_hostname);
+ if (pkcs11provider != ((void *)0))
+ do_download(pw);
+ if (print_fingerprint || print_bubblebabble)
+ do_fingerprint(pw);
+ if (change_passphrase)
+ do_change_passphrase(pw);
+ if (change_comment)
+ do_change_comment(pw);
+ if (convert_to)
+ do_convert_to(pw);
+ if (convert_from)
+ do_convert_from(pw);
+ if (print_public)
+ do_print_public(pw);
+ if (rr_hostname != ((void *)0)) {
+ 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,
+ "/etc/ssh"
+ "/ssh_host_rsa_key",
+ rr_hostname);
+ n += do_print_resource_record(pw,
+ "/etc/ssh"
+ "/ssh_host_dsa_key",
+ rr_hostname);
+ n += do_print_resource_record(pw,
+ "/etc/ssh"
+ "/ssh_host_ecdsa_key",
+ rr_hostname);
+ if (n == 0)
+ fatal("no keys found.");
+ exit(0);
+ }
+ }
+ if (do_gen_candidates) {
+ FILE *out = fopen(out_file, "w");
+ if (out == ((void *)0)) {
+ error("Couldn't open modulus candidate file \"%s\": %s",
+ out_file, strerror((*__errno_location())));
+ }
+ if (bits == 0)
+ bits = 2048;
+ if (gen_candidates(out, memory, bits, start) != 0)
+ fatal("modulus candidate generation failed");
+ }
+ if (do_screen_candidates) {
+ FILE *in;
+ FILE *out = fopen(out_file, "a");
+ if (have_identity && __extension__( {
+ size_t __s1_len, __s2_len;
+ (__builtin_constant_p
+ (identity_file)
+ && __builtin_constant_p("-")
+ && (__s1_len =
+ strlen(identity_file),
+ __s2_len =
+ strlen("-"),
+ (!((size_t)
+ (const void
+ *)((identity_file) +
+ 1) -
+ (size_t) (const void
+ *)
+ (identity_file) == 1)
+ || __s1_len >= 4)
+ &&
+ (!((size_t)
+ (const void *)(("-")
+ + 1) -
+ (size_t) (const void
+ *)("-") ==
+ 1)
+ || __s2_len >=
+ 4)) ?
+ __builtin_strcmp
+ (identity_file,
+ "-")
+ : (__builtin_constant_p
+ (identity_file)
+ &&
+ ((size_t) (const void *)
+ ((identity_file) + 1) -
+ (size_t) (const void
+ *)
+ (identity_file) == 1)
+ && (__s1_len =
+ strlen
+ (identity_file),
+ __s1_len <
+ 4)
+ ? (__builtin_constant_p
+ ("-")
+ &&
+ ((size_t)
+ (const void *)(("-")
+ + 1) -
+ (size_t) (const void
+ *)("-") ==
+ 1) ?
+ __builtin_strcmp
+ (identity_file,
+ "-")
+ : (__extension__( {
+ const
+ unsigned
+ char
+ *__s2
+ =
+ (const
+ unsigned
+ char
+ *)
+ (const
+ char
+ *)
+ ("-");
+ register
+ int
+ __result
+ =
+ (((const unsigned char *)(const char *)(identity_file))[0] - __s2[0]); __result;}
+ ))):
+ (__builtin_constant_p
+ ("-")
+ &&
+ ((size_t) (const void *)
+ (("-") + 1) -
+ (size_t) (const void
+ *)("-") == 1)
+ && (__s2_len =
+ strlen("-"),
+ __s2_len <
+ 4)
+ ? (__builtin_constant_p
+ (identity_file)
+ &&
+ ((size_t)
+ (const void
+ *)((identity_file)
+ + 1) -
+ (size_t) (const void
+ *)
+ (identity_file) ==
+ 1) ?
+ __builtin_strcmp
+ (identity_file,
+ "-")
+ : (__extension__( {
+ const
+ unsigned
+ char
+ *__s1
+ =
+ (const
+ unsigned
+ char
+ *)
+ (const
+ char
+ *)
+ (identity_file);
+ register
+ int
+ __result
+ =
+ __s1
+ [0]
+ -
+ ((const unsigned char *)(const char *)("-"))[0]; if (__s2_len > 0 && __result == 0) {
+ __result
+ =
+ (__s1
+ [1]
+ -
+ ((const unsigned char *)(const char *)("-"))[1]);}
+ __result;}
+ ))):
+ __builtin_strcmp
+ (identity_file,
+ "-"))));}
+ ) != 0) {
+ if ((in = fopen(identity_file, "r")) == ((void *)0)) {
+ fatal("Couldn't open modulus candidate "
+ "file \"%s\": %s", identity_file,
+ strerror((*__errno_location())));
+ }
+ } else
+ in = stdin;
+ if (out == ((void *)0)) {
+ fatal("Couldn't open moduli file \"%s\": %s", out_file,
+ strerror((*__errno_location())));
+ }
+ if (prime_test
+ (in, out, rounds == 0 ? 100 : rounds, generator_wanted,
+ checkpoint, start_lineno, lines_to_process) != 0)
+ fatal("modulus screening failed");
+ }
+ if (gen_all_hostkeys) {
+ do_gen_all_hostkeys(pw);
+ }
+ if (key_type_name == ((void *)0))
+ key_type_name = "rsa";
+ type = key_type_from_name(key_type_name);
+ type_bits_valid(type, &bits);
+ if (!quiet)
+ printf("Generating public/private %s key pair.\n",
+ key_type_name);
+ private = key_generate(type, bits);
+ if (private == ((void *)0)) {
+ fprintf(stderr, "key_generate failed\n");
+ exit(1);
+ }
+ public = key_from_private(private);
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which to save the key");
+ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s", pw->pw_dir, ".ssh");
+ if (strstr(identity_file, dotsshdir) != ((void *)0)) {
+ if (stat(dotsshdir, &st) < 0) {
+ if ((*__errno_location()) != 2) {
+ error("Could not stat %s: %s", dotsshdir,
+ strerror((*__errno_location())));
+ } else if (mkdir(dotsshdir, 0700) < 0) {
+ error("Could not create directory '%s': %s",
+ dotsshdir,
+ strerror((*__errno_location())));
+ } else if (!quiet)
+ printf("Created directory '%s'.\n", dotsshdir);
+ }
+ }
+ if (stat(identity_file, &st) >= 0) {
+ char yesno[3];
+ printf("%s already exists.\n", identity_file);
+ printf("Overwrite (y/n)? ");
+ fflush(stdout);
+ if (fgets(yesno, sizeof(yesno), stdin) == ((void *)0))
+ exit(1);
+ if (yesno[0] != 'y' && yesno[0] != 'Y')
+ exit(1);
+ }
+ if (identity_passphrase)
+ passphrase1 = xstrdup(identity_passphrase);
+ else if (identity_new_passphrase)
+ passphrase1 = xstrdup(identity_new_passphrase);
+ else {
+ passphrase_again:passphrase1 =
+ read_passphrase("Enter passphrase (empty for no "
+ "passphrase): ", 0x0002);
+ passphrase2 =
+ read_passphrase("Enter same passphrase again: ", 0x0002);
+ if (__extension__( {
+ size_t __s1_len, __s2_len;
+ (__builtin_constant_p(passphrase1)
+ && __builtin_constant_p(passphrase2)
+ && (__s1_len =
+ strlen(passphrase1), __s2_len =
+ strlen(passphrase2),
+ (!((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void *)(passphrase1)
+ == 1) || __s1_len >= 4)
+ &&
+ (!((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void *)(passphrase2)
+ == 1)
+ || __s2_len >=
+ 4)) ? __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__builtin_constant_p(passphrase1)
+ &&
+ ((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void *)(passphrase1) ==
+ 1)
+ && (__s1_len =
+ strlen(passphrase1),
+ __s1_len <
+ 4)
+ ? (__builtin_constant_p(passphrase2)
+ &&
+ ((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void *)(passphrase2)
+ == 1) ? __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__extension__( {
+ const unsigned char
+ *__s2 =
+ (const unsigned char
+ *)(const char
+ *)(passphrase2);
+ register int __result
+ =
+ (((const unsigned char
+ *)(const char
+ *)(passphrase1))
+ [0] - __s2[0]);
+ __result;}
+ ))): (__builtin_constant_p(passphrase2)
+ &&
+ ((size_t) (const void *)
+ ((passphrase2) + 1) -
+ (size_t) (const void
+ *)(passphrase2) == 1)
+ && (__s2_len =
+ strlen(passphrase2),
+ __s2_len <
+ 4)
+ ? (__builtin_constant_p
+ (passphrase1)
+ &&
+ ((size_t) (const void *)
+ ((passphrase1) + 1) -
+ (size_t) (const void
+ *)(passphrase1) ==
+ 1) ?
+ __builtin_strcmp(passphrase1,
+ passphrase2)
+ : (__extension__( {
+ const unsigned
+ char *__s1 =
+ (const unsigned
+ char *)(const
+ char
+ *)
+ (passphrase1);
+ register int
+ __result =
+ __s1[0] -
+ ((const
+ unsigned char
+ *)(const char
+ *)
+ (passphrase2))
+ [0]; __result;}
+ ))): __builtin_strcmp(passphrase1,
+ passphrase2))));}
+ ) != 0) {
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ explicit_bzero(passphrase2, strlen(passphrase2));
+ free(passphrase1);
+ free(passphrase2);
+ printf("Passphrases do not match. Try again.\n");
+ }
+ explicit_bzero(passphrase2, strlen(passphrase2));
+ free(passphrase2);
+ }
+ if (identity_comment) {
+ strlcpy(comment, identity_comment, sizeof(comment));
+ snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
+ hostname);
+ }
+ if (!key_save_private
+ (private, identity_file, passphrase1, comment, use_new_format,
+ new_format_cipher, rounds)) {
+ printf("Saving the key failed: %s.\n", identity_file);
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ free(passphrase1);
+ exit(1);
+ }
+ explicit_bzero(passphrase1, strlen(passphrase1));
+ free(passphrase1);
+ if (!quiet)
+ printf("Your identification has been saved in %s.\n",
+ identity_file);
+ strlcat(identity_file, ".pub", sizeof(identity_file));
+ if (!key_write(public, f))
+ fprintf(stderr, "write key failed\n");
+ fprintf(f, " %s\n", comment);
+ fclose(f);
+ if (!quiet) {
+ char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
+ char *ra =
+ key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART);
+ printf("Your public key has been saved in %s.\n",
+ identity_file);
+ printf("The key fingerprint is:\n");
+ printf("%s %s\n", fp, comment);
+ printf("The key's randomart image is:\n");
+ printf("%s\n", ra);
+ free(ra);
+ free(fp);
+ }
+}