~ubuntu-branches/ubuntu/lucid/openssh/lucid

« back to all changes in this revision

Viewing changes to ssh-keygen.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2008-09-30 23:09:58 UTC
  • mfrom: (1.13.3 upstream) (29 hardy)
  • mto: This revision was merged to the branch mainline in revision 43.
  • Revision ID: james.westby@ubuntu.com-20080930230958-o6vsgn8c4mm959s0
Tags: 1:5.1p1-3
* Remove unnecessary ssh-vulnkey output in non-verbose mode when no
  compromised or unknown keys were found (closes: #496495).
* Configure with --disable-strip; dh_strip will deal with stripping
  binaries and will honour DEB_BUILD_OPTIONS (thanks, Bernhard R. Link;
  closes: #498681).
* Fix handling of zero-length server banners (thanks, Tomas Mraz; closes:
  #497026).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
3
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4
4
 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
21
21
 
22
22
#include <openssl/evp.h>
23
23
#include <openssl/pem.h>
 
24
#include "openbsd-compat/openssl-compat.h"
24
25
 
25
26
#include <errno.h>
26
27
#include <fcntl.h>
71
72
 
72
73
int quiet = 0;
73
74
 
 
75
int log_level = SYSLOG_LEVEL_INFO;
 
76
 
74
77
/* Flag indicating that we want to hash a known_hosts file */
75
78
int hash_hosts = 0;
76
79
/* Flag indicating that we want lookup a host in known_hosts file */
141
144
        fprintf(stderr, "%s (%s): ", prompt, identity_file);
142
145
        if (fgets(buf, sizeof(buf), stdin) == NULL)
143
146
                exit(1);
144
 
        if (strchr(buf, '\n'))
145
 
                *strchr(buf, '\n') = 0;
 
147
        buf[strcspn(buf, "\n")] = '\0';
146
148
        if (strcmp(buf, "") != 0)
147
149
                strlcpy(identity_file, buf, sizeof(identity_file));
148
150
        have_identity = 1;
504
506
{
505
507
        FILE *f;
506
508
        Key *public;
507
 
        char *comment = NULL, *cp, *ep, line[16*1024], *fp;
508
 
        int i, skip = 0, num = 1, invalid = 1;
 
509
        char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra;
 
510
        int i, skip = 0, num = 0, invalid = 1;
509
511
        enum fp_rep rep;
510
512
        enum fp_type fptype;
511
513
        struct stat st;
522
524
        public = key_load_public(identity_file, &comment);
523
525
        if (public != NULL) {
524
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
532
                key_free(public);
527
533
                xfree(comment);
 
534
                xfree(ra);
528
535
                xfree(fp);
529
536
                exit(0);
530
537
        }
536
543
        f = fopen(identity_file, "r");
537
544
        if (f != NULL) {
538
545
                while (fgets(line, sizeof(line), f)) {
539
 
                        i = strlen(line) - 1;
540
 
                        if (line[i] != '\n') {
541
 
                                error("line %d too long: %.40s...", num, line);
 
546
                        if ((cp = strchr(line, '\n')) == NULL) {
 
547
                                error("line %d too long: %.40s...",
 
548
                                    num + 1, line);
542
549
                                skip = 1;
543
550
                                continue;
544
551
                        }
547
554
                                skip = 0;
548
555
                                continue;
549
556
                        }
550
 
                        line[i] = '\0';
 
557
                        *cp = '\0';
551
558
 
552
559
                        /* Skip leading whitespace, empty and comment lines. */
553
560
                        for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
582
589
                        }
583
590
                        comment = *cp ? cp : comment;
584
591
                        fp = key_fingerprint(public, fptype, rep);
585
 
                        printf("%u %s %s\n", key_size(public), fp,
586
 
                            comment ? comment : "no comment");
 
592
                        ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART);
 
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
598
                        xfree(fp);
588
599
                        key_free(public);
589
600
                        invalid = 0;
598
609
}
599
610
 
600
611
static void
601
 
print_host(FILE *f, char *name, Key *public, int hash)
 
612
print_host(FILE *f, const char *name, Key *public, int hash)
602
613
{
603
 
        if (hash && (name = host_hash(name, NULL, 0)) == NULL)
604
 
                fatal("hash_host failed");
605
 
        fprintf(f, "%s ", name);
606
 
        if (!key_write(public, f))
607
 
                fatal("key_write failed");
608
 
        fprintf(f, "\n");
 
614
        if (print_fingerprint) {
 
615
                enum fp_rep rep;
 
616
                enum fp_type fptype;
 
617
                char *fp, *ra;
 
618
 
 
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
 
611
639
static void
615
643
        Key *public;
616
644
        char *cp, *cp2, *kp, *kp2;
617
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
648
        if (!have_identity) {
621
649
                cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid);
650
678
        }
651
679
 
652
680
        while (fgets(line, sizeof(line), in)) {
 
681
                if ((cp = strchr(line, '\n')) == NULL) {
 
682
                        error("line %d too long: %.40s...", num + 1, line);
 
683
                        skip = 1;
 
684
                        invalid = 1;
 
685
                        continue;
 
686
                }
653
687
                num++;
654
 
                i = strlen(line) - 1;
655
 
                if (line[i] != '\n') {
656
 
                        error("line %d too long: %.40s...", num, line);
657
 
                        skip = 1;
658
 
                        invalid = 1;
659
 
                        continue;
660
 
                }
661
688
                if (skip) {
662
689
                        skip = 0;
663
690
                        continue;
664
691
                }
665
 
                line[i] = '\0';
 
692
                *cp = '\0';
666
693
 
667
694
                /* Skip leading whitespace, empty and comment lines. */
668
695
                for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
726
753
                                        printf("# Host %s found: "
727
754
                                            "line %d type %s\n", name,
728
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
759
                                if (delete_host && !c)
732
760
                                        print_host(out, cp, public, 0);
750
778
        fclose(in);
751
779
 
752
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
782
                    identity_file);
755
783
                if (inplace) {
756
784
                        fprintf(stderr, "Not replacing existing known_hosts "
962
990
                        key_free(private);
963
991
                        exit(1);
964
992
                }
965
 
                if (strchr(new_comment, '\n'))
966
 
                        *strchr(new_comment, '\n') = 0;
 
993
                new_comment[strcspn(new_comment, "\n")] = '\0';
967
994
        }
968
995
 
969
996
        /* Save the file using the new passphrase. */
1006
1033
static void
1007
1034
usage(void)
1008
1035
{
1009
 
        fprintf(stderr, "Usage: %s [options]\n", __progname);
 
1036
        fprintf(stderr, "usage: %s [options]\n", __progname);
1010
1037
        fprintf(stderr, "Options:\n");
1011
1038
        fprintf(stderr, "  -a trials   Number of trials for screening DH-GEX moduli.\n");
1012
1039
        fprintf(stderr, "  -B          Show bubblebabble digest of key file.\n");
1059
1086
        int opt, type, fd, download = 0;
1060
1087
        u_int32_t memory = 0, generator_wanted = 0, trials = 100;
1061
1088
        int do_gen_candidates = 0, do_screen_candidates = 0;
1062
 
        int log_level = SYSLOG_LEVEL_INFO;
1063
1089
        BIGNUM *start = NULL;
1064
1090
        FILE *f;
1065
1091
        const char *errstr;
1232
1258
                printf("Can only have one of -p and -c.\n");
1233
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
1265
        if (delete_host || hash_hosts || find_host)
1236
1266
                do_known_hosts(pw, rr_hostname);
1237
1267
        if (print_fingerprint || print_bubblebabble)
1436
1466
 
1437
1467
        if (!quiet) {
1438
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
1471
                printf("Your public key has been saved in %s.\n",
1440
1472
                    identity_file);
1441
1473
                printf("The key fingerprint is:\n");
1442
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
1478
                xfree(fp);
1444
1479
        }
1445
1480