From 399dfbc499f54bccb81318cbe86acddcd4bdfeee Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 25 May 2008 19:57:41 +0000 Subject: Check for blacklists in /usr/share/ssh/ as well as /etc/ssh/ (see #481283). --- Makefile.in | 4 +++- authfile.c | 59 +++++++++++++++++++++++++++++++++++--------------------- authfile.h | 1 - debian/changelog | 2 ++ pathnames.h | 7 ++++++- ssh-vulnkey.1 | 6 +++++- 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 SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign RAND_HELPER=$(libexecdir)/ssh-rand-helper +SSH_DATADIR=$(datadir)/ssh PRIVSEP_PATH=@PRIVSEP_PATH@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ STRIP_OPT=@STRIP_OPT@ @@ -37,7 +38,8 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ - -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" + -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" \ + -D_PATH_SSH_DATADIR=\"$(SSH_DATADIR)\" CC=@CC@ 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) return NULL; } -char * -blacklist_filename(const Key *key) -{ - char *name; - - xasprintf(&name, "%s.%s-%u", - _PATH_BLACKLIST, key_type(key), key_size(key)); - return name; -} - -/* Scan a blacklist of known-vulnerable keys. */ -int -blacklisted_key(const Key *key) +/* Scan a blacklist of known-vulnerable keys in blacklist_file. */ +static int +blacklisted_key_in_file(const Key *key, const char *blacklist_file) { - Key *public; - char *blacklist_file; int fd = -1; char *dgst_hex = NULL; char *dgst_packed = NULL, *p; @@ -705,17 +693,14 @@ blacklisted_key(const Key *key) off_t start, lower, upper; int ret = 0; - public = key_demote(key); - if (public->type == KEY_RSA1) - public->type = KEY_RSA; - - blacklist_file = blacklist_filename(public); debug("Checking blacklist file %s", blacklist_file); fd = open(blacklist_file, O_RDONLY); - if (fd < 0) + if (fd < 0) { + ret = -1; goto out; + } - dgst_hex = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); + dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); /* Remove all colons */ dgst_packed = xcalloc(1, strlen(dgst_hex) + 1); for (i = 0, p = dgst_packed; dgst_hex[i]; i++) @@ -790,7 +775,37 @@ out: xfree(dgst_hex); if (fd >= 0) close(fd); + return ret; +} + +/* Scan blacklists of known-vulnerable keys. */ +int +blacklisted_key(const Key *key) +{ + Key *public; + char *blacklist_file; + int ret, ret2; + + public = key_demote(key); + if (public->type == KEY_RSA1) + public->type = KEY_RSA; + + xasprintf(&blacklist_file, "%s.%s-%u", + _PATH_BLACKLIST, key_type(public), key_size(public)); + ret = blacklisted_key_in_file(public, blacklist_file); xfree(blacklist_file); + if (ret > 0) { + key_free(public); + return ret; + } + + xasprintf(&blacklist_file, "%s.%s-%u", + _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public)); + ret2 = blacklisted_key_in_file(public, blacklist_file); + xfree(blacklist_file); + if (ret2 > ret) + ret = ret2; + key_free(public); return ret; } 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 *); Key *key_load_private_pem(int, int, const char *, char **); int key_perm_ok(int, const char *); -char *blacklist_filename(const Key *key); int blacklisted_key(const Key *key); #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 openssh-server. * Make ssh-vulnkey report the file name and line number for each key (thanks, Heiko Schlittermann and Christopher Perry; closes: #481398). + * Check for blacklists in /usr/share/ssh/ as well as /etc/ssh/ (see + #481283). -- Colin Watson Sat, 17 May 2008 08:48:45 +0200 diff --git a/pathnames.h b/pathnames.h index 8886e8edd..e07123437 100644 --- a/pathnames.h +++ b/pathnames.h @@ -18,6 +18,10 @@ #define SSHDIR ETCDIR "/ssh" #endif +#ifndef _PATH_SSH_DATADIR +#define _PATH_SSH_DATADIR "/usr/share/ssh" +#endif + #ifndef _PATH_SSH_PIDDIR #define _PATH_SSH_PIDDIR "/var/run" #endif @@ -43,7 +47,8 @@ /* Backwards compatibility */ #define _PATH_DH_PRIMES SSHDIR "/primes" -#define _PATH_BLACKLIST SSHDIR "/blacklist" +#define _PATH_BLACKLIST _PATH_SSH_DATADIR "/blacklist" +#define _PATH_BLACKLIST_CONFIG SSHDIR "/blacklist" #ifndef _PATH_SSH_PROGRAM #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. If present, contains the protocol version 2 DSA identity of the system. .It Pa /etc/ssh/ssh_host_key If present, contains the protocol version 1 RSA identity of the system. -.It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH +.It Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH If present, lists the blacklisted keys of type .Ar TYPE .Pf ( Dq RSA @@ -175,6 +175,10 @@ The format of this file is described above. RSA1 keys are converted to RSA before being checked in the blacklist. Note that the fingerprints of RSA1 keys are computed differently, so you will not be able to find them in the blacklist by hand. +.It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH +Same as +.Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH , +but may be edited by the system administrator to add new blacklist entries. .El .Sh SEE ALSO .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, const Key *key, const char *comment) { Key *public; - char *blacklist_file; struct stat st; + int blacklist_status; int ret = 1; public = key_demote(key); if (public->type == KEY_RSA1) public->type = KEY_RSA; - blacklist_file = blacklist_filename(public); - if (stat(blacklist_file, &st) < 0) + blacklist_status = blacklisted_key(public); + if (blacklist_status == -1) describe_key(filename, linenum, "Unknown (no blacklist information)", key, comment); - else if (blacklisted_key(public)) { + else if (blacklist_status == 1) { describe_key(filename, linenum, "COMPROMISED", key, comment); ret = 0; } else describe_key(filename, linenum, "Not blacklisted", key, comment); - xfree(blacklist_file); key_free(public); -- cgit v1.2.3