summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c97
1 files changed, 66 insertions, 31 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 04a9b939a..f7e284062 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.160 2007/01/21 01:41:54 stevesk Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -21,6 +21,7 @@
21 21
22#include <openssl/evp.h> 22#include <openssl/evp.h>
23#include <openssl/pem.h> 23#include <openssl/pem.h>
24#include "openbsd-compat/openssl-compat.h"
24 25
25#include <errno.h> 26#include <errno.h>
26#include <fcntl.h> 27#include <fcntl.h>
@@ -71,6 +72,8 @@ int change_comment = 0;
71 72
72int quiet = 0; 73int quiet = 0;
73 74
75int log_level = SYSLOG_LEVEL_INFO;
76
74/* Flag indicating that we want to hash a known_hosts file */ 77/* Flag indicating that we want to hash a known_hosts file */
75int hash_hosts = 0; 78int hash_hosts = 0;
76/* Flag indicating that we want lookup a host in known_hosts file */ 79/* Flag indicating that we want lookup a host in known_hosts file */
@@ -141,8 +144,7 @@ ask_filename(struct passwd *pw, const char *prompt)
141 fprintf(stderr, "%s (%s): ", prompt, identity_file); 144 fprintf(stderr, "%s (%s): ", prompt, identity_file);
142 if (fgets(buf, sizeof(buf), stdin) == NULL) 145 if (fgets(buf, sizeof(buf), stdin) == NULL)
143 exit(1); 146 exit(1);
144 if (strchr(buf, '\n')) 147 buf[strcspn(buf, "\n")] = '\0';
145 *strchr(buf, '\n') = 0;
146 if (strcmp(buf, "") != 0) 148 if (strcmp(buf, "") != 0)
147 strlcpy(identity_file, buf, sizeof(identity_file)); 149 strlcpy(identity_file, buf, sizeof(identity_file));
148 have_identity = 1; 150 have_identity = 1;
@@ -504,8 +506,8 @@ do_fingerprint(struct passwd *pw)
504{ 506{
505 FILE *f; 507 FILE *f;
506 Key *public; 508 Key *public;
507 char *comment = NULL, *cp, *ep, line[16*1024], *fp; 509 char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
508 int i, skip = 0, num = 1, invalid = 1; 510 int i, skip = 0, num = 0, invalid = 1;
509 enum fp_rep rep; 511 enum fp_rep rep;
510 enum fp_type fptype; 512 enum fp_type fptype;
511 struct stat st; 513 struct stat st;
@@ -522,9 +524,14 @@ do_fingerprint(struct passwd *pw)
522 public = key_load_public(identity_file, &comment); 524 public = key_load_public(identity_file, &comment);
523 if (public != NULL) { 525 if (public != NULL) {
524 fp = key_fingerprint(public, fptype, rep); 526 fp = key_fingerprint(public, fptype, rep);
525 printf("%u %s %s\n", key_size(public), fp, comment); 527 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
528 printf("%u %s %s (%s)\n", key_size(public), fp, comment,
529 key_type(public));
530 if (log_level >= SYSLOG_LEVEL_VERBOSE)
531 printf("%s\n", ra);
526 key_free(public); 532 key_free(public);
527 xfree(comment); 533 xfree(comment);
534 xfree(ra);
528 xfree(fp); 535 xfree(fp);
529 exit(0); 536 exit(0);
530 } 537 }
@@ -536,9 +543,9 @@ do_fingerprint(struct passwd *pw)
536 f = fopen(identity_file, "r"); 543 f = fopen(identity_file, "r");
537 if (f != NULL) { 544 if (f != NULL) {
538 while (fgets(line, sizeof(line), f)) { 545 while (fgets(line, sizeof(line), f)) {
539 i = strlen(line) - 1; 546 if ((cp = strchr(line, '\n')) == NULL) {
540 if (line[i] != '\n') { 547 error("line %d too long: %.40s...",
541 error("line %d too long: %.40s...", num, line); 548 num + 1, line);
542 skip = 1; 549 skip = 1;
543 continue; 550 continue;
544 } 551 }
@@ -547,7 +554,7 @@ do_fingerprint(struct passwd *pw)
547 skip = 0; 554 skip = 0;
548 continue; 555 continue;
549 } 556 }
550 line[i] = '\0'; 557 *cp = '\0';
551 558
552 /* Skip leading whitespace, empty and comment lines. */ 559 /* Skip leading whitespace, empty and comment lines. */
553 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 560 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -582,8 +589,12 @@ do_fingerprint(struct passwd *pw)
582 } 589 }
583 comment = *cp ? cp : comment; 590 comment = *cp ? cp : comment;
584 fp = key_fingerprint(public, fptype, rep); 591 fp = key_fingerprint(public, fptype, rep);
585 printf("%u %s %s\n", key_size(public), fp, 592 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
586 comment ? comment : "no comment"); 593 printf("%u %s %s (%s)\n", key_size(public), fp,
594 comment ? comment : "no comment", key_type(public));
595 if (log_level >= SYSLOG_LEVEL_VERBOSE)
596 printf("%s\n", ra);
597 xfree(ra);
587 xfree(fp); 598 xfree(fp);
588 key_free(public); 599 key_free(public);
589 invalid = 0; 600 invalid = 0;
@@ -598,14 +609,31 @@ do_fingerprint(struct passwd *pw)
598} 609}
599 610
600static void 611static void
601print_host(FILE *f, char *name, Key *public, int hash) 612print_host(FILE *f, const char *name, Key *public, int hash)
602{ 613{
603 if (hash && (name = host_hash(name, NULL, 0)) == NULL) 614 if (print_fingerprint) {
604 fatal("hash_host failed"); 615 enum fp_rep rep;
605 fprintf(f, "%s ", name); 616 enum fp_type fptype;
606 if (!key_write(public, f)) 617 char *fp, *ra;
607 fatal("key_write failed"); 618
608 fprintf(f, "\n"); 619 fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
620 rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;
621 fp = key_fingerprint(public, fptype, rep);
622 ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
623 printf("%u %s %s (%s)\n", key_size(public), fp, name,
624 key_type(public));
625 if (log_level >= SYSLOG_LEVEL_VERBOSE)
626 printf("%s\n", ra);
627 xfree(ra);
628 xfree(fp);
629 } else {
630 if (hash && (name = host_hash(name, NULL, 0)) == NULL)
631 fatal("hash_host failed");
632 fprintf(f, "%s ", name);
633 if (!key_write(public, f))
634 fatal("key_write failed");
635 fprintf(f, "\n");
636 }
609} 637}
610 638
611static void 639static void
@@ -615,7 +643,7 @@ do_known_hosts(struct passwd *pw, const char *name)
615 Key *public; 643 Key *public;
616 char *cp, *cp2, *kp, *kp2; 644 char *cp, *cp2, *kp, *kp2;
617 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; 645 char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN];
618 int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; 646 int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0;
619 647
620 if (!have_identity) { 648 if (!have_identity) {
621 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); 649 cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
@@ -650,19 +678,18 @@ do_known_hosts(struct passwd *pw, const char *name)
650 } 678 }
651 679
652 while (fgets(line, sizeof(line), in)) { 680 while (fgets(line, sizeof(line), in)) {
653 num++; 681 if ((cp = strchr(line, '\n')) == NULL) {
654 i = strlen(line) - 1; 682 error("line %d too long: %.40s...", num + 1, line);
655 if (line[i] != '\n') {
656 error("line %d too long: %.40s...", num, line);
657 skip = 1; 683 skip = 1;
658 invalid = 1; 684 invalid = 1;
659 continue; 685 continue;
660 } 686 }
687 num++;
661 if (skip) { 688 if (skip) {
662 skip = 0; 689 skip = 0;
663 continue; 690 continue;
664 } 691 }
665 line[i] = '\0'; 692 *cp = '\0';
666 693
667 /* Skip leading whitespace, empty and comment lines. */ 694 /* Skip leading whitespace, empty and comment lines. */
668 for (cp = line; *cp == ' ' || *cp == '\t'; cp++) 695 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
@@ -726,7 +753,8 @@ do_known_hosts(struct passwd *pw, const char *name)
726 printf("# Host %s found: " 753 printf("# Host %s found: "
727 "line %d type %s\n", name, 754 "line %d type %s\n", name,
728 num, key_type(public)); 755 num, key_type(public));
729 print_host(out, cp, public, hash_hosts); 756 print_host(out, name, public,
757 hash_hosts);
730 } 758 }
731 if (delete_host && !c) 759 if (delete_host && !c)
732 print_host(out, cp, public, 0); 760 print_host(out, cp, public, 0);
@@ -750,7 +778,7 @@ do_known_hosts(struct passwd *pw, const char *name)
750 fclose(in); 778 fclose(in);
751 779
752 if (invalid) { 780 if (invalid) {
753 fprintf(stderr, "%s is not a valid known_host file.\n", 781 fprintf(stderr, "%s is not a valid known_hosts file.\n",
754 identity_file); 782 identity_file);
755 if (inplace) { 783 if (inplace) {
756 fprintf(stderr, "Not replacing existing known_hosts " 784 fprintf(stderr, "Not replacing existing known_hosts "
@@ -962,8 +990,7 @@ do_change_comment(struct passwd *pw)
962 key_free(private); 990 key_free(private);
963 exit(1); 991 exit(1);
964 } 992 }
965 if (strchr(new_comment, '\n')) 993 new_comment[strcspn(new_comment, "\n")] = '\0';
966 *strchr(new_comment, '\n') = 0;
967 } 994 }
968 995
969 /* Save the file using the new passphrase. */ 996 /* Save the file using the new passphrase. */
@@ -1006,7 +1033,7 @@ do_change_comment(struct passwd *pw)
1006static void 1033static void
1007usage(void) 1034usage(void)
1008{ 1035{
1009 fprintf(stderr, "Usage: %s [options]\n", __progname); 1036 fprintf(stderr, "usage: %s [options]\n", __progname);
1010 fprintf(stderr, "Options:\n"); 1037 fprintf(stderr, "Options:\n");
1011 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); 1038 fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n");
1012 fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); 1039 fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
@@ -1059,7 +1086,6 @@ main(int argc, char **argv)
1059 int opt, type, fd, download = 0; 1086 int opt, type, fd, download = 0;
1060 u_int32_t memory = 0, generator_wanted = 0, trials = 100; 1087 u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1061 int do_gen_candidates = 0, do_screen_candidates = 0; 1088 int do_gen_candidates = 0, do_screen_candidates = 0;
1062 int log_level = SYSLOG_LEVEL_INFO;
1063 BIGNUM *start = NULL; 1089 BIGNUM *start = NULL;
1064 FILE *f; 1090 FILE *f;
1065 const char *errstr; 1091 const char *errstr;
@@ -1232,6 +1258,10 @@ main(int argc, char **argv)
1232 printf("Can only have one of -p and -c.\n"); 1258 printf("Can only have one of -p and -c.\n");
1233 usage(); 1259 usage();
1234 } 1260 }
1261 if (print_fingerprint && (delete_host || hash_hosts)) {
1262 printf("Cannot use -l with -D or -R.\n");
1263 usage();
1264 }
1235 if (delete_host || hash_hosts || find_host) 1265 if (delete_host || hash_hosts || find_host)
1236 do_known_hosts(pw, rr_hostname); 1266 do_known_hosts(pw, rr_hostname);
1237 if (print_fingerprint || print_bubblebabble) 1267 if (print_fingerprint || print_bubblebabble)
@@ -1436,10 +1466,15 @@ passphrase_again:
1436 1466
1437 if (!quiet) { 1467 if (!quiet) {
1438 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); 1468 char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX);
1469 char *ra = key_fingerprint(public, SSH_FP_MD5,
1470 SSH_FP_RANDOMART);
1439 printf("Your public key has been saved in %s.\n", 1471 printf("Your public key has been saved in %s.\n",
1440 identity_file); 1472 identity_file);
1441 printf("The key fingerprint is:\n"); 1473 printf("The key fingerprint is:\n");
1442 printf("%s %s\n", fp, comment); 1474 printf("%s %s\n", fp, comment);
1475 printf("The key's randomart image is:\n");
1476 printf("%s\n", ra);
1477 xfree(ra);
1443 xfree(fp); 1478 xfree(fp);
1444 } 1479 }
1445 1480