SOURCES: openssh-blacklist.diff (NEW) - blacklist support and ssh-vulnkey t...

jajcus jajcus at pld-linux.org
Tue May 20 15:15:34 CEST 2008


Author: jajcus                       Date: Tue May 20 13:15:33 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- blacklist support and ssh-vulnkey tool for openssh (from Debian)

---- Files affected:
SOURCES:
   openssh-blacklist.diff (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/openssh-blacklist.diff
diff -u /dev/null SOURCES/openssh-blacklist.diff:1.1
--- /dev/null	Tue May 20 15:15:34 2008
+++ SOURCES/openssh-blacklist.diff	Tue May 20 15:15:28 2008
@@ -0,0 +1,991 @@
+This patch is against OpenSSH 4.7p1, although should apply to other versions
+without too much difficulty. It makes the following changes:
+
+  * Add key blacklisting support. Keys listed in
+    /etc/ssh/blacklist.TYPE-LENGTH will be rejected for authentication by
+    sshd, unless "PermitBlacklistedKeys yes" is set in /etc/ssh/sshd_config.
+
+  * Add a new program, ssh-vulnkey, which can be used to check keys against
+    these blacklists.
+
+This patch is up to date with respect to Debian openssh 1:4.7p1-10.
+
+--- openssh-4.7p1.orig/sshd_config.5
++++ openssh-4.7p1/sshd_config.5
+@@ -615,6 +615,20 @@
+ Specifies whether password authentication is allowed.
+ The default is
+ .Dq yes .
++.It Cm PermitBlacklistedKeys
++Specifies whether
++.Xr sshd 8
++should allow keys recorded in its blacklist of known-compromised keys (see
++.Xr ssh-vulnkey 1 ) .
++If
++.Dq yes ,
++then attempts to authenticate with compromised keys will be logged but
++accepted.
++If
++.Dq no ,
++then attempts to authenticate with compromised keys will be rejected.
++The default is
++.Dq no .
+ .It Cm PermitEmptyPasswords
+ When password authentication is allowed, it specifies whether the
+ server allows login to accounts with empty password strings.
+--- openssh-4.7p1.orig/sshd.c
++++ openssh-4.7p1/sshd.c
+@@ -1466,6 +1466,21 @@
+ 
+ 	for (i = 0; i < options.num_host_key_files; i++) {
+ 		key = key_load_private(options.host_key_files[i], "", NULL);
++		if (key && blacklisted_key(key)) {
++			char *fp;
++			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
++			if (options.permit_blacklisted_keys)
++				error("Host key %s blacklisted (see "
++				    "ssh-vulnkey(1)); continuing anyway", fp);
++			else
++				error("Host key %s blacklisted (see "
++				    "ssh-vulnkey(1))", fp);
++			xfree(fp);
++			if (!options.permit_blacklisted_keys) {
++				sensitive_data.host_keys[i] = NULL;
++				continue;
++			}
++		}
+ 		sensitive_data.host_keys[i] = key;
+ 		if (key == NULL) {
+ 			error("Could not load host key: %s",
+--- openssh-4.7p1.orig/servconf.c
++++ openssh-4.7p1/servconf.c
+@@ -96,6 +96,7 @@
+ 	options->password_authentication = -1;
+ 	options->kbd_interactive_authentication = -1;
+ 	options->challenge_response_authentication = -1;
++	options->permit_blacklisted_keys = -1;
+ 	options->permit_empty_passwd = -1;
+ 	options->permit_user_env = -1;
+ 	options->use_login = -1;
+@@ -218,6 +219,8 @@
+ 		options->kbd_interactive_authentication = 0;
+ 	if (options->challenge_response_authentication == -1)
+ 		options->challenge_response_authentication = 1;
++	if (options->permit_blacklisted_keys == -1)
++		options->permit_blacklisted_keys = 0;
+ 	if (options->permit_empty_passwd == -1)
+ 		options->permit_empty_passwd = 0;
+ 	if (options->permit_user_env == -1)
+@@ -287,7 +290,7 @@
+ 	sListenAddress, sAddressFamily,
+ 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
+ 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
+-	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
++	sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive,
+ 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
+ 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
+ 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
+@@ -387,6 +390,7 @@
+ 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
+ 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
+ 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
++	{ "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL },
+ 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
+ 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
+ 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
+@@ -943,6 +947,10 @@
+ 		intptr = &options->tcp_keep_alive;
+ 		goto parse_flag;
+ 
++	case sPermitBlacklistedKeys:
++		intptr = &options->permit_blacklisted_keys;
++		goto parse_flag;
++
+ 	case sEmptyPasswd:
+ 		intptr = &options->permit_empty_passwd;
+ 		goto parse_flag;
+--- openssh-4.7p1.orig/servconf.h
++++ openssh-4.7p1/servconf.h
+@@ -94,6 +94,7 @@
+ 						 * authentication. */
+ 	int     kbd_interactive_authentication;	/* If true, permit */
+ 	int     challenge_response_authentication;
++	int     permit_blacklisted_keys;	/* If true, permit */
+ 	int     permit_empty_passwd;	/* If false, do not permit empty
+ 					 * passwords. */
+ 	int     permit_user_env;	/* If true, read ~/.ssh/environment */
+--- openssh-4.7p1.orig/Makefile.in
++++ openssh-4.7p1/Makefile.in
+@@ -60,7 +60,7 @@
+ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
+ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
+ 
+-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-vulnkey$(EXEEXT)
+ 
+ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+ 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
+@@ -88,8 +88,8 @@
+ 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
+ 	audit.o audit-bsm.o platform.o
+ 
+-MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
+-MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
++MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out
++MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5
+ MANTYPE		= @MANTYPE@
+ 
+ CONFIGFILES=sshd_config.out ssh_config.out moduli.out
+@@ -165,6 +165,9 @@
+ ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
+ 	$(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ 
++ssh-vulnkey$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-vulnkey.o
++	$(LD) -o $@ ssh-vulnkey.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
++
+ # test driver for the loginrec code - not built by default
+ logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
+ 	$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
+@@ -264,6 +267,7 @@
+ 	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN)
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp
+ 	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER)
++	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-vulnkey $(DESTDIR)$(bindir)/ssh-vulnkey
+ 	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
+ 	$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
+ 	$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
+@@ -280,6 +284,7 @@
+ 	$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
+ 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+ 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
++	$(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
+ 	-rm -f $(DESTDIR)$(bindir)/slogin
+ 	ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+@@ -361,6 +366,7 @@
+ 	-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
++	-rm -f $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
+ 	-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
+ 	-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
+@@ -373,6 +379,7 @@
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
++	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8
+ 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
+--- openssh-4.7p1.orig/auth-rh-rsa.c
++++ openssh-4.7p1/auth-rh-rsa.c
+@@ -20,6 +20,7 @@
+ #include <pwd.h>
+ #include <stdarg.h>
+ 
++#include "xmalloc.h"
+ #include "packet.h"
+ #include "uidswap.h"
+ #include "log.h"
+@@ -27,6 +28,7 @@
+ #include "servconf.h"
+ #include "key.h"
+ #include "hostfile.h"
++#include "authfile.h"
+ #include "pathnames.h"
+ #include "auth.h"
+ #include "canohost.h"
+@@ -42,8 +44,22 @@
+ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
+     Key *client_host_key)
+ {
++	char *fp;
+ 	HostStatus host_status;
+ 
++	if (blacklisted_key(client_host_key)) {
++		fp = key_fingerprint(client_host_key, SSH_FP_MD5, SSH_FP_HEX);
++		if (options.permit_blacklisted_keys)
++			logit("Public key %s blacklisted (see "
++			    "ssh-vulnkey(1)); continuing anyway", fp);
++		else
++			logit("Public key %s blacklisted (see "
++			    "ssh-vulnkey(1))", fp);
++		xfree(fp);
++		if (!options.permit_blacklisted_keys)
++			return 0;
++	}
++
+ 	/* Check if we would accept it using rhosts authentication. */
+ 	if (!auth_rhosts(pw, cuser))
+ 		return 0;
+--- openssh-4.7p1.orig/authfile.h
++++ openssh-4.7p1/authfile.h
+@@ -23,4 +23,7 @@
+ 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
+--- openssh-4.7p1.orig/ssh-vulnkey.1
++++ openssh-4.7p1/ssh-vulnkey.1
+@@ -0,0 +1,187 @@
++.\" Copyright (c) 2008 Canonical Ltd.  All rights reserved.
++.\"
++.\" Redistribution and use in source and binary forms, with or without
++.\" modification, are permitted provided that the following conditions
++.\" are met:
++.\" 1. Redistributions of source code must retain the above copyright
++.\"    notice, this list of conditions and the following disclaimer.
++.\" 2. Redistributions in binary form must reproduce the above copyright
++.\"    notice, this list of conditions and the following disclaimer in the
++.\"    documentation and/or other materials provided with the distribution.
++.\"
++.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
++.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++.\"
++.Dd $Mdocdate: May 12 2008 $
++.Dt SSH-VULNKEY 1
++.Os
++.Sh NAME
++.Nm ssh-vulnkey
++.Nd check blacklist of compromised keys
++.Sh SYNOPSIS
++.Nm
++.Op Fl q
++.Ar file ...
++.Nm
++.Fl a
++.Sh DESCRIPTION
++.Nm
++checks a key against a blacklist of compromised keys.
++.Pp
++A substantial number of keys are known to have been generated using a broken
++version of OpenSSL distributed by Debian which failed to seed its random
++number generator correctly.
++Keys generated using these OpenSSL versions should be assumed to be
++compromised.
++This tool may be useful in checking for such keys.
++.Pp
++Keys that are compromised cannot be repaired; replacements must be generated
++using
++.Xr ssh-keygen 1 .
++Make sure to update
++.Pa authorized_keys
++files on all systems where compromised keys were permitted to authenticate.
++.Pp
++The argument list will be interpreted as a list of paths to public key files
++or
++.Pa authorized_keys
++files.
++If no suitable file is found at a given path,
++.Nm
++will append
++.Pa .pub
++and retry, in case it was given a private key file.
++If no files are given as arguments,
++.Nm
++will check
++.Pa ~/.ssh/id_rsa ,
++.Pa ~/.ssh/id_dsa ,
++.Pa ~/.ssh/identity ,
++.Pa ~/.ssh/authorized_keys
++and
++.Pa ~/.ssh/authorized_keys2 ,
++as well as the system's host keys if readable.
++.Pp
++If
++.Dq -
++is given as an argument,
++.Nm
++will read from standard input.
++This can be used to process output from
++.Xr ssh-keyscan 1 ,
++for example:
++.Pp
++.Dl $ ssh-keyscan -t rsa remote.example.org | ssh-vulnkey -
++.Pp
++.Nm
++will exit zero if any of the given keys were in the compromised list,
++otherwise non-zero.
++.Pp
++Unless the
++.Cm PermitBlacklistedKeys
++option is used,
++.Xr sshd 8
++will reject attempts to authenticate with keys in the compromised list.
++.Pp
++The options are as follows:
++.Bl -tag -width Ds
++.It Fl a
++Check keys of all users on the system.
++You will typically need to run
++.Nm
++as root to use this option.
++For each user,
++.Nm
++will check
++.Pa ~/.ssh/id_rsa ,
++.Pa ~/.ssh/id_dsa ,
++.Pa ~/.ssh/identity ,
++.Pa ~/.ssh/authorized_keys
++and
++.Pa ~/.ssh/authorized_keys2 .
++It will also check the system's host keys.
++.It Fl q
++Quiet mode.
++Normally,
++.Nm
++outputs the fingerprint of each key scanned, with a description of its
++status.
++This option suppresses that output.
++.El
++.Sh BLACKLIST FILE FORMAT
++The blacklist file may start with comments, on lines starting with
++.Dq # .
++After these initial comments, it must follow a strict format:
++.Pp
++.Bl -bullet -offset indent -compact
++.It
++All the lines must be exactly the same length (20 characters followed by a
++newline) and must be in sorted order.
++.It
++Each line must consist of the lower-case hexadecimal MD5 key fingerprint,
++without colons, and with the first 12 characters removed (that is, the least
++significant 80 bits of the fingerprint).
++.El
++.Pp
++The key fingerprint may be generated using
++.Xr ssh-keygen 1 :
++.Pp
++.Dl $ ssh-keygen -l -f /path/to/key
++.Pp
++This strict format is necessary to allow the blacklist file to be checked
++quickly, using a binary-search algorithm.
++.Sh FILES
++.Bl -tag -width Ds
++.It Pa ~/.ssh/id_rsa
++If present, contains the protocol version 2 RSA authentication identity of
++the user.
++.It Pa ~/.ssh/id_dsa
++If present, contains the protocol version 2 DSA authentication identity of
++the user.
++.It Pa ~/.ssh/identity
++If present, contains the protocol version 1 RSA authentication identity of
++the user.
++.It Pa ~/.ssh/authorized_keys
++If present, lists the public keys (RSA/DSA) that can be used for logging in
++as this user.
++.It Pa ~/.ssh/authorized_keys2
++Obsolete name for
++.Pa ~/.ssh/authorized_keys .
++This file may still be present on some old systems, but should not be
++created if it is missing.
++.It Pa /etc/ssh/ssh_host_rsa_key
++If present, contains the protocol version 2 RSA identity of the system.
++.It Pa /etc/ssh/ssh_host_dsa_key
++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
++If present, lists the blacklisted keys of type
++.Ar TYPE
++.Pf ( Dq RSA1 ,
++.Dq RSA ,
++or
++.Dq DSA )
++and bit length
++.Ar LENGTH .
++The format of this file is described above.
++.El
++.Sh SEE ALSO
++.Xr ssh-keygen 1 ,
++.Xr sshd 8
++.Sh AUTHORS
++.An -nosplit
++.An Colin Watson Aq cjwatson at ubuntu.com
++.Pp
++Florian Weimer suggested the option to check keys of all users, and the idea
++of processing
++.Xr ssh-keyscan 1
++output.
+--- openssh-4.7p1.orig/auth2-hostbased.c
++++ openssh-4.7p1/auth2-hostbased.c
+@@ -40,6 +40,7 @@
+ #include "compat.h"
+ #include "key.h"
+ #include "hostfile.h"
++#include "authfile.h"
+ #include "auth.h"
+ #include "canohost.h"
+ #ifdef GSSAPI
+@@ -141,10 +142,24 @@
+ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+     Key *key)
+ {
++	char *fp;
+ 	const char *resolvedname, *ipaddr, *lookup;
+ 	HostStatus host_status;
+ 	int len;
+ 
++	if (blacklisted_key(key)) {
++		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
++		if (options.permit_blacklisted_keys)
++			logit("Public key %s blacklisted (see "
++			    "ssh-vulnkey(1)); continuing anyway", fp);
++		else
++			logit("Public key %s blacklisted (see "
++			    "ssh-vulnkey(1))", fp);
++		xfree(fp);
++		if (!options.permit_blacklisted_keys)
++			return 0;
++	}
++
+ 	resolvedname = get_canonical_hostname(options.use_dns);
+ 	ipaddr = get_remote_ipaddr();
+ 
+--- openssh-4.7p1.orig/authfile.c
++++ openssh-4.7p1/authfile.c
+@@ -65,6 +65,7 @@
+ #include "rsa.h"
+ #include "misc.h"
+ #include "atomicio.h"
++#include "pathnames.h"
+ 
+ /* Version identification string for SSH v1 identity files. */
+ static const char authfile_id_string[] =
+@@ -677,3 +678,113 @@
+ 	key_free(pub);
+ 	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)
++{
++	char *blacklist_file;
++	int fd = -1;
++	char *dgst_hex = NULL;
++	char *dgst_packed = NULL, *p;
++	int i;
++	size_t line_len;
++	struct stat st;
++	char buf[256];
++	off_t start, lower, upper;
++	int ret = 0;
++
++	blacklist_file = blacklist_filename(key);
++	debug("Checking blacklist file %s", blacklist_file);
++	fd = open(blacklist_file, O_RDONLY);
++	if (fd < 0)
++		goto out;
++
++	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++)
++		if (dgst_hex[i] != ':')
++			*p++ = dgst_hex[i];
++	/* Only compare least-significant 80 bits (to keep the blacklist
++	 * size down)
++	 */
++	line_len = strlen(dgst_packed + 12);
++	if (line_len > 32)
++		goto out;
++
++	/* Skip leading comments */
++	start = 0;
++	for (;;) {
++		ssize_t r;
++		char *newline;
++
++		r = atomicio(read, fd, buf, 256);
++		if (r <= 0)
++			goto out;
++		if (buf[0] != '#')
++			break;
++
++		newline = memchr(buf, '\n', 256);
++		if (!newline)
++			goto out;
++		start += newline + 1 - buf;
++		if (lseek(fd, start, SEEK_SET) < 0)
++			goto out;
++	}
++
++	/* Initialise binary search record numbers */
++	if (fstat(fd, &st) < 0)
++		goto out;
++	lower = 0;
++	upper = (st.st_size - start) / (line_len + 1);
++
++	while (lower != upper) {
++		off_t cur;
++		char buf[32];
++		int cmp;
++
++		cur = lower + (upper - lower) / 2;
++
++		/* Read this line and compare to digest; this is
++		 * overflow-safe since cur < max(off_t) / (line_len + 1) */
++		if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
++			break;
++		if (atomicio(read, fd, buf, line_len) != line_len)
++			break;
++		cmp = memcmp(buf, dgst_packed + 12, line_len);
++		if (cmp < 0) {
++			if (cur == lower)
++				break;
++			lower = cur;
++		} else if (cmp > 0) {
++			if (cur == upper)
++				break;
++			upper = cur;
++		} else {
++			debug("Found %s in blacklist", dgst_hex);
++			ret = 1;
++			break;
++		}
++	}
++
++out:
++	if (dgst_packed)
++		xfree(dgst_packed);
++	if (dgst_hex)
++		xfree(dgst_hex);
++	if (fd >= 0)
++		close(fd);
++	xfree(blacklist_file);
++	return ret;
++}
+--- openssh-4.7p1.orig/ssh-vulnkey.c
++++ openssh-4.7p1/ssh-vulnkey.c
+@@ -0,0 +1,325 @@
++/*
++ * Copyright (c) 2008 Canonical Ltd.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list