diff options
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | authfile.c | 59 | ||||
-rw-r--r-- | authfile.h | 1 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | pathnames.h | 7 | ||||
-rw-r--r-- | ssh-vulnkey.1 | 6 | ||||
-rw-r--r-- | ssh-vulnkey.c | 9 |
7 files changed, 57 insertions, 31 deletions
diff --git a/Makefile.in b/Makefile.in index 0c6f7e550..a6b8aa693 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -26,6 +26,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass | |||
26 | SFTP_SERVER=$(libexecdir)/sftp-server | 26 | SFTP_SERVER=$(libexecdir)/sftp-server |
27 | SSH_KEYSIGN=$(libexecdir)/ssh-keysign | 27 | SSH_KEYSIGN=$(libexecdir)/ssh-keysign |
28 | RAND_HELPER=$(libexecdir)/ssh-rand-helper | 28 | RAND_HELPER=$(libexecdir)/ssh-rand-helper |
29 | SSH_DATADIR=$(datadir)/ssh | ||
29 | PRIVSEP_PATH=@PRIVSEP_PATH@ | 30 | PRIVSEP_PATH=@PRIVSEP_PATH@ |
30 | SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ | 31 | SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ |
31 | STRIP_OPT=@STRIP_OPT@ | 32 | STRIP_OPT=@STRIP_OPT@ |
@@ -37,7 +38,8 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ | |||
37 | -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ | 38 | -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ |
38 | -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ | 39 | -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ |
39 | -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ | 40 | -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ |
40 | -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" | 41 | -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" \ |
42 | -D_PATH_SSH_DATADIR=\"$(SSH_DATADIR)\" | ||
41 | 43 | ||
42 | CC=@CC@ | 44 | CC=@CC@ |
43 | LD=@LD@ | 45 | LD=@LD@ |
diff --git a/authfile.c b/authfile.c index a18509a50..9ab90e3c8 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -679,22 +679,10 @@ key_load_public(const char *filename, char **commentp) | |||
679 | return NULL; | 679 | return NULL; |
680 | } | 680 | } |
681 | 681 | ||
682 | char * | 682 | /* Scan a blacklist of known-vulnerable keys in blacklist_file. */ |
683 | blacklist_filename(const Key *key) | 683 | static int |
684 | { | 684 | blacklisted_key_in_file(const Key *key, const char *blacklist_file) |
685 | char *name; | ||
686 | |||
687 | xasprintf(&name, "%s.%s-%u", | ||
688 | _PATH_BLACKLIST, key_type(key), key_size(key)); | ||
689 | return name; | ||
690 | } | ||
691 | |||
692 | /* Scan a blacklist of known-vulnerable keys. */ | ||
693 | int | ||
694 | blacklisted_key(const Key *key) | ||
695 | { | 685 | { |
696 | Key *public; | ||
697 | char *blacklist_file; | ||
698 | int fd = -1; | 686 | int fd = -1; |
699 | char *dgst_hex = NULL; | 687 | char *dgst_hex = NULL; |
700 | char *dgst_packed = NULL, *p; | 688 | char *dgst_packed = NULL, *p; |
@@ -705,17 +693,14 @@ blacklisted_key(const Key *key) | |||
705 | off_t start, lower, upper; | 693 | off_t start, lower, upper; |
706 | int ret = 0; | 694 | int ret = 0; |
707 | 695 | ||
708 | public = key_demote(key); | ||
709 | if (public->type == KEY_RSA1) | ||
710 | public->type = KEY_RSA; | ||
711 | |||
712 | blacklist_file = blacklist_filename(public); | ||
713 | debug("Checking blacklist file %s", blacklist_file); | 696 | debug("Checking blacklist file %s", blacklist_file); |
714 | fd = open(blacklist_file, O_RDONLY); | 697 | fd = open(blacklist_file, O_RDONLY); |
715 | if (fd < 0) | 698 | if (fd < 0) { |
699 | ret = -1; | ||
716 | goto out; | 700 | goto out; |
701 | } | ||
717 | 702 | ||
718 | dgst_hex = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); | 703 | dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); |
719 | /* Remove all colons */ | 704 | /* Remove all colons */ |
720 | dgst_packed = xcalloc(1, strlen(dgst_hex) + 1); | 705 | dgst_packed = xcalloc(1, strlen(dgst_hex) + 1); |
721 | for (i = 0, p = dgst_packed; dgst_hex[i]; i++) | 706 | for (i = 0, p = dgst_packed; dgst_hex[i]; i++) |
@@ -790,7 +775,37 @@ out: | |||
790 | xfree(dgst_hex); | 775 | xfree(dgst_hex); |
791 | if (fd >= 0) | 776 | if (fd >= 0) |
792 | close(fd); | 777 | close(fd); |
778 | return ret; | ||
779 | } | ||
780 | |||
781 | /* Scan blacklists of known-vulnerable keys. */ | ||
782 | int | ||
783 | blacklisted_key(const Key *key) | ||
784 | { | ||
785 | Key *public; | ||
786 | char *blacklist_file; | ||
787 | int ret, ret2; | ||
788 | |||
789 | public = key_demote(key); | ||
790 | if (public->type == KEY_RSA1) | ||
791 | public->type = KEY_RSA; | ||
792 | |||
793 | xasprintf(&blacklist_file, "%s.%s-%u", | ||
794 | _PATH_BLACKLIST, key_type(public), key_size(public)); | ||
795 | ret = blacklisted_key_in_file(public, blacklist_file); | ||
793 | xfree(blacklist_file); | 796 | xfree(blacklist_file); |
797 | if (ret > 0) { | ||
798 | key_free(public); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | xasprintf(&blacklist_file, "%s.%s-%u", | ||
803 | _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public)); | ||
804 | ret2 = blacklisted_key_in_file(public, blacklist_file); | ||
805 | xfree(blacklist_file); | ||
806 | if (ret2 > ret) | ||
807 | ret = ret2; | ||
808 | |||
794 | key_free(public); | 809 | key_free(public); |
795 | return ret; | 810 | return ret; |
796 | } | 811 | } |
diff --git a/authfile.h b/authfile.h index e47710495..91557e4a2 100644 --- a/authfile.h +++ b/authfile.h | |||
@@ -23,7 +23,6 @@ Key *key_load_private_type(int, const char *, const char *, char **, int *); | |||
23 | Key *key_load_private_pem(int, int, const char *, char **); | 23 | Key *key_load_private_pem(int, int, const char *, char **); |
24 | int key_perm_ok(int, const char *); | 24 | int key_perm_ok(int, const char *); |
25 | 25 | ||
26 | char *blacklist_filename(const Key *key); | ||
27 | int blacklisted_key(const Key *key); | 26 | int blacklisted_key(const Key *key); |
28 | 27 | ||
29 | #endif | 28 | #endif |
diff --git a/debian/changelog b/debian/changelog index dd94c58e0..775cf81eb 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -26,6 +26,8 @@ openssh (1:4.7p1-11) UNRELEASED; urgency=low | |||
26 | openssh-server. | 26 | openssh-server. |
27 | * Make ssh-vulnkey report the file name and line number for each key | 27 | * Make ssh-vulnkey report the file name and line number for each key |
28 | (thanks, Heiko Schlittermann and Christopher Perry; closes: #481398). | 28 | (thanks, Heiko Schlittermann and Christopher Perry; closes: #481398). |
29 | * Check for blacklists in /usr/share/ssh/ as well as /etc/ssh/ (see | ||
30 | #481283). | ||
29 | 31 | ||
30 | -- Colin Watson <cjwatson@debian.org> Sat, 17 May 2008 08:48:45 +0200 | 32 | -- Colin Watson <cjwatson@debian.org> Sat, 17 May 2008 08:48:45 +0200 |
31 | 33 | ||
diff --git a/pathnames.h b/pathnames.h index 8886e8edd..e07123437 100644 --- a/pathnames.h +++ b/pathnames.h | |||
@@ -18,6 +18,10 @@ | |||
18 | #define SSHDIR ETCDIR "/ssh" | 18 | #define SSHDIR ETCDIR "/ssh" |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #ifndef _PATH_SSH_DATADIR | ||
22 | #define _PATH_SSH_DATADIR "/usr/share/ssh" | ||
23 | #endif | ||
24 | |||
21 | #ifndef _PATH_SSH_PIDDIR | 25 | #ifndef _PATH_SSH_PIDDIR |
22 | #define _PATH_SSH_PIDDIR "/var/run" | 26 | #define _PATH_SSH_PIDDIR "/var/run" |
23 | #endif | 27 | #endif |
@@ -43,7 +47,8 @@ | |||
43 | /* Backwards compatibility */ | 47 | /* Backwards compatibility */ |
44 | #define _PATH_DH_PRIMES SSHDIR "/primes" | 48 | #define _PATH_DH_PRIMES SSHDIR "/primes" |
45 | 49 | ||
46 | #define _PATH_BLACKLIST SSHDIR "/blacklist" | 50 | #define _PATH_BLACKLIST _PATH_SSH_DATADIR "/blacklist" |
51 | #define _PATH_BLACKLIST_CONFIG SSHDIR "/blacklist" | ||
47 | 52 | ||
48 | #ifndef _PATH_SSH_PROGRAM | 53 | #ifndef _PATH_SSH_PROGRAM |
49 | #define _PATH_SSH_PROGRAM "/usr/bin/ssh" | 54 | #define _PATH_SSH_PROGRAM "/usr/bin/ssh" |
diff --git a/ssh-vulnkey.1 b/ssh-vulnkey.1 index 73570fcad..c0a7592f8 100644 --- a/ssh-vulnkey.1 +++ b/ssh-vulnkey.1 | |||
@@ -163,7 +163,7 @@ If present, contains the protocol version 2 RSA identity of the system. | |||
163 | If present, contains the protocol version 2 DSA identity of the system. | 163 | If present, contains the protocol version 2 DSA identity of the system. |
164 | .It Pa /etc/ssh/ssh_host_key | 164 | .It Pa /etc/ssh/ssh_host_key |
165 | If present, contains the protocol version 1 RSA identity of the system. | 165 | If present, contains the protocol version 1 RSA identity of the system. |
166 | .It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH | 166 | .It Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH |
167 | If present, lists the blacklisted keys of type | 167 | If present, lists the blacklisted keys of type |
168 | .Ar TYPE | 168 | .Ar TYPE |
169 | .Pf ( Dq RSA | 169 | .Pf ( Dq RSA |
@@ -175,6 +175,10 @@ The format of this file is described above. | |||
175 | RSA1 keys are converted to RSA before being checked in the blacklist. | 175 | RSA1 keys are converted to RSA before being checked in the blacklist. |
176 | Note that the fingerprints of RSA1 keys are computed differently, so you | 176 | Note that the fingerprints of RSA1 keys are computed differently, so you |
177 | will not be able to find them in the blacklist by hand. | 177 | will not be able to find them in the blacklist by hand. |
178 | .It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH | ||
179 | Same as | ||
180 | .Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH , | ||
181 | but may be edited by the system administrator to add new blacklist entries. | ||
178 | .El | 182 | .El |
179 | .Sh SEE ALSO | 183 | .Sh SEE ALSO |
180 | .Xr ssh-keygen 1 , | 184 | .Xr ssh-keygen 1 , |
diff --git a/ssh-vulnkey.c b/ssh-vulnkey.c index 3c7985448..f78615478 100644 --- a/ssh-vulnkey.c +++ b/ssh-vulnkey.c | |||
@@ -90,26 +90,25 @@ do_key(const char *filename, u_long linenum, | |||
90 | const Key *key, const char *comment) | 90 | const Key *key, const char *comment) |
91 | { | 91 | { |
92 | Key *public; | 92 | Key *public; |
93 | char *blacklist_file; | ||
94 | struct stat st; | 93 | struct stat st; |
94 | int blacklist_status; | ||
95 | int ret = 1; | 95 | int ret = 1; |
96 | 96 | ||
97 | public = key_demote(key); | 97 | public = key_demote(key); |
98 | if (public->type == KEY_RSA1) | 98 | if (public->type == KEY_RSA1) |
99 | public->type = KEY_RSA; | 99 | public->type = KEY_RSA; |
100 | 100 | ||
101 | blacklist_file = blacklist_filename(public); | 101 | blacklist_status = blacklisted_key(public); |
102 | if (stat(blacklist_file, &st) < 0) | 102 | if (blacklist_status == -1) |
103 | describe_key(filename, linenum, | 103 | describe_key(filename, linenum, |
104 | "Unknown (no blacklist information)", key, comment); | 104 | "Unknown (no blacklist information)", key, comment); |
105 | else if (blacklisted_key(public)) { | 105 | else if (blacklist_status == 1) { |
106 | describe_key(filename, linenum, | 106 | describe_key(filename, linenum, |
107 | "COMPROMISED", key, comment); | 107 | "COMPROMISED", key, comment); |
108 | ret = 0; | 108 | ret = 0; |
109 | } else | 109 | } else |
110 | describe_key(filename, linenum, | 110 | describe_key(filename, linenum, |
111 | "Not blacklisted", key, comment); | 111 | "Not blacklisted", key, comment); |
112 | xfree(blacklist_file); | ||
113 | 112 | ||
114 | key_free(public); | 113 | key_free(public); |
115 | 114 | ||