summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in17
-rw-r--r--auth-rh-rsa.c2
-rw-r--r--auth-rsa.c2
-rw-r--r--auth.c27
-rw-r--r--auth.h2
-rw-r--r--auth2-hostbased.c2
-rw-r--r--auth2-pubkey.c5
-rw-r--r--authfile.c136
-rw-r--r--authfile.h2
-rw-r--r--debian/.git-dpm4
-rw-r--r--debian/README.compromised-keys167
-rw-r--r--debian/changelog6
-rw-r--r--debian/control4
-rw-r--r--debian/openssh-client.docs1
-rw-r--r--debian/openssh-client.install2
-rw-r--r--debian/patches/auth-log-verbosity.patch6
-rw-r--r--debian/patches/authorized-keys-man-symlink.patch6
-rw-r--r--debian/patches/consolekit.patch10
-rw-r--r--debian/patches/debian-banner.patch22
-rw-r--r--debian/patches/debian-config.patch10
-rw-r--r--debian/patches/dnssec-sshfp.patch2
-rw-r--r--debian/patches/doc-hash-tab-completion.patch4
-rw-r--r--debian/patches/doc-upstart.patch4
-rw-r--r--debian/patches/gnome-ssh-askpass2-icon.patch2
-rw-r--r--debian/patches/helpful-wait-terminate.patch2
-rw-r--r--debian/patches/keepalive-extensions.patch18
-rw-r--r--debian/patches/lintian-symlink-pickiness.patch8
-rw-r--r--debian/patches/mention-ssh-keygen-on-keychange.patch2
-rw-r--r--debian/patches/no-openssl-version-check.patch2
-rw-r--r--debian/patches/openbsd-docs.patch14
-rw-r--r--debian/patches/package-versioning.patch4
-rw-r--r--debian/patches/quieter-signals.patch2
-rw-r--r--debian/patches/scp-quoting.patch2
-rw-r--r--debian/patches/series2
-rw-r--r--debian/patches/shell-path.patch2
-rw-r--r--debian/patches/sigstop.patch6
-rw-r--r--debian/patches/ssh-agent-setgid.patch2
-rw-r--r--debian/patches/ssh-argv0.patch6
-rw-r--r--debian/patches/ssh-vulnkey-compat.patch42
-rw-r--r--debian/patches/ssh-vulnkey.patch1419
-rw-r--r--debian/patches/ssh1-keepalive.patch4
-rw-r--r--debian/patches/syslog-level-silent.patch4
-rw-r--r--debian/patches/user-group-modes.patch20
-rw-r--r--pathnames.h7
-rw-r--r--readconf.c10
-rw-r--r--readconf.h1
-rw-r--r--servconf.c12
-rw-r--r--servconf.h1
-rw-r--r--ssh-add.15
-rw-r--r--ssh-add.c10
-rw-r--r--ssh-keygen.11
-rw-r--r--ssh-vulnkey.1242
-rw-r--r--ssh-vulnkey.c386
-rw-r--r--ssh.11
-rw-r--r--ssh.c18
-rw-r--r--ssh_config.517
-rw-r--r--sshconnect2.c4
-rw-r--r--sshd.81
-rw-r--r--sshd.c5
-rw-r--r--sshd_config.514
60 files changed, 152 insertions, 2589 deletions
diff --git a/Makefile.in b/Makefile.in
index 839abbd48..095f4ff32 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -26,7 +26,6 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
26SFTP_SERVER=$(libexecdir)/sftp-server 26SFTP_SERVER=$(libexecdir)/sftp-server
27SSH_KEYSIGN=$(libexecdir)/ssh-keysign 27SSH_KEYSIGN=$(libexecdir)/ssh-keysign
28SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper 28SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
29SSH_DATADIR=$(datadir)/ssh
30PRIVSEP_PATH=@PRIVSEP_PATH@ 29PRIVSEP_PATH=@PRIVSEP_PATH@
31SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ 30SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
32STRIP_OPT=@STRIP_OPT@ 31STRIP_OPT=@STRIP_OPT@
@@ -38,8 +37,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \
38 -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ 37 -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
39 -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ 38 -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \
40 -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ 39 -D_PATH_SSH_PIDDIR=\"$(piddir)\" \
41 -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ 40 -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
42 -D_PATH_SSH_DATADIR=\"$(SSH_DATADIR)\"
43 41
44CC=@CC@ 42CC=@CC@
45LD=@LD@ 43LD=@LD@
@@ -63,7 +61,7 @@ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
63EXEEXT=@EXEEXT@ 61EXEEXT=@EXEEXT@
64MANFMT=@MANFMT@ 62MANFMT=@MANFMT@
65 63
66TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-vulnkey$(EXEEXT) 64TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
67 65
68LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ 66LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
69 canohost.o channels.o cipher.o cipher-aes.o \ 67 canohost.o channels.o cipher.o cipher-aes.o \
@@ -99,8 +97,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
99 sandbox-seccomp-filter.o \ 97 sandbox-seccomp-filter.o \
100 consolekit.o 98 consolekit.o
101 99
102MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out 100MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
103MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5 101MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
104MANTYPE = @MANTYPE@ 102MANTYPE = @MANTYPE@
105 103
106CONFIGFILES=sshd_config.out ssh_config.out moduli.out 104CONFIGFILES=sshd_config.out ssh_config.out moduli.out
@@ -179,9 +177,6 @@ sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o s
179sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o 177sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
180 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) 178 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
181 179
182ssh-vulnkey$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-vulnkey.o
183 $(LD) -o $@ ssh-vulnkey.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
184
185# test driver for the loginrec code - not built by default 180# test driver for the loginrec code - not built by default
186logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o 181logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
187 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) 182 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
@@ -278,7 +273,6 @@ install-files:
278 $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) 273 $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
279 $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT) 274 $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
280 $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) 275 $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
281 $(INSTALL) -m 0755 $(STRIP_OPT) ssh-vulnkey$(EXEEXT) $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
282 $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 276 $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
283 $(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 277 $(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
284 $(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 278 $(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
@@ -294,7 +288,6 @@ install-files:
294 $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 288 $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
295 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 289 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
296 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 290 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
297 $(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
298 -rm -f $(DESTDIR)$(bindir)/slogin 291 -rm -f $(DESTDIR)$(bindir)/slogin
299 ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin 292 ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
300 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 293 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
@@ -376,7 +369,6 @@ uninstall:
376 -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) 369 -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
377 -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) 370 -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
378 -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) 371 -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
379 -rm -f $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
380 -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT) 372 -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
381 -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) 373 -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
382 -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) 374 -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
@@ -389,7 +381,6 @@ uninstall:
389 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 381 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
390 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1 382 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
391 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1 383 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
392 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
393 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 384 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
394 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 385 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
395 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 386 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index 891ec3297..b21a0f4a2 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -44,7 +44,7 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
44{ 44{
45 HostStatus host_status; 45 HostStatus host_status;
46 46
47 if (auth_key_is_revoked(client_host_key, 0)) 47 if (auth_key_is_revoked(client_host_key))
48 return 0; 48 return 0;
49 49
50 /* Check if we would accept it using rhosts authentication. */ 50 /* Check if we would accept it using rhosts authentication. */
diff --git a/auth-rsa.c b/auth-rsa.c
index 9b139c928..4624c1597 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -239,7 +239,7 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
239 free(fp); 239 free(fp);
240 240
241 /* Never accept a revoked key */ 241 /* Never accept a revoked key */
242 if (auth_key_is_revoked(key, 0)) 242 if (auth_key_is_revoked(key))
243 break; 243 break;
244 244
245 /* We have found the desired key. */ 245 /* We have found the desired key. */
diff --git a/auth.c b/auth.c
index 7f6c6c8ad..0c45f0954 100644
--- a/auth.c
+++ b/auth.c
@@ -59,7 +59,6 @@
59#include "servconf.h" 59#include "servconf.h"
60#include "key.h" 60#include "key.h"
61#include "hostfile.h" 61#include "hostfile.h"
62#include "authfile.h"
63#include "auth.h" 62#include "auth.h"
64#include "auth-options.h" 63#include "auth-options.h"
65#include "canohost.h" 64#include "canohost.h"
@@ -655,34 +654,10 @@ getpwnamallow(const char *user)
655 654
656/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ 655/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
657int 656int
658auth_key_is_revoked(Key *key, int hostkey) 657auth_key_is_revoked(Key *key)
659{ 658{
660 char *key_fp; 659 char *key_fp;
661 660
662 if (blacklisted_key(key, &key_fp) == 1) {
663 if (options.permit_blacklisted_keys) {
664 if (hostkey)
665 error("Host key %s blacklisted (see "
666 "ssh-vulnkey(1)); continuing anyway",
667 key_fp);
668 else
669 logit("Public key %s from %s blacklisted (see "
670 "ssh-vulnkey(1)); continuing anyway",
671 key_fp, get_remote_ipaddr());
672 free(key_fp);
673 } else {
674 if (hostkey)
675 error("Host key %s blacklisted (see "
676 "ssh-vulnkey(1))", key_fp);
677 else
678 logit("Public key %s from %s blacklisted (see "
679 "ssh-vulnkey(1))",
680 key_fp, get_remote_ipaddr());
681 free(key_fp);
682 return 1;
683 }
684 }
685
686 if (options.revoked_keys_file == NULL) 661 if (options.revoked_keys_file == NULL)
687 return 0; 662 return 0;
688 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) { 663 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
diff --git a/auth.h b/auth.h
index ec95460cf..5b6824f71 100644
--- a/auth.h
+++ b/auth.h
@@ -191,7 +191,7 @@ char *authorized_principals_file(struct passwd *);
191 191
192FILE *auth_openkeyfile(const char *, struct passwd *, int); 192FILE *auth_openkeyfile(const char *, struct passwd *, int);
193FILE *auth_openprincipals(const char *, struct passwd *, int); 193FILE *auth_openprincipals(const char *, struct passwd *, int);
194int auth_key_is_revoked(Key *, int); 194int auth_key_is_revoked(Key *);
195 195
196HostStatus 196HostStatus
197check_key_in_hostfiles(struct passwd *, Key *, const char *, 197check_key_in_hostfiles(struct passwd *, Key *, const char *,
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 3a17f1bf2..a344dcc1f 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -150,7 +150,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
150 int len; 150 int len;
151 char *fp; 151 char *fp;
152 152
153 if (auth_key_is_revoked(key, 0)) 153 if (auth_key_is_revoked(key))
154 return 0; 154 return 0;
155 155
156 resolvedname = get_canonical_hostname(options.use_dns); 156 resolvedname = get_canonical_hostname(options.use_dns);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 7c0ceee55..4d87f4867 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -650,10 +650,9 @@ user_key_allowed(struct passwd *pw, Key *key)
650 u_int success, i; 650 u_int success, i;
651 char *file; 651 char *file;
652 652
653 if (auth_key_is_revoked(key, 0)) 653 if (auth_key_is_revoked(key))
654 return 0; 654 return 0;
655 if (key_is_cert(key) && 655 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
656 auth_key_is_revoked(key->cert->signature_key, 0))
657 return 0; 656 return 0;
658 657
659 success = user_cert_trusted_ca(pw, key); 658 success = user_cert_trusted_ca(pw, key);
diff --git a/authfile.c b/authfile.c
index 983359157..63ae16bbd 100644
--- a/authfile.c
+++ b/authfile.c
@@ -68,7 +68,6 @@
68#include "rsa.h" 68#include "rsa.h"
69#include "misc.h" 69#include "misc.h"
70#include "atomicio.h" 70#include "atomicio.h"
71#include "pathnames.h"
72 71
73#define MAX_KEY_FILE_SIZE (1024 * 1024) 72#define MAX_KEY_FILE_SIZE (1024 * 1024)
74 73
@@ -945,138 +944,3 @@ key_in_file(Key *key, const char *filename, int strict_type)
945 return ret; 944 return ret;
946} 945}
947 946
948/* Scan a blacklist of known-vulnerable keys in blacklist_file. */
949static int
950blacklisted_key_in_file(Key *key, const char *blacklist_file, char **fp)
951{
952 int fd = -1;
953 char *dgst_hex = NULL;
954 char *dgst_packed = NULL, *p;
955 int i;
956 size_t line_len;
957 struct stat st;
958 char buf[256];
959 off_t start, lower, upper;
960 int ret = 0;
961
962 debug("Checking blacklist file %s", blacklist_file);
963 fd = open(blacklist_file, O_RDONLY);
964 if (fd < 0) {
965 ret = -1;
966 goto out;
967 }
968
969 dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
970 /* Remove all colons */
971 dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
972 for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
973 if (dgst_hex[i] != ':')
974 *p++ = dgst_hex[i];
975 /* Only compare least-significant 80 bits (to keep the blacklist
976 * size down)
977 */
978 line_len = strlen(dgst_packed + 12);
979 if (line_len > 32)
980 goto out;
981
982 /* Skip leading comments */
983 start = 0;
984 for (;;) {
985 ssize_t r;
986 char *newline;
987
988 r = atomicio(read, fd, buf, sizeof(buf));
989 if (r <= 0)
990 goto out;
991 if (buf[0] != '#')
992 break;
993
994 newline = memchr(buf, '\n', sizeof(buf));
995 if (!newline)
996 goto out;
997 start += newline + 1 - buf;
998 if (lseek(fd, start, SEEK_SET) < 0)
999 goto out;
1000 }
1001
1002 /* Initialise binary search record numbers */
1003 if (fstat(fd, &st) < 0)
1004 goto out;
1005 lower = 0;
1006 upper = (st.st_size - start) / (line_len + 1);
1007
1008 while (lower != upper) {
1009 off_t cur;
1010 int cmp;
1011
1012 cur = lower + (upper - lower) / 2;
1013
1014 /* Read this line and compare to digest; this is
1015 * overflow-safe since cur < max(off_t) / (line_len + 1) */
1016 if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
1017 break;
1018 if (atomicio(read, fd, buf, line_len) != line_len)
1019 break;
1020 cmp = memcmp(buf, dgst_packed + 12, line_len);
1021 if (cmp < 0) {
1022 if (cur == lower)
1023 break;
1024 lower = cur;
1025 } else if (cmp > 0) {
1026 if (cur == upper)
1027 break;
1028 upper = cur;
1029 } else {
1030 debug("Found %s in blacklist", dgst_hex);
1031 ret = 1;
1032 break;
1033 }
1034 }
1035
1036out:
1037 free(dgst_packed);
1038 if (ret != 1 && dgst_hex) {
1039 free(dgst_hex);
1040 dgst_hex = NULL;
1041 }
1042 if (fp)
1043 *fp = dgst_hex;
1044 if (fd >= 0)
1045 close(fd);
1046 return ret;
1047}
1048
1049/*
1050 * Scan blacklists of known-vulnerable keys. If a vulnerable key is found,
1051 * its fingerprint is returned in *fp, unless fp is NULL.
1052 */
1053int
1054blacklisted_key(Key *key, char **fp)
1055{
1056 Key *public;
1057 char *blacklist_file;
1058 int ret, ret2;
1059
1060 public = key_demote(key);
1061 if (public->type == KEY_RSA1)
1062 public->type = KEY_RSA;
1063
1064 xasprintf(&blacklist_file, "%s.%s-%u",
1065 _PATH_BLACKLIST, key_type(public), key_size(public));
1066 ret = blacklisted_key_in_file(public, blacklist_file, fp);
1067 free(blacklist_file);
1068 if (ret > 0) {
1069 key_free(public);
1070 return ret;
1071 }
1072
1073 xasprintf(&blacklist_file, "%s.%s-%u",
1074 _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public));
1075 ret2 = blacklisted_key_in_file(public, blacklist_file, fp);
1076 free(blacklist_file);
1077 if (ret2 > ret)
1078 ret = ret2;
1079
1080 key_free(public);
1081 return ret;
1082}
diff --git a/authfile.h b/authfile.h
index 3f2bdcb06..78349beb5 100644
--- a/authfile.h
+++ b/authfile.h
@@ -28,6 +28,4 @@ Key *key_load_private_pem(int, int, const char *, char **);
28int key_perm_ok(int, const char *); 28int key_perm_ok(int, const char *);
29int key_in_file(Key *, const char *, int); 29int key_in_file(Key *, const char *, int);
30 30
31int blacklisted_key(Key *key, char **fp);
32
33#endif 31#endif
diff --git a/debian/.git-dpm b/debian/.git-dpm
index e19ae3f8a..ae624532a 100644
--- a/debian/.git-dpm
+++ b/debian/.git-dpm
@@ -1,6 +1,6 @@
1# see git-dpm(1) from git-dpm package 1# see git-dpm(1) from git-dpm package
2bb5616c94d6d6b97890e90dd01a7ad07c663dc0b 2b65a0ded7a8cfe7d351e28266d7851216d679e05
3bb5616c94d6d6b97890e90dd01a7ad07c663dc0b 3b65a0ded7a8cfe7d351e28266d7851216d679e05
4ee196dab7c5f97f0b80c8099343a375bead92010 4ee196dab7c5f97f0b80c8099343a375bead92010
5ee196dab7c5f97f0b80c8099343a375bead92010 5ee196dab7c5f97f0b80c8099343a375bead92010
6openssh_6.4p1.orig.tar.gz 6openssh_6.4p1.orig.tar.gz
diff --git a/debian/README.compromised-keys b/debian/README.compromised-keys
deleted file mode 100644
index 7a9cb7657..000000000
--- a/debian/README.compromised-keys
+++ /dev/null
@@ -1,167 +0,0 @@
1The following instructions relate to CVE-2008-0166. They were prepared by
2Matt Zimmerman, assisted by Colin Watson.
3
4== What Happened ==
5
6A weakness has been discovered in the random number generator used by OpenSSL
7on Debian and Ubuntu systems. As a result of this weakness, certain encryption
8keys are much more common than they should be, such that an attacker could
9guess the key through a brute-force attack given minimal knowledge of the
10system. This particularly affects the use of encryption keys in OpenSSH,
11OpenVPN and SSL certificates.
12
13This vulnerability only affects operating systems which (like Ubuntu) are based
14on Debian. However, other systems can be indirectly affected if weak keys are
15imported into them.
16
17We consider this an extremely serious vulnerability, and urge all users to act
18immediately to secure their systems.
19
20== Who is affected ==
21
22Systems which are running any of the following releases:
23
24 * Debian 4.0 (etch)
25 * Ubuntu 7.04 (Feisty)
26 * Ubuntu 7.10 (Gutsy)
27 * Ubuntu 8.04 LTS (Hardy)
28 * Ubuntu "Intrepid Ibex" (development): libssl <= 0.9.8g-8
29
30and have openssh-server installed or have been used to create an OpenSSH key or
31X.509 (SSL) certificate.
32
33All OpenSSH and X.509 keys generated on such systems must be considered
34untrustworthy, regardless of the system on which they are used, even after the
35update has been applied.
36
37This includes the automatically generated host keys used by OpenSSH, which are
38the basis for its server spoofing and man-in-the-middle protection.
39
40The specific package versions affected are:
41
42 * Debian 4.0: libssl <= 0.9.8c-4etch3
43 * Ubuntu 7.04: libssl <= 0.9.8c-4ubuntu0.2
44 * Ubuntu 7.10: libssl <= 0.9.8e-5ubuntu3.1
45 * Ubuntu 8.04: libssl <= 0.9.8g-4ubuntu3
46
47== What to do if you are affected ==
48
49OpenSSH:
50
511. Install the security updates
52
53 Once the update is applied, weak user keys will be automatically rejected
54 where possible (though they cannot be detected in all cases). If you are
55 using such keys for user authentication, they will immediately stop working
56 and will need to be replaced (see step 3).
57
58 OpenSSH host keys can be automatically regenerated when the OpenSSH security
59 update is applied. The update will prompt for confirmation before taking
60 this step.
61
622. Update OpenSSH known_hosts files
63
64 The regeneration of host keys will cause a warning to be displayed when
65 connecting to the system using SSH until the host key is updated in the
66 known_hosts file. The warning will look like this:
67
68 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
69 @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
70 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
71 IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
72 Someone could be eavesdropping on you right now (man-in-the-middle attack)!
73 It is also possible that the RSA host key has just been changed.
74
75 In this case, the host key has simply been changed, and you should update
76 the relevant known_hosts file as indicated in the error message.
77
783. Check all OpenSSH user keys
79
80 The safest course of action is to regenerate all OpenSSH user keys,
81 except where it can be established to a high degree of certainty that the
82 key was generated on an unaffected system.
83
84 Check whether your key is affected by running the ssh-vulnkey tool, included
85 in the security update. By default, ssh-vulnkey will check the standard
86 location for user keys (~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity),
87 your authorized_keys file (~/.ssh/authorized_keys and
88 ~/.ssh/authorized_keys2), and the system's host keys
89 (/etc/ssh/ssh_host_dsa_key and /etc/ssh/ssh_host_rsa_key).
90
91 To check all your own keys, assuming they are in the standard
92 locations (~/.ssh/id_rsa, ~/.ssh/id_dsa, or ~/.ssh/identity):
93
94 ssh-vulnkey
95
96 To check all keys on your system:
97
98 sudo ssh-vulnkey -a
99
100 To check a key in a non-standard location:
101
102 ssh-vulnkey /path/to/key
103
104 If ssh-vulnkey says "Unknown (no blacklist information)", then it has no
105 information about whether that key is affected. If in doubt, destroy the
106 key and generate a new one.
107
1084. Regenerate any affected user keys
109
110 OpenSSH keys used for user authentication must be manually regenerated,
111 including those which may have since been transferred to a different system
112 after being generated.
113
114 New keys can be generated using ssh-keygen, e.g.:
115
116 $ ssh-keygen
117 Generating public/private rsa key pair.
118 Enter file in which to save the key (/home/user/.ssh/id_rsa):
119 Enter passphrase (empty for no passphrase):
120 Enter same passphrase again:
121 Your identification has been saved in /home/user/.ssh/id_rsa.
122 Your public key has been saved in /home/user/.ssh/id_rsa.pub.
123 The key fingerprint is:
124 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 user@host
125
1265. Update authorized_keys files (if necessary)
127
128 Once the user keys have been regenerated, the relevant public keys must
129 be propagated to any authorized_keys files on remote systems. Be sure to
130 delete the affected key.
131
132OpenSSL:
133
1341. Install the security update
135
1362. Create new certificates to replace any server or client certificates in use
137 on the system
138
1393. If certificates have been generated for use on other systems, they must be
140 found and replaced as well.
141
142== Removing openssh-blacklist ==
143
144For the moment, the openssh-server package depends on openssh-blacklist, in
145order that the blacklist is deployed to the maximum possible number of
146systems to reduce the potential spread of worms exploiting this
147vulnerability. We acknowledge that this may be inconvenient for some small
148systems, but nevertheless feel that this was the best course of action.
149
150If you absolutely need to remove the blacklist from your system, then you
151can run the following commands to substitute a fake package for
152openssh-blacklist:
153
154 sudo apt-get install equivs
155 equivs-control openssh-blacklist.ctl
156 sed -i 's/^Package:.*/Package: openssh-blacklist/' openssh-blacklist.ctl
157 sed -i 's/^# Version:.*/Version: 9:1.0/' openssh-blacklist.ctl
158 equivs-build openssh-blacklist.ctl
159 sudo dpkg -i openssh-blacklist_1.0_all.deb
160
161Be warned: this circumvents a security measure for the sake of disk space.
162You should only do this if you have no other option, and if you are certain
163that no compromised keys will ever be generated on or copied onto this
164system.
165
166Once a sufficient amount of time and number of releases have passed, the
167openssh-blacklist package will be phased out.
diff --git a/debian/changelog b/debian/changelog
index 188f17070..afed2d957 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,12 @@ openssh (1:6.4p1-3) UNRELEASED; urgency=medium
3 * Switch to git; adjust Vcs-* fields. 3 * Switch to git; adjust Vcs-* fields.
4 * Convert to git-dpm, and drop source package documentation associated 4 * Convert to git-dpm, and drop source package documentation associated
5 with the old bzr/quilt patch handling workflow. 5 with the old bzr/quilt patch handling workflow.
6 * Drop ssh-vulnkey and the associated ssh/ssh-add/sshd integration code,
7 leaving only basic configuration file compatibility, since it has been
8 nearly six years since the original vulnerability and this code is not
9 likely to be of much value any more. See
10 https://lists.debian.org/debian-devel/2013/09/msg00240.html for my full
11 reasoning.
6 12
7 -- Colin Watson <cjwatson@debian.org> Sun, 09 Feb 2014 15:52:14 +0000 13 -- Colin Watson <cjwatson@debian.org> Sun, 09 Feb 2014 15:52:14 +0000
8 14
diff --git a/debian/control b/debian/control
index 308b7f4ef..8b3679570 100644
--- a/debian/control
+++ b/debian/control
@@ -15,7 +15,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, adduser (>= 3.10), dpkg (>= 1.7.0),
15Recommends: xauth 15Recommends: xauth
16Conflicts: ssh (<< 1:3.8.1p1-9), sftp, rsh-client (<<0.16.1-1), ssh-krb5 (<< 1:4.3p2-7) 16Conflicts: ssh (<< 1:3.8.1p1-9), sftp, rsh-client (<<0.16.1-1), ssh-krb5 (<< 1:4.3p2-7)
17Replaces: ssh, ssh-krb5 17Replaces: ssh, ssh-krb5
18Suggests: ssh-askpass, libpam-ssh, keychain, monkeysphere, openssh-blacklist, openssh-blacklist-extra 18Suggests: ssh-askpass, libpam-ssh, keychain, monkeysphere
19Provides: rsh-client, ssh-client 19Provides: rsh-client, ssh-client
20Multi-Arch: foreign 20Multi-Arch: foreign
21Description: secure shell (SSH) client, for secure access to remote machines 21Description: secure shell (SSH) client, for secure access to remote machines
@@ -49,7 +49,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime (>= 0.76-14), libpam
49Recommends: xauth, ncurses-term, ${openssh-server:Recommends} 49Recommends: xauth, ncurses-term, ${openssh-server:Recommends}
50Conflicts: ssh (<< 1:3.8.1p1-9), ssh-nonfree (<<2), ssh-socks, ssh2, sftp, rsh-client (<<0.16.1-1), ssh-krb5 (<< 1:4.3p2-7) 50Conflicts: ssh (<< 1:3.8.1p1-9), ssh-nonfree (<<2), ssh-socks, ssh2, sftp, rsh-client (<<0.16.1-1), ssh-krb5 (<< 1:4.3p2-7)
51Replaces: ssh, openssh-client (<< 1:3.8.1p1-11), ssh-krb5 51Replaces: ssh, openssh-client (<< 1:3.8.1p1-11), ssh-krb5
52Suggests: ssh-askpass, rssh, molly-guard, ufw, monkeysphere, openssh-blacklist, openssh-blacklist-extra 52Suggests: ssh-askpass, rssh, molly-guard, ufw, monkeysphere
53Provides: ssh-server 53Provides: ssh-server
54Multi-Arch: foreign 54Multi-Arch: foreign
55Description: secure shell (SSH) server, for secure access from remote machines 55Description: secure shell (SSH) server, for secure access from remote machines
diff --git a/debian/openssh-client.docs b/debian/openssh-client.docs
index 00fd691c4..d80ec1262 100644
--- a/debian/openssh-client.docs
+++ b/debian/openssh-client.docs
@@ -4,4 +4,3 @@ README
4README.dns 4README.dns
5README.tun 5README.tun
6debian/faq.html 6debian/faq.html
7debian/README.compromised-keys
diff --git a/debian/openssh-client.install b/debian/openssh-client.install
index fd9e8feab..6a8060000 100644
--- a/debian/openssh-client.install
+++ b/debian/openssh-client.install
@@ -8,7 +8,6 @@ usr/bin/ssh-add
8usr/bin/ssh-agent 8usr/bin/ssh-agent
9usr/bin/ssh-keygen 9usr/bin/ssh-keygen
10usr/bin/ssh-keyscan 10usr/bin/ssh-keyscan
11usr/bin/ssh-vulnkey
12usr/lib/openssh/ssh-keysign 11usr/lib/openssh/ssh-keysign
13usr/lib/openssh/ssh-pkcs11-helper 12usr/lib/openssh/ssh-pkcs11-helper
14usr/share/man/man1/scp.1 13usr/share/man/man1/scp.1
@@ -18,7 +17,6 @@ usr/share/man/man1/ssh-add.1
18usr/share/man/man1/ssh-agent.1 17usr/share/man/man1/ssh-agent.1
19usr/share/man/man1/ssh-keygen.1 18usr/share/man/man1/ssh-keygen.1
20usr/share/man/man1/ssh-keyscan.1 19usr/share/man/man1/ssh-keyscan.1
21usr/share/man/man1/ssh-vulnkey.1
22usr/share/man/man1/ssh.1 20usr/share/man/man1/ssh.1
23usr/share/man/man5/moduli.5 21usr/share/man/man5/moduli.5
24usr/share/man/man5/ssh_config.5 22usr/share/man/man5/ssh_config.5
diff --git a/debian/patches/auth-log-verbosity.patch b/debian/patches/auth-log-verbosity.patch
index 5d98b81a2..f1db2dbdf 100644
--- a/debian/patches/auth-log-verbosity.patch
+++ b/debian/patches/auth-log-verbosity.patch
@@ -1,4 +1,4 @@
1From ec5991d73abdc0b3c43ea9f8a0e99da045e7beb1 Mon Sep 17 00:00:00 2001 1From 490aadd108dc4bf7f4b5084e3336d88ec23f6b19 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:02 +0000 3Date: Sun, 9 Feb 2014 16:10:02 +0000
4Subject: Quieten logs when multiple from= restrictions are used 4Subject: Quieten logs when multiple from= restrictions are used
@@ -91,7 +91,7 @@ index 7455c94..a3f0a02 100644
91 void auth_clear_options(void); 91 void auth_clear_options(void);
92 int auth_cert_options(Key *, struct passwd *); 92 int auth_cert_options(Key *, struct passwd *);
93diff --git a/auth-rsa.c b/auth-rsa.c 93diff --git a/auth-rsa.c b/auth-rsa.c
94index 6ed152c..9b139c9 100644 94index 545aa49..4624c15 100644
95--- a/auth-rsa.c 95--- a/auth-rsa.c
96+++ b/auth-rsa.c 96+++ b/auth-rsa.c
97@@ -174,6 +174,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, 97@@ -174,6 +174,8 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
@@ -104,7 +104,7 @@ index 6ed152c..9b139c9 100644
104 * Go though the accepted keys, looking for the current key. If 104 * Go though the accepted keys, looking for the current key. If
105 * found, perform a challenge-response dialog to verify that the 105 * found, perform a challenge-response dialog to verify that the
106diff --git a/auth2-pubkey.c b/auth2-pubkey.c 106diff --git a/auth2-pubkey.c b/auth2-pubkey.c
107index 12eb8a6..7c0ceee 100644 107index 2b3ecb1..4d87f48 100644
108--- a/auth2-pubkey.c 108--- a/auth2-pubkey.c
109+++ b/auth2-pubkey.c 109+++ b/auth2-pubkey.c
110@@ -257,6 +257,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert) 110@@ -257,6 +257,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
diff --git a/debian/patches/authorized-keys-man-symlink.patch b/debian/patches/authorized-keys-man-symlink.patch
index 751ba841c..f59df61bd 100644
--- a/debian/patches/authorized-keys-man-symlink.patch
+++ b/debian/patches/authorized-keys-man-symlink.patch
@@ -1,4 +1,4 @@
1From 6342b4c70310da7f73e1d54ddae0edde990d95d8 Mon Sep 17 00:00:00 2001 1From d5b4a3617c50cbe9526582979797248af5cbd9d5 Mon Sep 17 00:00:00 2001
2From: Tomas Pospisek <tpo_deb@sourcepole.ch> 2From: Tomas Pospisek <tpo_deb@sourcepole.ch>
3Date: Sun, 9 Feb 2014 16:10:07 +0000 3Date: Sun, 9 Feb 2014 16:10:07 +0000
4Subject: Install authorized_keys(5) as a symlink to sshd(8) 4Subject: Install authorized_keys(5) as a symlink to sshd(8)
@@ -13,10 +13,10 @@ Patch-Name: authorized-keys-man-symlink.patch
13 1 file changed, 1 insertion(+) 13 1 file changed, 1 insertion(+)
14 14
15diff --git a/Makefile.in b/Makefile.in 15diff --git a/Makefile.in b/Makefile.in
16index ca6eee5..7cd3a08 100644 16index b2dbead..7849979 100644
17--- a/Makefile.in 17--- a/Makefile.in
18+++ b/Makefile.in 18+++ b/Makefile.in
19@@ -289,6 +289,7 @@ install-files: 19@@ -283,6 +283,7 @@ install-files:
20 $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5 20 $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
21 $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5 21 $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
22 $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 22 $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
diff --git a/debian/patches/consolekit.patch b/debian/patches/consolekit.patch
index f43e78500..b97bf0cd5 100644
--- a/debian/patches/consolekit.patch
+++ b/debian/patches/consolekit.patch
@@ -1,4 +1,4 @@
1From cfae2bfa1e95cbb6c7a9799f13b82e8e804ca869 Mon Sep 17 00:00:00 2001 1From 05609b1cb381eafb999214bf4a95138e63abdbf2 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com> 2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:57 +0000 3Date: Sun, 9 Feb 2014 16:09:57 +0000
4Subject: Add support for registering ConsoleKit sessions on login 4Subject: Add support for registering ConsoleKit sessions on login
@@ -24,10 +24,10 @@ Patch-Name: consolekit.patch
24 create mode 100644 consolekit.h 24 create mode 100644 consolekit.h
25 25
26diff --git a/Makefile.in b/Makefile.in 26diff --git a/Makefile.in b/Makefile.in
27index b8f5099..ca6eee5 100644 27index f979926..b2dbead 100644
28--- a/Makefile.in 28--- a/Makefile.in
29+++ b/Makefile.in 29+++ b/Makefile.in
30@@ -96,7 +96,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ 30@@ -94,7 +94,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
31 sftp-server.o sftp-common.o \ 31 sftp-server.o sftp-common.o \
32 roaming_common.o roaming_serv.o \ 32 roaming_common.o roaming_serv.o \
33 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ 33 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
@@ -35,8 +35,8 @@ index b8f5099..ca6eee5 100644
35+ sandbox-seccomp-filter.o \ 35+ sandbox-seccomp-filter.o \
36+ consolekit.o 36+ consolekit.o
37 37
38 MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out 38 MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
39 MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5 39 MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
40diff --git a/configure b/configure 40diff --git a/configure b/configure
41index ceb1b5d..78bbcd0 100755 41index ceb1b5d..78bbcd0 100755
42--- a/configure 42--- a/configure
diff --git a/debian/patches/debian-banner.patch b/debian/patches/debian-banner.patch
index d02e8ffcb..8edc27f70 100644
--- a/debian/patches/debian-banner.patch
+++ b/debian/patches/debian-banner.patch
@@ -1,4 +1,4 @@
1From 8a75df792931443e868e574408ed1666208a28c2 Mon Sep 17 00:00:00 2001 1From e1e1e23ca98c59a031217da0ea50b70de5427683 Mon Sep 17 00:00:00 2001
2From: Kees Cook <kees@debian.org> 2From: Kees Cook <kees@debian.org>
3Date: Sun, 9 Feb 2014 16:10:06 +0000 3Date: Sun, 9 Feb 2014 16:10:06 +0000
4Subject: Add DebianBanner server configuration option 4Subject: Add DebianBanner server configuration option
@@ -19,10 +19,10 @@ Patch-Name: debian-banner.patch
19 4 files changed, 18 insertions(+), 1 deletion(-) 19 4 files changed, 18 insertions(+), 1 deletion(-)
20 20
21diff --git a/servconf.c b/servconf.c 21diff --git a/servconf.c b/servconf.c
22index 9155a8b..a2928ff 100644 22index dcb8caf..802db1d 100644
23--- a/servconf.c 23--- a/servconf.c
24+++ b/servconf.c 24+++ b/servconf.c
25@@ -157,6 +157,7 @@ initialize_server_options(ServerOptions *options) 25@@ -156,6 +156,7 @@ initialize_server_options(ServerOptions *options)
26 options->ip_qos_interactive = -1; 26 options->ip_qos_interactive = -1;
27 options->ip_qos_bulk = -1; 27 options->ip_qos_bulk = -1;
28 options->version_addendum = NULL; 28 options->version_addendum = NULL;
@@ -30,7 +30,7 @@ index 9155a8b..a2928ff 100644
30 } 30 }
31 31
32 void 32 void
33@@ -310,6 +311,8 @@ fill_default_server_options(ServerOptions *options) 33@@ -307,6 +308,8 @@ fill_default_server_options(ServerOptions *options)
34 options->ip_qos_bulk = IPTOS_THROUGHPUT; 34 options->ip_qos_bulk = IPTOS_THROUGHPUT;
35 if (options->version_addendum == NULL) 35 if (options->version_addendum == NULL)
36 options->version_addendum = xstrdup(""); 36 options->version_addendum = xstrdup("");
@@ -39,7 +39,7 @@ index 9155a8b..a2928ff 100644
39 /* Turn privilege separation on by default */ 39 /* Turn privilege separation on by default */
40 if (use_privsep == -1) 40 if (use_privsep == -1)
41 use_privsep = PRIVSEP_NOSANDBOX; 41 use_privsep = PRIVSEP_NOSANDBOX;
42@@ -360,6 +363,7 @@ typedef enum { 42@@ -357,6 +360,7 @@ typedef enum {
43 sKexAlgorithms, sIPQoS, sVersionAddendum, 43 sKexAlgorithms, sIPQoS, sVersionAddendum,
44 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, 44 sAuthorizedKeysCommand, sAuthorizedKeysCommandUser,
45 sAuthenticationMethods, sHostKeyAgent, 45 sAuthenticationMethods, sHostKeyAgent,
@@ -47,7 +47,7 @@ index 9155a8b..a2928ff 100644
47 sDeprecated, sUnsupported 47 sDeprecated, sUnsupported
48 } ServerOpCodes; 48 } ServerOpCodes;
49 49
50@@ -501,6 +505,7 @@ static struct { 50@@ -498,6 +502,7 @@ static struct {
51 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL }, 51 { "authorizedkeyscommanduser", sAuthorizedKeysCommandUser, SSHCFG_ALL },
52 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, 52 { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
53 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL }, 53 { "authenticationmethods", sAuthenticationMethods, SSHCFG_ALL },
@@ -55,7 +55,7 @@ index 9155a8b..a2928ff 100644
55 { NULL, sBadOption, 0 } 55 { NULL, sBadOption, 0 }
56 }; 56 };
57 57
58@@ -1648,6 +1653,10 @@ process_server_config_line(ServerOptions *options, char *line, 58@@ -1641,6 +1646,10 @@ process_server_config_line(ServerOptions *options, char *line,
59 } 59 }
60 return 0; 60 return 0;
61 61
@@ -67,10 +67,10 @@ index 9155a8b..a2928ff 100644
67 logit("%s line %d: Deprecated option %s", 67 logit("%s line %d: Deprecated option %s",
68 filename, linenum, arg); 68 filename, linenum, arg);
69diff --git a/servconf.h b/servconf.h 69diff --git a/servconf.h b/servconf.h
70index f655c5b..fd72ce2 100644 70index ab6e346..1891a95 100644
71--- a/servconf.h 71--- a/servconf.h
72+++ b/servconf.h 72+++ b/servconf.h
73@@ -188,6 +188,8 @@ typedef struct { 73@@ -187,6 +187,8 @@ typedef struct {
74 74
75 u_int num_auth_methods; 75 u_int num_auth_methods;
76 char *auth_methods[MAX_AUTH_METHODS]; 76 char *auth_methods[MAX_AUTH_METHODS];
@@ -80,7 +80,7 @@ index f655c5b..fd72ce2 100644
80 80
81 /* Information about the incoming connection as used by Match */ 81 /* Information about the incoming connection as used by Match */
82diff --git a/sshd.c b/sshd.c 82diff --git a/sshd.c b/sshd.c
83index 7efa7ef..6b988fe 100644 83index 46ec1a7..63b9357 100644
84--- a/sshd.c 84--- a/sshd.c
85+++ b/sshd.c 85+++ b/sshd.c
86@@ -440,7 +440,8 @@ sshd_exchange_identification(int sock_in, int sock_out) 86@@ -440,7 +440,8 @@ sshd_exchange_identification(int sock_in, int sock_out)
@@ -94,7 +94,7 @@ index 7efa7ef..6b988fe 100644
94 options.version_addendum, newline); 94 options.version_addendum, newline);
95 95
96diff --git a/sshd_config.5 b/sshd_config.5 96diff --git a/sshd_config.5 b/sshd_config.5
97index 510cc7c..eaf8d01 100644 97index e29604a..50eec53 100644
98--- a/sshd_config.5 98--- a/sshd_config.5
99+++ b/sshd_config.5 99+++ b/sshd_config.5
100@@ -404,6 +404,11 @@ or 100@@ -404,6 +404,11 @@ or
diff --git a/debian/patches/debian-config.patch b/debian/patches/debian-config.patch
index e706b4a02..3c5af97c3 100644
--- a/debian/patches/debian-config.patch
+++ b/debian/patches/debian-config.patch
@@ -1,4 +1,4 @@
1From bb5616c94d6d6b97890e90dd01a7ad07c663dc0b Mon Sep 17 00:00:00 2001 1From b65a0ded7a8cfe7d351e28266d7851216d679e05 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:18 +0000 3Date: Sun, 9 Feb 2014 16:10:18 +0000
4Subject: Various Debian-specific configuration changes 4Subject: Various Debian-specific configuration changes
@@ -34,10 +34,10 @@ Patch-Name: debian-config.patch
34 5 files changed, 53 insertions(+), 3 deletions(-) 34 5 files changed, 53 insertions(+), 3 deletions(-)
35 35
36diff --git a/readconf.c b/readconf.c 36diff --git a/readconf.c b/readconf.c
37index 389de7d..2778176 100644 37index c741934..e1e82c5 100644
38--- a/readconf.c 38--- a/readconf.c
39+++ b/readconf.c 39+++ b/readconf.c
40@@ -1298,7 +1298,7 @@ fill_default_options(Options * options) 40@@ -1292,7 +1292,7 @@ fill_default_options(Options * options)
41 if (options->forward_x11 == -1) 41 if (options->forward_x11 == -1)
42 options->forward_x11 = 0; 42 options->forward_x11 = 0;
43 if (options->forward_x11_trusted == -1) 43 if (options->forward_x11_trusted == -1)
@@ -71,7 +71,7 @@ index 3234321..064b593 100644
71+ GSSAPIAuthentication yes 71+ GSSAPIAuthentication yes
72+ GSSAPIDelegateCredentials no 72+ GSSAPIDelegateCredentials no
73diff --git a/ssh_config.5 b/ssh_config.5 73diff --git a/ssh_config.5 b/ssh_config.5
74index 5bca932..127540a 100644 74index 7b05e5f..01e7b6f 100644
75--- a/ssh_config.5 75--- a/ssh_config.5
76+++ b/ssh_config.5 76+++ b/ssh_config.5
77@@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more 77@@ -71,6 +71,22 @@ Since the first obtained value for each parameter is used, more
@@ -120,7 +120,7 @@ index 9450141..9cfe28d 100644
120 #StrictModes yes 120 #StrictModes yes
121 #MaxAuthTries 6 121 #MaxAuthTries 6
122diff --git a/sshd_config.5 b/sshd_config.5 122diff --git a/sshd_config.5 b/sshd_config.5
123index ec4851a..faf93fc 100644 123index 04b5f1a..ca4cb19 100644
124--- a/sshd_config.5 124--- a/sshd_config.5
125+++ b/sshd_config.5 125+++ b/sshd_config.5
126@@ -57,6 +57,33 @@ Arguments may optionally be enclosed in double quotes 126@@ -57,6 +57,33 @@ Arguments may optionally be enclosed in double quotes
diff --git a/debian/patches/dnssec-sshfp.patch b/debian/patches/dnssec-sshfp.patch
index 3cb291e97..4349df707 100644
--- a/debian/patches/dnssec-sshfp.patch
+++ b/debian/patches/dnssec-sshfp.patch
@@ -1,4 +1,4 @@
1From 145099bdca1b959e2ef3555cd6ce0bc44fb69ce8 Mon Sep 17 00:00:00 2001 1From d77a569da1afcb73c6ddfc934092461eeb4edb53 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:01 +0000 3Date: Sun, 9 Feb 2014 16:10:01 +0000
4Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf 4Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf
diff --git a/debian/patches/doc-hash-tab-completion.patch b/debian/patches/doc-hash-tab-completion.patch
index 4f9de88ec..a6408c21f 100644
--- a/debian/patches/doc-hash-tab-completion.patch
+++ b/debian/patches/doc-hash-tab-completion.patch
@@ -1,4 +1,4 @@
1From cee45b00a94730c9a49a52a967ec08b9c29b9ca2 Mon Sep 17 00:00:00 2001 1From 6a3efad36a54be8fa4de750cd7a555fe925f21cc Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:11 +0000 3Date: Sun, 9 Feb 2014 16:10:11 +0000
4Subject: Document that HashKnownHosts may break tab-completion 4Subject: Document that HashKnownHosts may break tab-completion
@@ -13,7 +13,7 @@ Patch-Name: doc-hash-tab-completion.patch
13 1 file changed, 3 insertions(+) 13 1 file changed, 3 insertions(+)
14 14
15diff --git a/ssh_config.5 b/ssh_config.5 15diff --git a/ssh_config.5 b/ssh_config.5
16index 1497cfc..5bca932 100644 16index a1e18d2..7b05e5f 100644
17--- a/ssh_config.5 17--- a/ssh_config.5
18+++ b/ssh_config.5 18+++ b/ssh_config.5
19@@ -587,6 +587,9 @@ Note that existing names and addresses in known hosts files 19@@ -587,6 +587,9 @@ Note that existing names and addresses in known hosts files
diff --git a/debian/patches/doc-upstart.patch b/debian/patches/doc-upstart.patch
index cb24998a2..0fa00a883 100644
--- a/debian/patches/doc-upstart.patch
+++ b/debian/patches/doc-upstart.patch
@@ -1,4 +1,4 @@
1From c1e7260fe4ed36dddc317655a69a7d4a69b3170a Mon Sep 17 00:00:00 2001 1From 5093448a615dcbab13bbbd3765ac353b827f21aa Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com> 2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:12 +0000 3Date: Sun, 9 Feb 2014 16:10:12 +0000
4Subject: Refer to ssh's Upstart job as well as its init script 4Subject: Refer to ssh's Upstart job as well as its init script
@@ -12,7 +12,7 @@ Patch-Name: doc-upstart.patch
12 1 file changed, 4 insertions(+), 1 deletion(-) 12 1 file changed, 4 insertions(+), 1 deletion(-)
13 13
14diff --git a/sshd.8 b/sshd.8 14diff --git a/sshd.8 b/sshd.8
15index 6bdd219..b91f08c 100644 15index 95c1845..8e4017b 100644
16--- a/sshd.8 16--- a/sshd.8
17+++ b/sshd.8 17+++ b/sshd.8
18@@ -70,7 +70,10 @@ over an insecure network. 18@@ -70,7 +70,10 @@ over an insecure network.
diff --git a/debian/patches/gnome-ssh-askpass2-icon.patch b/debian/patches/gnome-ssh-askpass2-icon.patch
index 58966dd74..1cbb93436 100644
--- a/debian/patches/gnome-ssh-askpass2-icon.patch
+++ b/debian/patches/gnome-ssh-askpass2-icon.patch
@@ -1,4 +1,4 @@
1From 52e810085e196c457dfda9cad08ce76191d11fe7 Mon Sep 17 00:00:00 2001 1From 797d4dfd543b9d3fe96db6396e902a40b868d5c0 Mon Sep 17 00:00:00 2001
2From: Vincent Untz <vuntz@ubuntu.com> 2From: Vincent Untz <vuntz@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:16 +0000 3Date: Sun, 9 Feb 2014 16:10:16 +0000
4Subject: Give the ssh-askpass-gnome window a default icon 4Subject: Give the ssh-askpass-gnome window a default icon
diff --git a/debian/patches/helpful-wait-terminate.patch b/debian/patches/helpful-wait-terminate.patch
index 66a59a053..23afe3be9 100644
--- a/debian/patches/helpful-wait-terminate.patch
+++ b/debian/patches/helpful-wait-terminate.patch
@@ -1,4 +1,4 @@
1From ea2e0af0bc3a683edb32b508c03eb793617f6f31 Mon Sep 17 00:00:00 2001 1From 84589dc348c43ec22b50ede0c2946cf6afd0980d Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <matthew@debian.org> 2From: Matthew Vernon <matthew@debian.org>
3Date: Sun, 9 Feb 2014 16:09:56 +0000 3Date: Sun, 9 Feb 2014 16:09:56 +0000
4Subject: Mention ~& when waiting for forwarded connections to terminate 4Subject: Mention ~& when waiting for forwarded connections to terminate
diff --git a/debian/patches/keepalive-extensions.patch b/debian/patches/keepalive-extensions.patch
index 61389cc44..e22410298 100644
--- a/debian/patches/keepalive-extensions.patch
+++ b/debian/patches/keepalive-extensions.patch
@@ -1,4 +1,4 @@
1From affb41e3cf23b79a3d165ae0d97689a46a965b6f Mon Sep 17 00:00:00 2001 1From bd3d91c378d549aed56246ad4535aea29db04150 Mon Sep 17 00:00:00 2001
2From: Richard Kettlewell <rjk@greenend.org.uk> 2From: Richard Kettlewell <rjk@greenend.org.uk>
3Date: Sun, 9 Feb 2014 16:09:52 +0000 3Date: Sun, 9 Feb 2014 16:09:52 +0000
4Subject: Various keepalive extensions 4Subject: Various keepalive extensions
@@ -26,10 +26,10 @@ Patch-Name: keepalive-extensions.patch
26 3 files changed, 34 insertions(+), 4 deletions(-) 26 3 files changed, 34 insertions(+), 4 deletions(-)
27 27
28diff --git a/readconf.c b/readconf.c 28diff --git a/readconf.c b/readconf.c
29index 22e5a3a..2dcbf31 100644 29index 915a0f7..dab7963 100644
30--- a/readconf.c 30--- a/readconf.c
31+++ b/readconf.c 31+++ b/readconf.c
32@@ -141,6 +141,7 @@ typedef enum { 32@@ -140,6 +140,7 @@ typedef enum {
33 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 33 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
34 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, 34 oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
35 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, 35 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown,
@@ -37,7 +37,7 @@ index 22e5a3a..2dcbf31 100644
37 oIgnoredUnknownOption, oDeprecated, oUnsupported 37 oIgnoredUnknownOption, oDeprecated, oUnsupported
38 } OpCodes; 38 } OpCodes;
39 39
40@@ -263,6 +264,8 @@ static struct { 40@@ -262,6 +263,8 @@ static struct {
41 { "ipqos", oIPQoS }, 41 { "ipqos", oIPQoS },
42 { "requesttty", oRequestTTY }, 42 { "requesttty", oRequestTTY },
43 { "ignoreunknown", oIgnoreUnknown }, 43 { "ignoreunknown", oIgnoreUnknown },
@@ -46,7 +46,7 @@ index 22e5a3a..2dcbf31 100644
46 46
47 { NULL, oBadOption } 47 { NULL, oBadOption }
48 }; 48 };
49@@ -939,6 +942,8 @@ parse_int: 49@@ -934,6 +937,8 @@ parse_int:
50 goto parse_flag; 50 goto parse_flag;
51 51
52 case oServerAliveInterval: 52 case oServerAliveInterval:
@@ -55,7 +55,7 @@ index 22e5a3a..2dcbf31 100644
55 intptr = &options->server_alive_interval; 55 intptr = &options->server_alive_interval;
56 goto parse_time; 56 goto parse_time;
57 57
58@@ -1404,8 +1409,13 @@ fill_default_options(Options * options) 58@@ -1396,8 +1401,13 @@ fill_default_options(Options * options)
59 options->rekey_interval = 0; 59 options->rekey_interval = 0;
60 if (options->verify_host_key_dns == -1) 60 if (options->verify_host_key_dns == -1)
61 options->verify_host_key_dns = 0; 61 options->verify_host_key_dns = 0;
@@ -72,7 +72,7 @@ index 22e5a3a..2dcbf31 100644
72 options->server_alive_count_max = 3; 72 options->server_alive_count_max = 3;
73 if (options->control_master == -1) 73 if (options->control_master == -1)
74diff --git a/ssh_config.5 b/ssh_config.5 74diff --git a/ssh_config.5 b/ssh_config.5
75index 89b25cd..135d833 100644 75index 1fc0a6b..6948680 100644
76--- a/ssh_config.5 76--- a/ssh_config.5
77+++ b/ssh_config.5 77+++ b/ssh_config.5
78@@ -136,8 +136,12 @@ Valid arguments are 78@@ -136,8 +136,12 @@ Valid arguments are
@@ -120,10 +120,10 @@ index 89b25cd..135d833 100644
120 connections will die if the route is down temporarily, and some people 120 connections will die if the route is down temporarily, and some people
121 find it annoying. 121 find it annoying.
122diff --git a/sshd_config.5 b/sshd_config.5 122diff --git a/sshd_config.5 b/sshd_config.5
123index 18ec81f..510cc7c 100644 123index 525d9c8..e29604a 100644
124--- a/sshd_config.5 124--- a/sshd_config.5
125+++ b/sshd_config.5 125+++ b/sshd_config.5
126@@ -1161,6 +1161,9 @@ This avoids infinitely hanging sessions. 126@@ -1147,6 +1147,9 @@ This avoids infinitely hanging sessions.
127 .Pp 127 .Pp
128 To disable TCP keepalive messages, the value should be set to 128 To disable TCP keepalive messages, the value should be set to
129 .Dq no . 129 .Dq no .
diff --git a/debian/patches/lintian-symlink-pickiness.patch b/debian/patches/lintian-symlink-pickiness.patch
index b3b549cc8..e1073e4ac 100644
--- a/debian/patches/lintian-symlink-pickiness.patch
+++ b/debian/patches/lintian-symlink-pickiness.patch
@@ -1,4 +1,4 @@
1From 6d50dc6d561af1bcf41eaf1dc69e7920abe5aa4b Mon Sep 17 00:00:00 2001 1From 9ffc99332ff1bac6be9f0af430268e7981bd3dd2 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:08 +0000 3Date: Sun, 9 Feb 2014 16:10:08 +0000
4Subject: Fix picky lintian errors about slogin symlinks 4Subject: Fix picky lintian errors about slogin symlinks
@@ -15,12 +15,12 @@ Patch-Name: lintian-symlink-pickiness.patch
15 1 file changed, 2 insertions(+), 2 deletions(-) 15 1 file changed, 2 insertions(+), 2 deletions(-)
16 16
17diff --git a/Makefile.in b/Makefile.in 17diff --git a/Makefile.in b/Makefile.in
18index 7cd3a08..839abbd 100644 18index 7849979..095f4ff 100644
19--- a/Makefile.in 19--- a/Makefile.in
20+++ b/Makefile.in 20+++ b/Makefile.in
21@@ -296,9 +296,9 @@ install-files: 21@@ -289,9 +289,9 @@ install-files:
22 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
22 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 23 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
23 $(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
24 -rm -f $(DESTDIR)$(bindir)/slogin 24 -rm -f $(DESTDIR)$(bindir)/slogin
25- ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin 25- ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
26+ ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin 26+ ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
diff --git a/debian/patches/mention-ssh-keygen-on-keychange.patch b/debian/patches/mention-ssh-keygen-on-keychange.patch
index 07682155c..08e1a2f3e 100644
--- a/debian/patches/mention-ssh-keygen-on-keychange.patch
+++ b/debian/patches/mention-ssh-keygen-on-keychange.patch
@@ -1,4 +1,4 @@
1From 7a20ce0712e7b7174a0c079e84568a9e8321c42b Mon Sep 17 00:00:00 2001 1From 6a137c3718ea1afab92b25a018e393cfede4d6a8 Mon Sep 17 00:00:00 2001
2From: Scott Moser <smoser@ubuntu.com> 2From: Scott Moser <smoser@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:10:03 +0000 3Date: Sun, 9 Feb 2014 16:10:03 +0000
4Subject: Mention ssh-keygen in ssh fingerprint changed warning 4Subject: Mention ssh-keygen in ssh fingerprint changed warning
diff --git a/debian/patches/no-openssl-version-check.patch b/debian/patches/no-openssl-version-check.patch
index f45e2b959..6e41d2ed9 100644
--- a/debian/patches/no-openssl-version-check.patch
+++ b/debian/patches/no-openssl-version-check.patch
@@ -1,4 +1,4 @@
1From bc87a22e258193138419d6615c0e92e4124dbe90 Mon Sep 17 00:00:00 2001 1From 3e3f5462b563ab0f2b4ba67590e5a5735fa17bec Mon Sep 17 00:00:00 2001
2From: Philip Hands <phil@hands.com> 2From: Philip Hands <phil@hands.com>
3Date: Sun, 9 Feb 2014 16:10:14 +0000 3Date: Sun, 9 Feb 2014 16:10:14 +0000
4Subject: Disable OpenSSL version check 4Subject: Disable OpenSSL version check
diff --git a/debian/patches/openbsd-docs.patch b/debian/patches/openbsd-docs.patch
index afc1fe306..670eea421 100644
--- a/debian/patches/openbsd-docs.patch
+++ b/debian/patches/openbsd-docs.patch
@@ -1,4 +1,4 @@
1From 98517b1b99dceff74e4a1e50d5a345f5b569ad6f Mon Sep 17 00:00:00 2001 1From d087ec8cf190df54fa8cb77c6ffd55a819dd1777 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:09 +0000 3Date: Sun, 9 Feb 2014 16:10:09 +0000
4Subject: Adjust various OpenBSD-specific references in manual pages 4Subject: Adjust various OpenBSD-specific references in manual pages
@@ -44,7 +44,7 @@ index ef0de08..149846c 100644
44 .Sh SEE ALSO 44 .Sh SEE ALSO
45 .Xr ssh-keygen 1 , 45 .Xr ssh-keygen 1 ,
46diff --git a/ssh-keygen.1 b/ssh-keygen.1 46diff --git a/ssh-keygen.1 b/ssh-keygen.1
47index 144be7d..753cc62 100644 47index 0d55854..151cab0 100644
48--- a/ssh-keygen.1 48--- a/ssh-keygen.1
49+++ b/ssh-keygen.1 49+++ b/ssh-keygen.1
50@@ -171,9 +171,7 @@ key in 50@@ -171,9 +171,7 @@ key in
@@ -88,7 +88,7 @@ index 144be7d..753cc62 100644
88 The file format is described in 88 The file format is described in
89 .Xr moduli 5 . 89 .Xr moduli 5 .
90diff --git a/ssh.1 b/ssh.1 90diff --git a/ssh.1 b/ssh.1
91index 0b38ae1..b3c3924 100644 91index 05ae6ad..6e2e03b 100644
92--- a/ssh.1 92--- a/ssh.1
93+++ b/ssh.1 93+++ b/ssh.1
94@@ -756,6 +756,10 @@ Protocol 1 is restricted to using only RSA keys, 94@@ -756,6 +756,10 @@ Protocol 1 is restricted to using only RSA keys,
@@ -103,7 +103,7 @@ index 0b38ae1..b3c3924 100644
103 .Pp 103 .Pp
104 The file 104 The file
105diff --git a/sshd.8 b/sshd.8 105diff --git a/sshd.8 b/sshd.8
106index a604429..6bdd219 100644 106index b0c7ab6..95c1845 100644
107--- a/sshd.8 107--- a/sshd.8
108+++ b/sshd.8 108+++ b/sshd.8
109@@ -70,7 +70,7 @@ over an insecure network. 109@@ -70,7 +70,7 @@ over an insecure network.
@@ -124,8 +124,8 @@ index a604429..6bdd219 100644
124 Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange". 124 Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
125 The file format is described in 125 The file format is described in
126 .Xr moduli 5 . 126 .Xr moduli 5 .
127@@ -957,7 +957,6 @@ The content of this file is not sensitive; it can be world-readable. 127@@ -956,7 +956,6 @@ The content of this file is not sensitive; it can be world-readable.
128 .Xr ssh-vulnkey 1 , 128 .Xr ssh-keyscan 1 ,
129 .Xr chroot 2 , 129 .Xr chroot 2 ,
130 .Xr hosts_access 5 , 130 .Xr hosts_access 5 ,
131-.Xr login.conf 5 , 131-.Xr login.conf 5 ,
@@ -133,7 +133,7 @@ index a604429..6bdd219 100644
133 .Xr sshd_config 5 , 133 .Xr sshd_config 5 ,
134 .Xr inetd 8 , 134 .Xr inetd 8 ,
135diff --git a/sshd_config.5 b/sshd_config.5 135diff --git a/sshd_config.5 b/sshd_config.5
136index eaf8d01..ec4851a 100644 136index 50eec53..04b5f1a 100644
137--- a/sshd_config.5 137--- a/sshd_config.5
138+++ b/sshd_config.5 138+++ b/sshd_config.5
139@@ -283,8 +283,7 @@ This option is only available for protocol version 2. 139@@ -283,8 +283,7 @@ This option is only available for protocol version 2.
diff --git a/debian/patches/package-versioning.patch b/debian/patches/package-versioning.patch
index df97fa40f..f6d793751 100644
--- a/debian/patches/package-versioning.patch
+++ b/debian/patches/package-versioning.patch
@@ -1,4 +1,4 @@
1From da3ff9786c4c03b2aac4936b28f06b3c152e230d Mon Sep 17 00:00:00 2001 1From 893bd5a6f70b58e1ed98d496c4f465d8c1df71a7 Mon Sep 17 00:00:00 2001
2From: Matthew Vernon <matthew@debian.org> 2From: Matthew Vernon <matthew@debian.org>
3Date: Sun, 9 Feb 2014 16:10:05 +0000 3Date: Sun, 9 Feb 2014 16:10:05 +0000
4Subject: Include the Debian version in our identification 4Subject: Include the Debian version in our identification
@@ -36,7 +36,7 @@ index bda83b2..ad960fd 100644
36 if (roaming_atomicio(vwrite, connection_out, client_version_string, 36 if (roaming_atomicio(vwrite, connection_out, client_version_string,
37 strlen(client_version_string)) != strlen(client_version_string)) 37 strlen(client_version_string)) != strlen(client_version_string))
38diff --git a/sshd.c b/sshd.c 38diff --git a/sshd.c b/sshd.c
39index fbe3284..7efa7ef 100644 39index e5c9835..46ec1a7 100644
40--- a/sshd.c 40--- a/sshd.c
41+++ b/sshd.c 41+++ b/sshd.c
42@@ -440,7 +440,7 @@ sshd_exchange_identification(int sock_in, int sock_out) 42@@ -440,7 +440,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
diff --git a/debian/patches/quieter-signals.patch b/debian/patches/quieter-signals.patch
index 5cb0146d8..664abf0ff 100644
--- a/debian/patches/quieter-signals.patch
+++ b/debian/patches/quieter-signals.patch
@@ -1,4 +1,4 @@
1From da5b4ce7296ada332d70133a9ec02ba71c742b7d Mon Sep 17 00:00:00 2001 1From 360257b8a56798d507123ff770f2def408464f00 Mon Sep 17 00:00:00 2001
2From: Peter Samuelson <peter@p12n.org> 2From: Peter Samuelson <peter@p12n.org>
3Date: Sun, 9 Feb 2014 16:09:55 +0000 3Date: Sun, 9 Feb 2014 16:09:55 +0000
4Subject: Reduce severity of "Killed by signal %d" 4Subject: Reduce severity of "Killed by signal %d"
diff --git a/debian/patches/scp-quoting.patch b/debian/patches/scp-quoting.patch
index 887164beb..71dcecc9c 100644
--- a/debian/patches/scp-quoting.patch
+++ b/debian/patches/scp-quoting.patch
@@ -1,4 +1,4 @@
1From 7531f41888f9e40be95a319fb325f6f05dd50751 Mon Sep 17 00:00:00 2001 1From bb3ea9f222f7f0fe9b449b75bfae93513f7ca3e2 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com> 2From: =?UTF-8?q?Nicolas=20Valc=C3=A1rcel?= <nvalcarcel@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:59 +0000 3Date: Sun, 9 Feb 2014 16:09:59 +0000
4Subject: Adjust scp quoting in verbose mode 4Subject: Adjust scp quoting in verbose mode
diff --git a/debian/patches/series b/debian/patches/series
index ced2bbd1e..5d21e57d1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,6 +1,6 @@
1gssapi.patch 1gssapi.patch
2selinux-role.patch 2selinux-role.patch
3ssh-vulnkey.patch 3ssh-vulnkey-compat.patch
4ssh1-keepalive.patch 4ssh1-keepalive.patch
5keepalive-extensions.patch 5keepalive-extensions.patch
6syslog-level-silent.patch 6syslog-level-silent.patch
diff --git a/debian/patches/shell-path.patch b/debian/patches/shell-path.patch
index 8f09b936a..a7540eb34 100644
--- a/debian/patches/shell-path.patch
+++ b/debian/patches/shell-path.patch
@@ -1,4 +1,4 @@
1From b5f3be892e6d7150e7885133228fd03af69a11bc Mon Sep 17 00:00:00 2001 1From 7231af57ca3efb451ace1b8e056fa0e52c67654e Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:00 +0000 3Date: Sun, 9 Feb 2014 16:10:00 +0000
4Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand 4Subject: Look for $SHELL on the path for ProxyCommand/LocalCommand
diff --git a/debian/patches/sigstop.patch b/debian/patches/sigstop.patch
index febcbc86a..7776b6d11 100644
--- a/debian/patches/sigstop.patch
+++ b/debian/patches/sigstop.patch
@@ -1,4 +1,4 @@
1From 6fba9b85d3529fd3e1ca03dff3e457f04b3e39dd Mon Sep 17 00:00:00 2001 1From 727d51f30918f6635f06694f71f4318a6038296d Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:17 +0000 3Date: Sun, 9 Feb 2014 16:10:17 +0000
4Subject: Support synchronisation with service supervisor using SIGSTOP 4Subject: Support synchronisation with service supervisor using SIGSTOP
@@ -12,10 +12,10 @@ Patch-Name: sigstop.patch
12 1 file changed, 4 insertions(+) 12 1 file changed, 4 insertions(+)
13 13
14diff --git a/sshd.c b/sshd.c 14diff --git a/sshd.c b/sshd.c
15index 6b988fe..72e9eaf 100644 15index 63b9357..fd7f182 100644
16--- a/sshd.c 16--- a/sshd.c
17+++ b/sshd.c 17+++ b/sshd.c
18@@ -1914,6 +1914,10 @@ main(int ac, char **av) 18@@ -1909,6 +1909,10 @@ main(int ac, char **av)
19 } 19 }
20 } 20 }
21 21
diff --git a/debian/patches/ssh-agent-setgid.patch b/debian/patches/ssh-agent-setgid.patch
index 3760e8c14..9ae105960 100644
--- a/debian/patches/ssh-agent-setgid.patch
+++ b/debian/patches/ssh-agent-setgid.patch
@@ -1,4 +1,4 @@
1From 92a81c0caf44c15d3a07cf1f36470ca05c11ff1e Mon Sep 17 00:00:00 2001 1From ad4f5086a0f0c47daf04be484ff310101551e48a Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:13 +0000 3Date: Sun, 9 Feb 2014 16:10:13 +0000
4Subject: Document consequences of ssh-agent being setgid in ssh-agent(1) 4Subject: Document consequences of ssh-agent being setgid in ssh-agent(1)
diff --git a/debian/patches/ssh-argv0.patch b/debian/patches/ssh-argv0.patch
index b15f251ef..138a3632a 100644
--- a/debian/patches/ssh-argv0.patch
+++ b/debian/patches/ssh-argv0.patch
@@ -1,4 +1,4 @@
1From b339802cbe8c304541273029a1c9c3c639725643 Mon Sep 17 00:00:00 2001 1From 901a9e09f92a72c4a627af9feffdd39fb805e95d Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:10:10 +0000 3Date: Sun, 9 Feb 2014 16:10:10 +0000
4Subject: ssh(1): Refer to ssh-argv0(1) 4Subject: ssh(1): Refer to ssh-argv0(1)
@@ -18,7 +18,7 @@ Patch-Name: ssh-argv0.patch
18 1 file changed, 1 insertion(+) 18 1 file changed, 1 insertion(+)
19 19
20diff --git a/ssh.1 b/ssh.1 20diff --git a/ssh.1 b/ssh.1
21index b3c3924..c0cc12f 100644 21index 6e2e03b..63b0573 100644
22--- a/ssh.1 22--- a/ssh.1
23+++ b/ssh.1 23+++ b/ssh.1
24@@ -1451,6 +1451,7 @@ if an error occurred. 24@@ -1451,6 +1451,7 @@ if an error occurred.
@@ -28,4 +28,4 @@ index b3c3924..c0cc12f 100644
28+.Xr ssh-argv0 1 , 28+.Xr ssh-argv0 1 ,
29 .Xr ssh-keygen 1 , 29 .Xr ssh-keygen 1 ,
30 .Xr ssh-keyscan 1 , 30 .Xr ssh-keyscan 1 ,
31 .Xr ssh-vulnkey 1 , 31 .Xr tun 4 ,
diff --git a/debian/patches/ssh-vulnkey-compat.patch b/debian/patches/ssh-vulnkey-compat.patch
new file mode 100644
index 000000000..50d500f6d
--- /dev/null
+++ b/debian/patches/ssh-vulnkey-compat.patch
@@ -0,0 +1,42 @@
1From bdc94de85ed7dbafb949c239d7c3eff23ea4aa28 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:50 +0000
4Subject: Accept obsolete ssh-vulnkey configuration options
5
6These options were used as part of Debian's response to CVE-2008-0166.
7Nearly six years later, we no longer need to continue carrying the bulk
8of that patch, but we do need to avoid failing when the associated
9configuration options are still present.
10
11Last-Update: 2014-02-09
12
13Patch-Name: ssh-vulnkey-compat.patch
14---
15 readconf.c | 1 +
16 servconf.c | 1 +
17 2 files changed, 2 insertions(+)
18
19diff --git a/readconf.c b/readconf.c
20index 2695fd6..915a0f7 100644
21--- a/readconf.c
22+++ b/readconf.c
23@@ -161,6 +161,7 @@ static struct {
24 { "passwordauthentication", oPasswordAuthentication },
25 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
26 { "kbdinteractivedevices", oKbdInteractiveDevices },
27+ { "useblacklistedkeys", oDeprecated },
28 { "rsaauthentication", oRSAAuthentication },
29 { "pubkeyauthentication", oPubkeyAuthentication },
30 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
31diff --git a/servconf.c b/servconf.c
32index c938ae3..dcb8caf 100644
33--- a/servconf.c
34+++ b/servconf.c
35@@ -451,6 +451,7 @@ static struct {
36 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
37 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
38 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
39+ { "permitblacklistedkeys", sDeprecated, SSHCFG_GLOBAL },
40 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
41 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
42 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
diff --git a/debian/patches/ssh-vulnkey.patch b/debian/patches/ssh-vulnkey.patch
deleted file mode 100644
index ae262083d..000000000
--- a/debian/patches/ssh-vulnkey.patch
+++ /dev/null
@@ -1,1419 +0,0 @@
1From 8909ff0e3cd07d1b042d1be1c8b8828dbf6c9a83 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@ubuntu.com>
3Date: Sun, 9 Feb 2014 16:09:50 +0000
4Subject: Reject vulnerable keys to mitigate Debian OpenSSL flaw
5
6In 2008, Debian (and derived distributions such as Ubuntu) shipped an
7OpenSSL package with a flawed random number generator, causing OpenSSH to
8generate only a very limited set of keys which were subject to private half
9precomputation. To mitigate this, this patch checks key authentications
10against a blacklist of known-vulnerable keys, and adds a new ssh-vulnkey
11program which can be used to explicitly check keys against that blacklist.
12See CVE-2008-0166.
13
14Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1469
15Last-Update: 2013-09-14
16
17Patch-Name: ssh-vulnkey.patch
18---
19 Makefile.in | 17 ++-
20 auth-rh-rsa.c | 2 +-
21 auth-rsa.c | 2 +-
22 auth.c | 27 +++-
23 auth.h | 2 +-
24 auth2-hostbased.c | 2 +-
25 auth2-pubkey.c | 5 +-
26 authfile.c | 136 +++++++++++++++++++
27 authfile.h | 2 +
28 pathnames.h | 7 +
29 readconf.c | 9 ++
30 readconf.h | 1 +
31 servconf.c | 11 +-
32 servconf.h | 1 +
33 ssh-add.1 | 5 +
34 ssh-add.c | 10 +-
35 ssh-keygen.1 | 1 +
36 ssh-vulnkey.1 | 242 ++++++++++++++++++++++++++++++++++
37 ssh-vulnkey.c | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 ssh.1 | 1 +
39 ssh.c | 18 ++-
40 ssh_config.5 | 17 +++
41 sshconnect2.c | 4 +-
42 sshd.8 | 1 +
43 sshd.c | 5 +
44 sshd_config.5 | 14 ++
45 26 files changed, 913 insertions(+), 15 deletions(-)
46 create mode 100644 ssh-vulnkey.1
47 create mode 100644 ssh-vulnkey.c
48
49diff --git a/Makefile.in b/Makefile.in
50index f979926..b8f5099 100644
51--- a/Makefile.in
52+++ b/Makefile.in
53@@ -26,6 +26,7 @@ ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
54 SFTP_SERVER=$(libexecdir)/sftp-server
55 SSH_KEYSIGN=$(libexecdir)/ssh-keysign
56 SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper
57+SSH_DATADIR=$(datadir)/ssh
58 PRIVSEP_PATH=@PRIVSEP_PATH@
59 SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
60 STRIP_OPT=@STRIP_OPT@
61@@ -37,7 +38,8 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \
62 -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
63 -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \
64 -D_PATH_SSH_PIDDIR=\"$(piddir)\" \
65- -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\"
66+ -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \
67+ -D_PATH_SSH_DATADIR=\"$(SSH_DATADIR)\"
68
69 CC=@CC@
70 LD=@LD@
71@@ -61,7 +63,7 @@ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
72 EXEEXT=@EXEEXT@
73 MANFMT=@MANFMT@
74
75-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
76+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-vulnkey$(EXEEXT)
77
78 LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
79 canohost.o channels.o cipher.o cipher-aes.o \
80@@ -96,8 +98,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
81 sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
82 sandbox-seccomp-filter.o
83
84-MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out
85-MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5
86+MANPAGES = moduli.5.out 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-keysign.8.out ssh-pkcs11-helper.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out
87+MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5
88 MANTYPE = @MANTYPE@
89
90 CONFIGFILES=sshd_config.out ssh_config.out moduli.out
91@@ -176,6 +178,9 @@ sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o s
92 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
93 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
94
95+ssh-vulnkey$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-vulnkey.o
96+ $(LD) -o $@ ssh-vulnkey.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
97+
98 # test driver for the loginrec code - not built by default
99 logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
100 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
101@@ -272,6 +277,7 @@ install-files:
102 $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
103 $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
104 $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
105+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-vulnkey$(EXEEXT) $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
106 $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
107 $(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
108 $(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
109@@ -286,6 +292,7 @@ install-files:
110 $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
111 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
112 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
113+ $(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
114 -rm -f $(DESTDIR)$(bindir)/slogin
115 ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
116 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
117@@ -367,6 +374,7 @@ uninstall:
118 -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
119 -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
120 -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
121+ -rm -f $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
122 -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
123 -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
124 -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
125@@ -379,6 +387,7 @@ uninstall:
126 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
127 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
128 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
129+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
130 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
131 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
132 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
133diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
134index b21a0f4..891ec32 100644
135--- a/auth-rh-rsa.c
136+++ b/auth-rh-rsa.c
137@@ -44,7 +44,7 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
138 {
139 HostStatus host_status;
140
141- if (auth_key_is_revoked(client_host_key))
142+ if (auth_key_is_revoked(client_host_key, 0))
143 return 0;
144
145 /* Check if we would accept it using rhosts authentication. */
146diff --git a/auth-rsa.c b/auth-rsa.c
147index 545aa49..6ed152c 100644
148--- a/auth-rsa.c
149+++ b/auth-rsa.c
150@@ -237,7 +237,7 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file,
151 free(fp);
152
153 /* Never accept a revoked key */
154- if (auth_key_is_revoked(key))
155+ if (auth_key_is_revoked(key, 0))
156 break;
157
158 /* We have found the desired key. */
159diff --git a/auth.c b/auth.c
160index 9a36f1d..6662e9a 100644
161--- a/auth.c
162+++ b/auth.c
163@@ -59,6 +59,7 @@
164 #include "servconf.h"
165 #include "key.h"
166 #include "hostfile.h"
167+#include "authfile.h"
168 #include "auth.h"
169 #include "auth-options.h"
170 #include "canohost.h"
171@@ -657,10 +658,34 @@ getpwnamallow(const char *user)
172
173 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
174 int
175-auth_key_is_revoked(Key *key)
176+auth_key_is_revoked(Key *key, int hostkey)
177 {
178 char *key_fp;
179
180+ if (blacklisted_key(key, &key_fp) == 1) {
181+ if (options.permit_blacklisted_keys) {
182+ if (hostkey)
183+ error("Host key %s blacklisted (see "
184+ "ssh-vulnkey(1)); continuing anyway",
185+ key_fp);
186+ else
187+ logit("Public key %s from %s blacklisted (see "
188+ "ssh-vulnkey(1)); continuing anyway",
189+ key_fp, get_remote_ipaddr());
190+ free(key_fp);
191+ } else {
192+ if (hostkey)
193+ error("Host key %s blacklisted (see "
194+ "ssh-vulnkey(1))", key_fp);
195+ else
196+ logit("Public key %s from %s blacklisted (see "
197+ "ssh-vulnkey(1))",
198+ key_fp, get_remote_ipaddr());
199+ free(key_fp);
200+ return 1;
201+ }
202+ }
203+
204 if (options.revoked_keys_file == NULL)
205 return 0;
206 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
207diff --git a/auth.h b/auth.h
208index 5b6824f..ec95460 100644
209--- a/auth.h
210+++ b/auth.h
211@@ -191,7 +191,7 @@ char *authorized_principals_file(struct passwd *);
212
213 FILE *auth_openkeyfile(const char *, struct passwd *, int);
214 FILE *auth_openprincipals(const char *, struct passwd *, int);
215-int auth_key_is_revoked(Key *);
216+int auth_key_is_revoked(Key *, int);
217
218 HostStatus
219 check_key_in_hostfiles(struct passwd *, Key *, const char *,
220diff --git a/auth2-hostbased.c b/auth2-hostbased.c
221index a344dcc..3a17f1b 100644
222--- a/auth2-hostbased.c
223+++ b/auth2-hostbased.c
224@@ -150,7 +150,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
225 int len;
226 char *fp;
227
228- if (auth_key_is_revoked(key))
229+ if (auth_key_is_revoked(key, 0))
230 return 0;
231
232 resolvedname = get_canonical_hostname(options.use_dns);
233diff --git a/auth2-pubkey.c b/auth2-pubkey.c
234index 2b3ecb1..12eb8a6 100644
235--- a/auth2-pubkey.c
236+++ b/auth2-pubkey.c
237@@ -647,9 +647,10 @@ user_key_allowed(struct passwd *pw, Key *key)
238 u_int success, i;
239 char *file;
240
241- if (auth_key_is_revoked(key))
242+ if (auth_key_is_revoked(key, 0))
243 return 0;
244- if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
245+ if (key_is_cert(key) &&
246+ auth_key_is_revoked(key->cert->signature_key, 0))
247 return 0;
248
249 success = user_cert_trusted_ca(pw, key);
250diff --git a/authfile.c b/authfile.c
251index 63ae16b..9833591 100644
252--- a/authfile.c
253+++ b/authfile.c
254@@ -68,6 +68,7 @@
255 #include "rsa.h"
256 #include "misc.h"
257 #include "atomicio.h"
258+#include "pathnames.h"
259
260 #define MAX_KEY_FILE_SIZE (1024 * 1024)
261
262@@ -944,3 +945,138 @@ key_in_file(Key *key, const char *filename, int strict_type)
263 return ret;
264 }
265
266+/* Scan a blacklist of known-vulnerable keys in blacklist_file. */
267+static int
268+blacklisted_key_in_file(Key *key, const char *blacklist_file, char **fp)
269+{
270+ int fd = -1;
271+ char *dgst_hex = NULL;
272+ char *dgst_packed = NULL, *p;
273+ int i;
274+ size_t line_len;
275+ struct stat st;
276+ char buf[256];
277+ off_t start, lower, upper;
278+ int ret = 0;
279+
280+ debug("Checking blacklist file %s", blacklist_file);
281+ fd = open(blacklist_file, O_RDONLY);
282+ if (fd < 0) {
283+ ret = -1;
284+ goto out;
285+ }
286+
287+ dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
288+ /* Remove all colons */
289+ dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
290+ for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
291+ if (dgst_hex[i] != ':')
292+ *p++ = dgst_hex[i];
293+ /* Only compare least-significant 80 bits (to keep the blacklist
294+ * size down)
295+ */
296+ line_len = strlen(dgst_packed + 12);
297+ if (line_len > 32)
298+ goto out;
299+
300+ /* Skip leading comments */
301+ start = 0;
302+ for (;;) {
303+ ssize_t r;
304+ char *newline;
305+
306+ r = atomicio(read, fd, buf, sizeof(buf));
307+ if (r <= 0)
308+ goto out;
309+ if (buf[0] != '#')
310+ break;
311+
312+ newline = memchr(buf, '\n', sizeof(buf));
313+ if (!newline)
314+ goto out;
315+ start += newline + 1 - buf;
316+ if (lseek(fd, start, SEEK_SET) < 0)
317+ goto out;
318+ }
319+
320+ /* Initialise binary search record numbers */
321+ if (fstat(fd, &st) < 0)
322+ goto out;
323+ lower = 0;
324+ upper = (st.st_size - start) / (line_len + 1);
325+
326+ while (lower != upper) {
327+ off_t cur;
328+ int cmp;
329+
330+ cur = lower + (upper - lower) / 2;
331+
332+ /* Read this line and compare to digest; this is
333+ * overflow-safe since cur < max(off_t) / (line_len + 1) */
334+ if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
335+ break;
336+ if (atomicio(read, fd, buf, line_len) != line_len)
337+ break;
338+ cmp = memcmp(buf, dgst_packed + 12, line_len);
339+ if (cmp < 0) {
340+ if (cur == lower)
341+ break;
342+ lower = cur;
343+ } else if (cmp > 0) {
344+ if (cur == upper)
345+ break;
346+ upper = cur;
347+ } else {
348+ debug("Found %s in blacklist", dgst_hex);
349+ ret = 1;
350+ break;
351+ }
352+ }
353+
354+out:
355+ free(dgst_packed);
356+ if (ret != 1 && dgst_hex) {
357+ free(dgst_hex);
358+ dgst_hex = NULL;
359+ }
360+ if (fp)
361+ *fp = dgst_hex;
362+ if (fd >= 0)
363+ close(fd);
364+ return ret;
365+}
366+
367+/*
368+ * Scan blacklists of known-vulnerable keys. If a vulnerable key is found,
369+ * its fingerprint is returned in *fp, unless fp is NULL.
370+ */
371+int
372+blacklisted_key(Key *key, char **fp)
373+{
374+ Key *public;
375+ char *blacklist_file;
376+ int ret, ret2;
377+
378+ public = key_demote(key);
379+ if (public->type == KEY_RSA1)
380+ public->type = KEY_RSA;
381+
382+ xasprintf(&blacklist_file, "%s.%s-%u",
383+ _PATH_BLACKLIST, key_type(public), key_size(public));
384+ ret = blacklisted_key_in_file(public, blacklist_file, fp);
385+ free(blacklist_file);
386+ if (ret > 0) {
387+ key_free(public);
388+ return ret;
389+ }
390+
391+ xasprintf(&blacklist_file, "%s.%s-%u",
392+ _PATH_BLACKLIST_CONFIG, key_type(public), key_size(public));
393+ ret2 = blacklisted_key_in_file(public, blacklist_file, fp);
394+ free(blacklist_file);
395+ if (ret2 > ret)
396+ ret = ret2;
397+
398+ key_free(public);
399+ return ret;
400+}
401diff --git a/authfile.h b/authfile.h
402index 78349be..3f2bdcb 100644
403--- a/authfile.h
404+++ b/authfile.h
405@@ -28,4 +28,6 @@ Key *key_load_private_pem(int, int, const char *, char **);
406 int key_perm_ok(int, const char *);
407 int key_in_file(Key *, const char *, int);
408
409+int blacklisted_key(Key *key, char **fp);
410+
411 #endif
412diff --git a/pathnames.h b/pathnames.h
413index 5027fba..47f7867 100644
414--- a/pathnames.h
415+++ b/pathnames.h
416@@ -18,6 +18,10 @@
417 #define SSHDIR ETCDIR "/ssh"
418 #endif
419
420+#ifndef _PATH_SSH_DATADIR
421+#define _PATH_SSH_DATADIR "/usr/share/ssh"
422+#endif
423+
424 #ifndef _PATH_SSH_PIDDIR
425 #define _PATH_SSH_PIDDIR "/var/run"
426 #endif
427@@ -44,6 +48,9 @@
428 /* Backwards compatibility */
429 #define _PATH_DH_PRIMES SSHDIR "/primes"
430
431+#define _PATH_BLACKLIST _PATH_SSH_DATADIR "/blacklist"
432+#define _PATH_BLACKLIST_CONFIG SSHDIR "/blacklist"
433+
434 #ifndef _PATH_SSH_PROGRAM
435 #define _PATH_SSH_PROGRAM "/usr/bin/ssh"
436 #endif
437diff --git a/readconf.c b/readconf.c
438index 2695fd6..22e5a3a 100644
439--- a/readconf.c
440+++ b/readconf.c
441@@ -128,6 +128,7 @@ typedef enum {
442 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
443 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
444 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
445+ oUseBlacklistedKeys,
446 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
447 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
448 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
449@@ -161,6 +162,7 @@ static struct {
450 { "passwordauthentication", oPasswordAuthentication },
451 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
452 { "kbdinteractivedevices", oKbdInteractiveDevices },
453+ { "useblacklistedkeys", oUseBlacklistedKeys },
454 { "rsaauthentication", oRSAAuthentication },
455 { "pubkeyauthentication", oPubkeyAuthentication },
456 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
457@@ -523,6 +525,10 @@ parse_flag:
458 intptr = &options->challenge_response_authentication;
459 goto parse_flag;
460
461+ case oUseBlacklistedKeys:
462+ intptr = &options->use_blacklisted_keys;
463+ goto parse_flag;
464+
465 case oGssAuthentication:
466 intptr = &options->gss_authentication;
467 goto parse_flag;
468@@ -1210,6 +1216,7 @@ initialize_options(Options * options)
469 options->kbd_interactive_devices = NULL;
470 options->rhosts_rsa_authentication = -1;
471 options->hostbased_authentication = -1;
472+ options->use_blacklisted_keys = -1;
473 options->batch_mode = -1;
474 options->check_host_ip = -1;
475 options->strict_host_key_checking = -1;
476@@ -1320,6 +1327,8 @@ fill_default_options(Options * options)
477 options->rhosts_rsa_authentication = 0;
478 if (options->hostbased_authentication == -1)
479 options->hostbased_authentication = 0;
480+ if (options->use_blacklisted_keys == -1)
481+ options->use_blacklisted_keys = 0;
482 if (options->batch_mode == -1)
483 options->batch_mode = 0;
484 if (options->check_host_ip == -1)
485diff --git a/readconf.h b/readconf.h
486index 675b35d..a508151 100644
487--- a/readconf.h
488+++ b/readconf.h
489@@ -59,6 +59,7 @@ typedef struct {
490 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
491 char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
492 int zero_knowledge_password_authentication; /* Try jpake */
493+ int use_blacklisted_keys; /* If true, send */
494 int batch_mode; /* Batch mode: do not ask for passwords. */
495 int check_host_ip; /* Also keep track of keys for IP address */
496 int strict_host_key_checking; /* Strict host key checking. */
497diff --git a/servconf.c b/servconf.c
498index c938ae3..9155a8b 100644
499--- a/servconf.c
500+++ b/servconf.c
501@@ -114,6 +114,7 @@ initialize_server_options(ServerOptions *options)
502 options->password_authentication = -1;
503 options->kbd_interactive_authentication = -1;
504 options->challenge_response_authentication = -1;
505+ options->permit_blacklisted_keys = -1;
506 options->permit_empty_passwd = -1;
507 options->permit_user_env = -1;
508 options->use_login = -1;
509@@ -257,6 +258,8 @@ fill_default_server_options(ServerOptions *options)
510 options->kbd_interactive_authentication = 0;
511 if (options->challenge_response_authentication == -1)
512 options->challenge_response_authentication = 1;
513+ if (options->permit_blacklisted_keys == -1)
514+ options->permit_blacklisted_keys = 0;
515 if (options->permit_empty_passwd == -1)
516 options->permit_empty_passwd = 0;
517 if (options->permit_user_env == -1)
518@@ -338,7 +341,7 @@ typedef enum {
519 sListenAddress, sAddressFamily,
520 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
521 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
522- sStrictModes, sEmptyPasswd, sTCPKeepAlive,
523+ sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive,
524 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
525 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
526 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
527@@ -451,6 +454,7 @@ static struct {
528 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
529 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
530 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
531+ { "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL },
532 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
533 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
534 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
535@@ -1158,6 +1162,10 @@ process_server_config_line(ServerOptions *options, char *line,
536 intptr = &options->tcp_keep_alive;
537 goto parse_flag;
538
539+ case sPermitBlacklistedKeys:
540+ intptr = &options->permit_blacklisted_keys;
541+ goto parse_flag;
542+
543 case sEmptyPasswd:
544 intptr = &options->permit_empty_passwd;
545 goto parse_flag;
546@@ -2036,6 +2044,7 @@ dump_config(ServerOptions *o)
547 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
548 dump_cfg_fmtint(sStrictModes, o->strict_modes);
549 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
550+ dump_cfg_fmtint(sPermitBlacklistedKeys, o->permit_blacklisted_keys);
551 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
552 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
553 dump_cfg_fmtint(sUseLogin, o->use_login);
554diff --git a/servconf.h b/servconf.h
555index ab6e346..f655c5b 100644
556--- a/servconf.h
557+++ b/servconf.h
558@@ -121,6 +121,7 @@ typedef struct {
559 int challenge_response_authentication;
560 int zero_knowledge_password_authentication;
561 /* If true, permit jpake auth */
562+ int permit_blacklisted_keys; /* If true, permit */
563 int permit_empty_passwd; /* If false, do not permit empty
564 * passwords. */
565 int permit_user_env; /* If true, read ~/.ssh/environment */
566diff --git a/ssh-add.1 b/ssh-add.1
567index 44846b6..d394b26 100644
568--- a/ssh-add.1
569+++ b/ssh-add.1
570@@ -81,6 +81,10 @@ environment variable must contain the name of its socket for
571 .Nm
572 to work.
573 .Pp
574+Any keys recorded in the blacklist of known-compromised keys (see
575+.Xr ssh-vulnkey 1 )
576+will be refused.
577+.Pp
578 The options are as follows:
579 .Bl -tag -width Ds
580 .It Fl c
581@@ -186,6 +190,7 @@ is unable to contact the authentication agent.
582 .Xr ssh 1 ,
583 .Xr ssh-agent 1 ,
584 .Xr ssh-keygen 1 ,
585+.Xr ssh-vulnkey 1 ,
586 .Xr sshd 8
587 .Sh AUTHORS
588 OpenSSH is a derivative of the original and free
589diff --git a/ssh-add.c b/ssh-add.c
590index 5e8166f..b309582 100644
591--- a/ssh-add.c
592+++ b/ssh-add.c
593@@ -167,7 +167,7 @@ static int
594 add_file(AuthenticationConnection *ac, const char *filename, int key_only)
595 {
596 Key *private, *cert;
597- char *comment = NULL;
598+ char *comment = NULL, *fp;
599 char msg[1024], *certpath = NULL;
600 int fd, perms_ok, ret = -1;
601 Buffer keyblob;
602@@ -243,6 +243,14 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only)
603 } else {
604 fprintf(stderr, "Could not add identity: %s\n", filename);
605 }
606+ if (blacklisted_key(private, &fp) == 1) {
607+ fprintf(stderr, "Public key %s blacklisted (see "
608+ "ssh-vulnkey(1)); refusing to add it\n", fp);
609+ free(fp);
610+ key_free(private);
611+ free(comment);
612+ return -1;
613+ }
614
615 /* Skip trying to load the cert if requested */
616 if (key_only)
617diff --git a/ssh-keygen.1 b/ssh-keygen.1
618index 0d55854..144be7d 100644
619--- a/ssh-keygen.1
620+++ b/ssh-keygen.1
621@@ -809,6 +809,7 @@ The file format is described in
622 .Xr ssh 1 ,
623 .Xr ssh-add 1 ,
624 .Xr ssh-agent 1 ,
625+.Xr ssh-vulnkey 1 ,
626 .Xr moduli 5 ,
627 .Xr sshd 8
628 .Rs
629diff --git a/ssh-vulnkey.1 b/ssh-vulnkey.1
630new file mode 100644
631index 0000000..bcb9d31
632--- /dev/null
633+++ b/ssh-vulnkey.1
634@@ -0,0 +1,242 @@
635+.\" Copyright (c) 2008 Canonical Ltd. All rights reserved.
636+.\"
637+.\" Redistribution and use in source and binary forms, with or without
638+.\" modification, are permitted provided that the following conditions
639+.\" are met:
640+.\" 1. Redistributions of source code must retain the above copyright
641+.\" notice, this list of conditions and the following disclaimer.
642+.\" 2. Redistributions in binary form must reproduce the above copyright
643+.\" notice, this list of conditions and the following disclaimer in the
644+.\" documentation and/or other materials provided with the distribution.
645+.\"
646+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
647+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
648+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
649+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
650+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
651+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
652+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
653+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
654+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
655+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
656+.\"
657+.Dd $Mdocdate: May 12 2008 $
658+.Dt SSH-VULNKEY 1
659+.Os
660+.Sh NAME
661+.Nm ssh-vulnkey
662+.Nd check blacklist of compromised keys
663+.Sh SYNOPSIS
664+.Nm
665+.Op Fl q | Fl v
666+.Ar file ...
667+.Nm
668+.Fl a
669+.Sh DESCRIPTION
670+.Nm
671+checks a key against a blacklist of compromised keys.
672+.Pp
673+A substantial number of keys are known to have been generated using a broken
674+version of OpenSSL distributed by Debian which failed to seed its random
675+number generator correctly.
676+Keys generated using these OpenSSL versions should be assumed to be
677+compromised.
678+This tool may be useful in checking for such keys.
679+.Pp
680+Keys that are compromised cannot be repaired; replacements must be generated
681+using
682+.Xr ssh-keygen 1 .
683+Make sure to update
684+.Pa authorized_keys
685+files on all systems where compromised keys were permitted to authenticate.
686+.Pp
687+The argument list will be interpreted as a list of paths to public key files
688+or
689+.Pa authorized_keys
690+files.
691+If no suitable file is found at a given path,
692+.Nm
693+will append
694+.Pa .pub
695+and retry, in case it was given a private key file.
696+If no files are given as arguments,
697+.Nm
698+will check
699+.Pa ~/.ssh/id_rsa ,
700+.Pa ~/.ssh/id_dsa ,
701+.Pa ~/.ssh/identity ,
702+.Pa ~/.ssh/authorized_keys
703+and
704+.Pa ~/.ssh/authorized_keys2 ,
705+as well as the system's host keys if readable.
706+.Pp
707+If
708+.Dq -
709+is given as an argument,
710+.Nm
711+will read from standard input.
712+This can be used to process output from
713+.Xr ssh-keyscan 1 ,
714+for example:
715+.Pp
716+.Dl $ ssh-keyscan -t rsa remote.example.org | ssh-vulnkey -
717+.Pp
718+Unless the
719+.Cm PermitBlacklistedKeys
720+option is used,
721+.Xr sshd 8
722+will reject attempts to authenticate with keys in the compromised list.
723+.Pp
724+The output from
725+.Nm
726+looks like this:
727+.Pp
728+.Bd -literal -offset indent
729+/etc/ssh/ssh_host_key:1: COMPROMISED: RSA1 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx root@host
730+/home/user/.ssh/id_dsa:1: Not blacklisted: DSA 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx /home/user/.ssh/id_dsa.pub
731+/home/user/.ssh/authorized_keys:3: Unknown (blacklist file not installed): RSA 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user@host
732+.Ed
733+.Pp
734+Each line is of the following format (any lines beginning with
735+.Dq #
736+should be ignored by scripts):
737+.Pp
738+.Dl Ar filename : Ns Ar line : Ar status : Ar type Ar size Ar fingerprint Ar comment
739+.Pp
740+It is important to distinguish between the possible values of
741+.Ar status :
742+.Pp
743+.Bl -tag -width Ds
744+.It COMPROMISED
745+These keys are listed in a blacklist file, normally because their
746+corresponding private keys are well-known.
747+Replacements must be generated using
748+.Xr ssh-keygen 1 .
749+.It Not blacklisted
750+A blacklist file exists for this key type and size, but this key is not
751+listed in it.
752+Unless there is some particular reason to believe otherwise, this key
753+may be used safely.
754+(Note that DSA keys used with the broken version of OpenSSL distributed
755+by Debian may be compromised in the event that anyone captured a network
756+trace, even if they were generated with a secure version of OpenSSL.)
757+.It Unknown (blacklist file not installed)
758+No blacklist file exists for this key type and size.
759+You should find a suitable published blacklist and install it before
760+deciding whether this key is safe to use.
761+.El
762+.Pp
763+The options are as follows:
764+.Bl -tag -width Ds
765+.It Fl a
766+Check keys of all users on the system.
767+You will typically need to run
768+.Nm
769+as root to use this option.
770+For each user,
771+.Nm
772+will check
773+.Pa ~/.ssh/id_rsa ,
774+.Pa ~/.ssh/id_dsa ,
775+.Pa ~/.ssh/identity ,
776+.Pa ~/.ssh/authorized_keys
777+and
778+.Pa ~/.ssh/authorized_keys2 .
779+It will also check the system's host keys.
780+.It Fl q
781+Quiet mode.
782+Normally,
783+.Nm
784+outputs the fingerprint of each key scanned, with a description of its
785+status.
786+This option suppresses that output.
787+.It Fl v
788+Verbose mode.
789+Normally,
790+.Nm
791+does not output anything for keys that are not listed in their corresponding
792+blacklist file (although it still produces output for keys for which there
793+is no blacklist file, since their status is unknown).
794+This option causes
795+.Nm
796+to produce output for all keys.
797+.El
798+.Sh EXIT STATUS
799+.Nm
800+will exit zero if any of the given keys were in the compromised list,
801+otherwise non-zero.
802+.Sh BLACKLIST FILE FORMAT
803+The blacklist file may start with comments, on lines starting with
804+.Dq # .
805+After these initial comments, it must follow a strict format:
806+.Pp
807+.Bl -bullet -offset indent -compact
808+.It
809+All the lines must be exactly the same length (20 characters followed by a
810+newline) and must be in sorted order.
811+.It
812+Each line must consist of the lower-case hexadecimal MD5 key fingerprint,
813+without colons, and with the first 12 characters removed (that is, the least
814+significant 80 bits of the fingerprint).
815+.El
816+.Pp
817+The key fingerprint may be generated using
818+.Xr ssh-keygen 1 :
819+.Pp
820+.Dl $ ssh-keygen -l -f /path/to/key
821+.Pp
822+This strict format is necessary to allow the blacklist file to be checked
823+quickly, using a binary-search algorithm.
824+.Sh FILES
825+.Bl -tag -width Ds
826+.It Pa ~/.ssh/id_rsa
827+If present, contains the protocol version 2 RSA authentication identity of
828+the user.
829+.It Pa ~/.ssh/id_dsa
830+If present, contains the protocol version 2 DSA authentication identity of
831+the user.
832+.It Pa ~/.ssh/identity
833+If present, contains the protocol version 1 RSA authentication identity of
834+the user.
835+.It Pa ~/.ssh/authorized_keys
836+If present, lists the public keys (RSA/DSA) that can be used for logging in
837+as this user.
838+.It Pa ~/.ssh/authorized_keys2
839+Obsolete name for
840+.Pa ~/.ssh/authorized_keys .
841+This file may still be present on some old systems, but should not be
842+created if it is missing.
843+.It Pa /etc/ssh/ssh_host_rsa_key
844+If present, contains the protocol version 2 RSA identity of the system.
845+.It Pa /etc/ssh/ssh_host_dsa_key
846+If present, contains the protocol version 2 DSA identity of the system.
847+.It Pa /etc/ssh/ssh_host_key
848+If present, contains the protocol version 1 RSA identity of the system.
849+.It Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH
850+If present, lists the blacklisted keys of type
851+.Ar TYPE
852+.Pf ( Dq RSA
853+or
854+.Dq DSA )
855+and bit length
856+.Ar LENGTH .
857+The format of this file is described above.
858+RSA1 keys are converted to RSA before being checked in the blacklist.
859+Note that the fingerprints of RSA1 keys are computed differently, so you
860+will not be able to find them in the blacklist by hand.
861+.It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH
862+Same as
863+.Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH ,
864+but may be edited by the system administrator to add new blacklist entries.
865+.El
866+.Sh SEE ALSO
867+.Xr ssh-keygen 1 ,
868+.Xr sshd 8
869+.Sh AUTHORS
870+.An -nosplit
871+.An Colin Watson Aq cjwatson@ubuntu.com
872+.Pp
873+Florian Weimer suggested the option to check keys of all users, and the idea
874+of processing
875+.Xr ssh-keyscan 1
876+output.
877diff --git a/ssh-vulnkey.c b/ssh-vulnkey.c
878new file mode 100644
879index 0000000..ca1a5be
880--- /dev/null
881+++ b/ssh-vulnkey.c
882@@ -0,0 +1,386 @@
883+/*
884+ * Copyright (c) 2008 Canonical Ltd. All rights reserved.
885+ *
886+ * Redistribution and use in source and binary forms, with or without
887+ * modification, are permitted provided that the following conditions
888+ * are met:
889+ * 1. Redistributions of source code must retain the above copyright
890+ * notice, this list of conditions and the following disclaimer.
891+ * 2. Redistributions in binary form must reproduce the above copyright
892+ * notice, this list of conditions and the following disclaimer in the
893+ * documentation and/or other materials provided with the distribution.
894+ *
895+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
896+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
897+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
898+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
899+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
900+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
901+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
902+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
903+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
904+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
905+ */
906+
907+#include "includes.h"
908+
909+#include <sys/types.h>
910+#include <sys/stat.h>
911+
912+#include <errno.h>
913+#include <string.h>
914+#include <stdio.h>
915+#include <fcntl.h>
916+#include <unistd.h>
917+
918+#include <openssl/evp.h>
919+
920+#include "xmalloc.h"
921+#include "ssh.h"
922+#include "log.h"
923+#include "key.h"
924+#include "authfile.h"
925+#include "pathnames.h"
926+#include "uidswap.h"
927+#include "misc.h"
928+
929+extern char *__progname;
930+
931+/* Default files to check */
932+static char *default_host_files[] = {
933+ _PATH_HOST_RSA_KEY_FILE,
934+ _PATH_HOST_DSA_KEY_FILE,
935+ _PATH_HOST_KEY_FILE,
936+ NULL
937+};
938+static char *default_files[] = {
939+ _PATH_SSH_CLIENT_ID_RSA,
940+ _PATH_SSH_CLIENT_ID_DSA,
941+ _PATH_SSH_CLIENT_IDENTITY,
942+ _PATH_SSH_USER_PERMITTED_KEYS,
943+ _PATH_SSH_USER_PERMITTED_KEYS2,
944+ NULL
945+};
946+
947+static int verbosity = 0;
948+
949+static int some_keys = 0;
950+static int some_unknown = 0;
951+static int some_compromised = 0;
952+
953+static void
954+usage(void)
955+{
956+ fprintf(stderr, "usage: %s [-aqv] [file ...]\n", __progname);
957+ fprintf(stderr, "Options:\n");
958+ fprintf(stderr, " -a Check keys of all users.\n");
959+ fprintf(stderr, " -q Quiet mode.\n");
960+ fprintf(stderr, " -v Verbose mode.\n");
961+ exit(1);
962+}
963+
964+static void
965+describe_key(const char *filename, u_long linenum, const char *msg,
966+ Key *key, const char *comment, int min_verbosity)
967+{
968+ char *fp;
969+
970+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
971+ if (verbosity >= min_verbosity) {
972+ if (strchr(filename, ':'))
973+ printf("\"%s\"", filename);
974+ else
975+ printf("%s", filename);
976+ printf(":%lu: %s: %s %u %s %s\n", linenum, msg,
977+ key_type(key), key_size(key), fp, comment);
978+ }
979+ free(fp);
980+}
981+
982+static int
983+do_key(const char *filename, u_long linenum,
984+ Key *key, const char *comment)
985+{
986+ Key *public;
987+ int blacklist_status;
988+ int ret = 1;
989+
990+ some_keys = 1;
991+
992+ public = key_demote(key);
993+ if (public->type == KEY_RSA1)
994+ public->type = KEY_RSA;
995+
996+ blacklist_status = blacklisted_key(public, NULL);
997+ if (blacklist_status == -1) {
998+ describe_key(filename, linenum,
999+ "Unknown (blacklist file not installed)", key, comment, 0);
1000+ some_unknown = 1;
1001+ } else if (blacklist_status == 1) {
1002+ describe_key(filename, linenum,
1003+ "COMPROMISED", key, comment, 0);
1004+ some_compromised = 1;
1005+ ret = 0;
1006+ } else
1007+ describe_key(filename, linenum,
1008+ "Not blacklisted", key, comment, 1);
1009+
1010+ key_free(public);
1011+
1012+ return ret;
1013+}
1014+
1015+static int
1016+do_filename(const char *filename, int quiet_open)
1017+{
1018+ FILE *f;
1019+ char line[SSH_MAX_PUBKEY_BYTES];
1020+ char *cp;
1021+ u_long linenum = 0;
1022+ Key *key;
1023+ char *comment = NULL;
1024+ int found = 0, ret = 1;
1025+
1026+ /* Copy much of key_load_public's logic here so that we can read
1027+ * several keys from a single file (e.g. authorized_keys).
1028+ */
1029+
1030+ if (strcmp(filename, "-") != 0) {
1031+ int save_errno;
1032+ f = fopen(filename, "r");
1033+ save_errno = errno;
1034+ if (!f) {
1035+ char pubfile[MAXPATHLEN];
1036+ if (strlcpy(pubfile, filename, sizeof pubfile) <
1037+ sizeof(pubfile) &&
1038+ strlcat(pubfile, ".pub", sizeof pubfile) <
1039+ sizeof(pubfile))
1040+ f = fopen(pubfile, "r");
1041+ }
1042+ errno = save_errno; /* earlier errno is more useful */
1043+ if (!f) {
1044+ if (!quiet_open)
1045+ perror(filename);
1046+ return -1;
1047+ }
1048+ if (verbosity > 0)
1049+ printf("# %s\n", filename);
1050+ } else
1051+ f = stdin;
1052+ while (read_keyfile_line(f, filename, line, sizeof(line),
1053+ &linenum) != -1) {
1054+ int i;
1055+ char *space;
1056+ int type;
1057+ char *end;
1058+
1059+ /* Chop trailing newline. */
1060+ i = strlen(line) - 1;
1061+ if (line[i] == '\n')
1062+ line[i] = '\0';
1063+
1064+ /* Skip leading whitespace, empty and comment lines. */
1065+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
1066+ ;
1067+ if (!*cp || *cp == '\n' || *cp == '#')
1068+ continue;
1069+
1070+ /* Cope with ssh-keyscan output and options in
1071+ * authorized_keys files.
1072+ */
1073+ space = strchr(cp, ' ');
1074+ if (!space)
1075+ continue;
1076+ *space = '\0';
1077+ type = key_type_from_name(cp);
1078+ *space = ' ';
1079+ /* Leading number (RSA1) or valid type (RSA/DSA) indicates
1080+ * that we have no host name or options to skip.
1081+ */
1082+ if ((strtol(cp, &end, 10) == 0 || *end != ' ') &&
1083+ type == KEY_UNSPEC) {
1084+ int quoted = 0;
1085+
1086+ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
1087+ if (*cp == '\\' && cp[1] == '"')
1088+ cp++; /* Skip both */
1089+ else if (*cp == '"')
1090+ quoted = !quoted;
1091+ }
1092+ /* Skip remaining whitespace. */
1093+ for (; *cp == ' ' || *cp == '\t'; cp++)
1094+ ;
1095+ if (!*cp)
1096+ continue;
1097+ }
1098+
1099+ /* Read and process the key itself. */
1100+ key = key_new(KEY_RSA1);
1101+ if (key_read(key, &cp) == 1) {
1102+ while (*cp == ' ' || *cp == '\t')
1103+ cp++;
1104+ if (!do_key(filename, linenum,
1105+ key, *cp ? cp : filename))
1106+ ret = 0;
1107+ found = 1;
1108+ } else {
1109+ key_free(key);
1110+ key = key_new(KEY_UNSPEC);
1111+ if (key_read(key, &cp) == 1) {
1112+ while (*cp == ' ' || *cp == '\t')
1113+ cp++;
1114+ if (!do_key(filename, linenum,
1115+ key, *cp ? cp : filename))
1116+ ret = 0;
1117+ found = 1;
1118+ }
1119+ }
1120+ key_free(key);
1121+ }
1122+ if (f != stdin)
1123+ fclose(f);
1124+
1125+ if (!found && filename) {
1126+ key = key_load_public(filename, &comment);
1127+ if (key) {
1128+ if (!do_key(filename, 1, key, comment))
1129+ ret = 0;
1130+ found = 1;
1131+ }
1132+ free(comment);
1133+ }
1134+
1135+ return ret;
1136+}
1137+
1138+static int
1139+do_host(int quiet_open)
1140+{
1141+ int i;
1142+ struct stat st;
1143+ int ret = 1;
1144+
1145+ for (i = 0; default_host_files[i]; i++) {
1146+ if (stat(default_host_files[i], &st) < 0 && errno == ENOENT)
1147+ continue;
1148+ if (!do_filename(default_host_files[i], quiet_open))
1149+ ret = 0;
1150+ }
1151+
1152+ return ret;
1153+}
1154+
1155+static int
1156+do_user(const char *dir)
1157+{
1158+ int i;
1159+ char *file;
1160+ struct stat st;
1161+ int ret = 1;
1162+
1163+ for (i = 0; default_files[i]; i++) {
1164+ xasprintf(&file, "%s/%s", dir, default_files[i]);
1165+ if (stat(file, &st) < 0 && errno == ENOENT) {
1166+ free(file);
1167+ continue;
1168+ }
1169+ if (!do_filename(file, 0))
1170+ ret = 0;
1171+ free(file);
1172+ }
1173+
1174+ return ret;
1175+}
1176+
1177+int
1178+main(int argc, char **argv)
1179+{
1180+ int opt, all_users = 0;
1181+ int ret = 1;
1182+ extern int optind;
1183+
1184+ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
1185+ sanitise_stdfd();
1186+
1187+ __progname = ssh_get_progname(argv[0]);
1188+
1189+ SSLeay_add_all_algorithms();
1190+ log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
1191+
1192+ /* We don't need the RNG ourselves, but symbol references here allow
1193+ * ld to link us properly.
1194+ */
1195+ seed_rng();
1196+
1197+ while ((opt = getopt(argc, argv, "ahqv")) != -1) {
1198+ switch (opt) {
1199+ case 'a':
1200+ all_users = 1;
1201+ break;
1202+ case 'q':
1203+ verbosity--;
1204+ break;
1205+ case 'v':
1206+ verbosity++;
1207+ break;
1208+ case 'h':
1209+ default:
1210+ usage();
1211+ }
1212+ }
1213+
1214+ if (all_users) {
1215+ struct passwd *pw;
1216+
1217+ if (!do_host(0))
1218+ ret = 0;
1219+
1220+ while ((pw = getpwent()) != NULL) {
1221+ if (pw->pw_dir) {
1222+ temporarily_use_uid(pw);
1223+ if (!do_user(pw->pw_dir))
1224+ ret = 0;
1225+ restore_uid();
1226+ }
1227+ }
1228+ } else if (optind == argc) {
1229+ struct passwd *pw;
1230+
1231+ if (!do_host(1))
1232+ ret = 0;
1233+
1234+ if ((pw = getpwuid(geteuid())) == NULL)
1235+ fprintf(stderr, "No user found with uid %u\n",
1236+ (u_int)geteuid());
1237+ else {
1238+ if (!do_user(pw->pw_dir))
1239+ ret = 0;
1240+ }
1241+ } else {
1242+ while (optind < argc)
1243+ if (!do_filename(argv[optind++], 0))
1244+ ret = 0;
1245+ }
1246+
1247+ if (verbosity >= 0) {
1248+ if (some_unknown) {
1249+ printf("#\n");
1250+ printf("# The status of some keys on your system is unknown.\n");
1251+ printf("# You may need to install additional blacklist files.\n");
1252+ }
1253+ if (some_compromised) {
1254+ printf("#\n");
1255+ printf("# Some keys on your system have been compromised!\n");
1256+ printf("# You must replace them using ssh-keygen(1).\n");
1257+ }
1258+ if (some_unknown || some_compromised) {
1259+ printf("#\n");
1260+ printf("# See the ssh-vulnkey(1) manual page for further advice.\n");
1261+ } else if (some_keys && verbosity > 0) {
1262+ printf("#\n");
1263+ printf("# No blacklisted keys!\n");
1264+ }
1265+ }
1266+
1267+ return ret;
1268+}
1269diff --git a/ssh.1 b/ssh.1
1270index 62292cc..66a7007 100644
1271--- a/ssh.1
1272+++ b/ssh.1
1273@@ -1447,6 +1447,7 @@ if an error occurred.
1274 .Xr ssh-agent 1 ,
1275 .Xr ssh-keygen 1 ,
1276 .Xr ssh-keyscan 1 ,
1277+.Xr ssh-vulnkey 1 ,
1278 .Xr tun 4 ,
1279 .Xr hosts.equiv 5 ,
1280 .Xr ssh_config 5 ,
1281diff --git a/ssh.c b/ssh.c
1282index 87233bc..567248d 100644
1283--- a/ssh.c
1284+++ b/ssh.c
1285@@ -1525,7 +1525,7 @@ ssh_session2(void)
1286 static void
1287 load_public_identity_files(void)
1288 {
1289- char *filename, *cp, thishost[NI_MAXHOST];
1290+ char *filename, *cp, thishost[NI_MAXHOST], *fp;
1291 char *pwdir = NULL, *pwname = NULL;
1292 int i = 0;
1293 Key *public;
1294@@ -1583,6 +1583,22 @@ load_public_identity_files(void)
1295 public = key_load_public(filename, NULL);
1296 debug("identity file %s type %d", filename,
1297 public ? public->type : -1);
1298+ if (public && blacklisted_key(public, &fp) == 1) {
1299+ if (options.use_blacklisted_keys)
1300+ logit("Public key %s blacklisted (see "
1301+ "ssh-vulnkey(1)); continuing anyway", fp);
1302+ else
1303+ logit("Public key %s blacklisted (see "
1304+ "ssh-vulnkey(1)); refusing to send it",
1305+ fp);
1306+ free(fp);
1307+ if (!options.use_blacklisted_keys) {
1308+ key_free(public);
1309+ free(filename);
1310+ filename = NULL;
1311+ public = NULL;
1312+ }
1313+ }
1314 free(options.identity_files[i]);
1315 identity_files[n_ids] = filename;
1316 identity_keys[n_ids] = public;
1317diff --git a/ssh_config.5 b/ssh_config.5
1318index e72919a..8d806c7 100644
1319--- a/ssh_config.5
1320+++ b/ssh_config.5
1321@@ -1229,6 +1229,23 @@ is not specified, it defaults to
1322 .Dq any .
1323 The default is
1324 .Dq any:any .
1325+.It Cm UseBlacklistedKeys
1326+Specifies whether
1327+.Xr ssh 1
1328+should use keys recorded in its blacklist of known-compromised keys (see
1329+.Xr ssh-vulnkey 1 )
1330+for authentication.
1331+If
1332+.Dq yes ,
1333+then attempts to use compromised keys for authentication will be logged but
1334+accepted.
1335+It is strongly recommended that this be used only to install new authorized
1336+keys on the remote system, and even then only with the utmost care.
1337+If
1338+.Dq no ,
1339+then attempts to use compromised keys for authentication will be prevented.
1340+The default is
1341+.Dq no .
1342 .It Cm UsePrivilegedPort
1343 Specifies whether to use a privileged port for outgoing connections.
1344 The argument must be
1345diff --git a/sshconnect2.c b/sshconnect2.c
1346index 0b13530..93818c9 100644
1347--- a/sshconnect2.c
1348+++ b/sshconnect2.c
1349@@ -1491,6 +1491,8 @@ pubkey_prepare(Authctxt *authctxt)
1350
1351 /* list of keys stored in the filesystem and PKCS#11 */
1352 for (i = 0; i < options.num_identity_files; i++) {
1353+ if (options.identity_files[i] == NULL)
1354+ continue;
1355 key = options.identity_keys[i];
1356 if (key && key->type == KEY_RSA1)
1357 continue;
1358@@ -1608,7 +1610,7 @@ userauth_pubkey(Authctxt *authctxt)
1359 debug("Offering %s public key: %s", key_type(id->key),
1360 id->filename);
1361 sent = send_pubkey_test(authctxt, id);
1362- } else if (id->key == NULL) {
1363+ } else if (id->key == NULL && id->filename) {
1364 debug("Trying private key: %s", id->filename);
1365 id->key = load_identity_file(id->filename,
1366 id->userprovided);
1367diff --git a/sshd.8 b/sshd.8
1368index b0c7ab6..a604429 100644
1369--- a/sshd.8
1370+++ b/sshd.8
1371@@ -954,6 +954,7 @@ The content of this file is not sensitive; it can be world-readable.
1372 .Xr ssh-agent 1 ,
1373 .Xr ssh-keygen 1 ,
1374 .Xr ssh-keyscan 1 ,
1375+.Xr ssh-vulnkey 1 ,
1376 .Xr chroot 2 ,
1377 .Xr hosts_access 5 ,
1378 .Xr login.conf 5 ,
1379diff --git a/sshd.c b/sshd.c
1380index e5c9835..fbe3284 100644
1381--- a/sshd.c
1382+++ b/sshd.c
1383@@ -1688,6 +1688,11 @@ main(int ac, char **av)
1384 sensitive_data.host_pubkeys[i] = NULL;
1385 continue;
1386 }
1387+ if (auth_key_is_revoked(key != NULL ? key : pubkey, 1)) {
1388+ sensitive_data.host_keys[i] = NULL;
1389+ sensitive_data.host_pubkeys[i] = NULL;
1390+ continue;
1391+ }
1392
1393 switch (keytype) {
1394 case KEY_RSA1:
1395diff --git a/sshd_config.5 b/sshd_config.5
1396index 525d9c8..18ec81f 100644
1397--- a/sshd_config.5
1398+++ b/sshd_config.5
1399@@ -885,6 +885,20 @@ are refused if the number of unauthenticated connections reaches
1400 Specifies whether password authentication is allowed.
1401 The default is
1402 .Dq yes .
1403+.It Cm PermitBlacklistedKeys
1404+Specifies whether
1405+.Xr sshd 8
1406+should allow keys recorded in its blacklist of known-compromised keys (see
1407+.Xr ssh-vulnkey 1 ) .
1408+If
1409+.Dq yes ,
1410+then attempts to authenticate with compromised keys will be logged but
1411+accepted.
1412+If
1413+.Dq no ,
1414+then attempts to authenticate with compromised keys will be rejected.
1415+The default is
1416+.Dq no .
1417 .It Cm PermitEmptyPasswords
1418 When password authentication is allowed, it specifies whether the
1419 server allows login to accounts with empty password strings.
diff --git a/debian/patches/ssh1-keepalive.patch b/debian/patches/ssh1-keepalive.patch
index e563bda7c..1ab818a37 100644
--- a/debian/patches/ssh1-keepalive.patch
+++ b/debian/patches/ssh1-keepalive.patch
@@ -1,4 +1,4 @@
1From 4c7ed5c80e5f67277620ac973317cc516b67d0e7 Mon Sep 17 00:00:00 2001 1From 3d498ae4180b8338db5f960865882b3f781aec2a Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:09:51 +0000 3Date: Sun, 9 Feb 2014 16:09:51 +0000
4Subject: Partial server keep-alive implementation for SSH1 4Subject: Partial server keep-alive implementation for SSH1
@@ -57,7 +57,7 @@ index 311dc13..dc76d69 100644
57 server_alive_time = now + options.server_alive_interval; 57 server_alive_time = now + options.server_alive_interval;
58 } 58 }
59diff --git a/ssh_config.5 b/ssh_config.5 59diff --git a/ssh_config.5 b/ssh_config.5
60index 8d806c7..89b25cd 100644 60index e72919a..1fc0a6b 100644
61--- a/ssh_config.5 61--- a/ssh_config.5
62+++ b/ssh_config.5 62+++ b/ssh_config.5
63@@ -1130,7 +1130,10 @@ If, for example, 63@@ -1130,7 +1130,10 @@ If, for example,
diff --git a/debian/patches/syslog-level-silent.patch b/debian/patches/syslog-level-silent.patch
index a1eaa7513..40b26d002 100644
--- a/debian/patches/syslog-level-silent.patch
+++ b/debian/patches/syslog-level-silent.patch
@@ -1,4 +1,4 @@
1From bbddcd71a027a33919f859f35dae800335a2de6a Mon Sep 17 00:00:00 2001 1From b8a355b5db58dc489fca181e333dacf5e14f4f1d Mon Sep 17 00:00:00 2001
2From: Jonathan David Amery <jdamery@ysolde.ucam.org> 2From: Jonathan David Amery <jdamery@ysolde.ucam.org>
3Date: Sun, 9 Feb 2014 16:09:54 +0000 3Date: Sun, 9 Feb 2014 16:09:54 +0000
4Subject: "LogLevel SILENT" compatibility 4Subject: "LogLevel SILENT" compatibility
@@ -33,7 +33,7 @@ index 32e1d2e..53e7b65 100644
33 { "FATAL", SYSLOG_LEVEL_FATAL }, 33 { "FATAL", SYSLOG_LEVEL_FATAL },
34 { "ERROR", SYSLOG_LEVEL_ERROR }, 34 { "ERROR", SYSLOG_LEVEL_ERROR },
35diff --git a/ssh.c b/ssh.c 35diff --git a/ssh.c b/ssh.c
36index 567248d..219a466 100644 36index 87233bc..5502889 100644
37--- a/ssh.c 37--- a/ssh.c
38+++ b/ssh.c 38+++ b/ssh.c
39@@ -740,7 +740,7 @@ main(int ac, char **av) 39@@ -740,7 +740,7 @@ main(int ac, char **av)
diff --git a/debian/patches/user-group-modes.patch b/debian/patches/user-group-modes.patch
index 9382d5086..cfc14523a 100644
--- a/debian/patches/user-group-modes.patch
+++ b/debian/patches/user-group-modes.patch
@@ -1,4 +1,4 @@
1From 7016a7e8a6b854833132db253fd5e392984bd4ea Mon Sep 17 00:00:00 2001 1From 2bb37315c1e077bc176e703fbf0028a1f6315d37 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org> 2From: Colin Watson <cjwatson@debian.org>
3Date: Sun, 9 Feb 2014 16:09:58 +0000 3Date: Sun, 9 Feb 2014 16:09:58 +0000
4Subject: Allow harmless group-writability 4Subject: Allow harmless group-writability
@@ -52,10 +52,10 @@ index 06ae7f0..f202787 100644
52 pw->pw_name, buf); 52 pw->pw_name, buf);
53 auth_debug_add("Bad file modes for %.200s", buf); 53 auth_debug_add("Bad file modes for %.200s", buf);
54diff --git a/auth.c b/auth.c 54diff --git a/auth.c b/auth.c
55index 6662e9a..7f6c6c8 100644 55index 9a36f1d..0c45f09 100644
56--- a/auth.c 56--- a/auth.c
57+++ b/auth.c 57+++ b/auth.c
58@@ -408,8 +408,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, 58@@ -407,8 +407,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
59 user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); 59 user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
60 if (options.strict_modes && 60 if (options.strict_modes &&
61 (stat(user_hostfile, &st) == 0) && 61 (stat(user_hostfile, &st) == 0) &&
@@ -65,7 +65,7 @@ index 6662e9a..7f6c6c8 100644
65 logit("Authentication refused for %.100s: " 65 logit("Authentication refused for %.100s: "
66 "bad owner or modes for %.200s", 66 "bad owner or modes for %.200s",
67 pw->pw_name, user_hostfile); 67 pw->pw_name, user_hostfile);
68@@ -471,8 +470,7 @@ auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, 68@@ -470,8 +469,7 @@ auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
69 snprintf(err, errlen, "%s is not a regular file", buf); 69 snprintf(err, errlen, "%s is not a regular file", buf);
70 return -1; 70 return -1;
71 } 71 }
@@ -75,7 +75,7 @@ index 6662e9a..7f6c6c8 100644
75 snprintf(err, errlen, "bad ownership or modes for file %s", 75 snprintf(err, errlen, "bad ownership or modes for file %s",
76 buf); 76 buf);
77 return -1; 77 return -1;
78@@ -487,8 +485,7 @@ auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, 78@@ -486,8 +484,7 @@ auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
79 strlcpy(buf, cp, sizeof(buf)); 79 strlcpy(buf, cp, sizeof(buf));
80 80
81 if (stat(buf, &st) < 0 || 81 if (stat(buf, &st) < 0 ||
@@ -216,7 +216,7 @@ index a962f15..0b3bee1 100644
216- return 0; 216- return 0;
217-} 217-}
218diff --git a/readconf.c b/readconf.c 218diff --git a/readconf.c b/readconf.c
219index 2dcbf31..389de7d 100644 219index dab7963..c741934 100644
220--- a/readconf.c 220--- a/readconf.c
221+++ b/readconf.c 221+++ b/readconf.c
222@@ -30,6 +30,8 @@ 222@@ -30,6 +30,8 @@
@@ -228,7 +228,7 @@ index 2dcbf31..389de7d 100644
228 #ifdef HAVE_UTIL_H 228 #ifdef HAVE_UTIL_H
229 #include <util.h> 229 #include <util.h>
230 #endif 230 #endif
231@@ -1160,8 +1162,7 @@ read_config_file(const char *filename, const char *host, Options *options, 231@@ -1155,8 +1157,7 @@ read_config_file(const char *filename, const char *host, Options *options,
232 232
233 if (fstat(fileno(f), &sb) == -1) 233 if (fstat(fileno(f), &sb) == -1)
234 fatal("fstat %s: %s", filename, strerror(errno)); 234 fatal("fstat %s: %s", filename, strerror(errno));
@@ -239,7 +239,7 @@ index 2dcbf31..389de7d 100644
239 } 239 }
240 240
241diff --git a/ssh.1 b/ssh.1 241diff --git a/ssh.1 b/ssh.1
242index 66a7007..0b38ae1 100644 242index 62292cc..05ae6ad 100644
243--- a/ssh.1 243--- a/ssh.1
244+++ b/ssh.1 244+++ b/ssh.1
245@@ -1338,6 +1338,8 @@ The file format and configuration options are described in 245@@ -1338,6 +1338,8 @@ The file format and configuration options are described in
@@ -252,10 +252,10 @@ index 66a7007..0b38ae1 100644
252 .It Pa ~/.ssh/environment 252 .It Pa ~/.ssh/environment
253 Contains additional definitions for environment variables; see 253 Contains additional definitions for environment variables; see
254diff --git a/ssh_config.5 b/ssh_config.5 254diff --git a/ssh_config.5 b/ssh_config.5
255index 135d833..1497cfc 100644 255index 6948680..a1e18d2 100644
256--- a/ssh_config.5 256--- a/ssh_config.5
257+++ b/ssh_config.5 257+++ b/ssh_config.5
258@@ -1382,6 +1382,8 @@ The format of this file is described above. 258@@ -1365,6 +1365,8 @@ The format of this file is described above.
259 This file is used by the SSH client. 259 This file is used by the SSH client.
260 Because of the potential for abuse, this file must have strict permissions: 260 Because of the potential for abuse, this file must have strict permissions:
261 read/write for the user, and not accessible by others. 261 read/write for the user, and not accessible by others.
diff --git a/pathnames.h b/pathnames.h
index 47f7867d5..5027fbaed 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -18,10 +18,6 @@
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
25#ifndef _PATH_SSH_PIDDIR 21#ifndef _PATH_SSH_PIDDIR
26#define _PATH_SSH_PIDDIR "/var/run" 22#define _PATH_SSH_PIDDIR "/var/run"
27#endif 23#endif
@@ -48,9 +44,6 @@
48/* Backwards compatibility */ 44/* Backwards compatibility */
49#define _PATH_DH_PRIMES SSHDIR "/primes" 45#define _PATH_DH_PRIMES SSHDIR "/primes"
50 46
51#define _PATH_BLACKLIST _PATH_SSH_DATADIR "/blacklist"
52#define _PATH_BLACKLIST_CONFIG SSHDIR "/blacklist"
53
54#ifndef _PATH_SSH_PROGRAM 47#ifndef _PATH_SSH_PROGRAM
55#define _PATH_SSH_PROGRAM "/usr/bin/ssh" 48#define _PATH_SSH_PROGRAM "/usr/bin/ssh"
56#endif 49#endif
diff --git a/readconf.c b/readconf.c
index 2778176c6..e1e82c5ad 100644
--- a/readconf.c
+++ b/readconf.c
@@ -130,7 +130,6 @@ typedef enum {
130 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 130 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
131 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 131 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
132 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 132 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
133 oUseBlacklistedKeys,
134 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, 133 oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
135 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 134 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
136 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 135 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
@@ -165,7 +164,7 @@ static struct {
165 { "passwordauthentication", oPasswordAuthentication }, 164 { "passwordauthentication", oPasswordAuthentication },
166 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 165 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
167 { "kbdinteractivedevices", oKbdInteractiveDevices }, 166 { "kbdinteractivedevices", oKbdInteractiveDevices },
168 { "useblacklistedkeys", oUseBlacklistedKeys }, 167 { "useblacklistedkeys", oDeprecated },
169 { "rsaauthentication", oRSAAuthentication }, 168 { "rsaauthentication", oRSAAuthentication },
170 { "pubkeyauthentication", oPubkeyAuthentication }, 169 { "pubkeyauthentication", oPubkeyAuthentication },
171 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 170 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
@@ -530,10 +529,6 @@ parse_flag:
530 intptr = &options->challenge_response_authentication; 529 intptr = &options->challenge_response_authentication;
531 goto parse_flag; 530 goto parse_flag;
532 531
533 case oUseBlacklistedKeys:
534 intptr = &options->use_blacklisted_keys;
535 goto parse_flag;
536
537 case oGssAuthentication: 532 case oGssAuthentication:
538 intptr = &options->gss_authentication; 533 intptr = &options->gss_authentication;
539 goto parse_flag; 534 goto parse_flag;
@@ -1222,7 +1217,6 @@ initialize_options(Options * options)
1222 options->kbd_interactive_devices = NULL; 1217 options->kbd_interactive_devices = NULL;
1223 options->rhosts_rsa_authentication = -1; 1218 options->rhosts_rsa_authentication = -1;
1224 options->hostbased_authentication = -1; 1219 options->hostbased_authentication = -1;
1225 options->use_blacklisted_keys = -1;
1226 options->batch_mode = -1; 1220 options->batch_mode = -1;
1227 options->check_host_ip = -1; 1221 options->check_host_ip = -1;
1228 options->strict_host_key_checking = -1; 1222 options->strict_host_key_checking = -1;
@@ -1333,8 +1327,6 @@ fill_default_options(Options * options)
1333 options->rhosts_rsa_authentication = 0; 1327 options->rhosts_rsa_authentication = 0;
1334 if (options->hostbased_authentication == -1) 1328 if (options->hostbased_authentication == -1)
1335 options->hostbased_authentication = 0; 1329 options->hostbased_authentication = 0;
1336 if (options->use_blacklisted_keys == -1)
1337 options->use_blacklisted_keys = 0;
1338 if (options->batch_mode == -1) 1330 if (options->batch_mode == -1)
1339 options->batch_mode = 0; 1331 options->batch_mode = 0;
1340 if (options->check_host_ip == -1) 1332 if (options->check_host_ip == -1)
diff --git a/readconf.h b/readconf.h
index a508151f7..675b35dfe 100644
--- a/readconf.h
+++ b/readconf.h
@@ -59,7 +59,6 @@ typedef struct {
59 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ 59 int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
60 char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ 60 char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */
61 int zero_knowledge_password_authentication; /* Try jpake */ 61 int zero_knowledge_password_authentication; /* Try jpake */
62 int use_blacklisted_keys; /* If true, send */
63 int batch_mode; /* Batch mode: do not ask for passwords. */ 62 int batch_mode; /* Batch mode: do not ask for passwords. */
64 int check_host_ip; /* Also keep track of keys for IP address */ 63 int check_host_ip; /* Also keep track of keys for IP address */
65 int strict_host_key_checking; /* Strict host key checking. */ 64 int strict_host_key_checking; /* Strict host key checking. */
diff --git a/servconf.c b/servconf.c
index a2928ff57..802db1d79 100644
--- a/servconf.c
+++ b/servconf.c
@@ -114,7 +114,6 @@ initialize_server_options(ServerOptions *options)
114 options->password_authentication = -1; 114 options->password_authentication = -1;
115 options->kbd_interactive_authentication = -1; 115 options->kbd_interactive_authentication = -1;
116 options->challenge_response_authentication = -1; 116 options->challenge_response_authentication = -1;
117 options->permit_blacklisted_keys = -1;
118 options->permit_empty_passwd = -1; 117 options->permit_empty_passwd = -1;
119 options->permit_user_env = -1; 118 options->permit_user_env = -1;
120 options->use_login = -1; 119 options->use_login = -1;
@@ -259,8 +258,6 @@ fill_default_server_options(ServerOptions *options)
259 options->kbd_interactive_authentication = 0; 258 options->kbd_interactive_authentication = 0;
260 if (options->challenge_response_authentication == -1) 259 if (options->challenge_response_authentication == -1)
261 options->challenge_response_authentication = 1; 260 options->challenge_response_authentication = 1;
262 if (options->permit_blacklisted_keys == -1)
263 options->permit_blacklisted_keys = 0;
264 if (options->permit_empty_passwd == -1) 261 if (options->permit_empty_passwd == -1)
265 options->permit_empty_passwd = 0; 262 options->permit_empty_passwd = 0;
266 if (options->permit_user_env == -1) 263 if (options->permit_user_env == -1)
@@ -344,7 +341,7 @@ typedef enum {
344 sListenAddress, sAddressFamily, 341 sListenAddress, sAddressFamily,
345 sPrintMotd, sPrintLastLog, sIgnoreRhosts, 342 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
346 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, 343 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
347 sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive, 344 sStrictModes, sEmptyPasswd, sTCPKeepAlive,
348 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, 345 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
349 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 346 sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
350 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 347 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@@ -458,7 +455,7 @@ static struct {
458 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, 455 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
459 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, 456 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
460 { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, 457 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
461 { "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL }, 458 { "permitblacklistedkeys", sDeprecated, SSHCFG_GLOBAL },
462 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, 459 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
463 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, 460 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
464 { "uselogin", sUseLogin, SSHCFG_GLOBAL }, 461 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
@@ -1167,10 +1164,6 @@ process_server_config_line(ServerOptions *options, char *line,
1167 intptr = &options->tcp_keep_alive; 1164 intptr = &options->tcp_keep_alive;
1168 goto parse_flag; 1165 goto parse_flag;
1169 1166
1170 case sPermitBlacklistedKeys:
1171 intptr = &options->permit_blacklisted_keys;
1172 goto parse_flag;
1173
1174 case sEmptyPasswd: 1167 case sEmptyPasswd:
1175 intptr = &options->permit_empty_passwd; 1168 intptr = &options->permit_empty_passwd;
1176 goto parse_flag; 1169 goto parse_flag;
@@ -2053,7 +2046,6 @@ dump_config(ServerOptions *o)
2053 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); 2046 dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
2054 dump_cfg_fmtint(sStrictModes, o->strict_modes); 2047 dump_cfg_fmtint(sStrictModes, o->strict_modes);
2055 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); 2048 dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
2056 dump_cfg_fmtint(sPermitBlacklistedKeys, o->permit_blacklisted_keys);
2057 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); 2049 dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
2058 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); 2050 dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
2059 dump_cfg_fmtint(sUseLogin, o->use_login); 2051 dump_cfg_fmtint(sUseLogin, o->use_login);
diff --git a/servconf.h b/servconf.h
index fd72ce2a3..1891a95a1 100644
--- a/servconf.h
+++ b/servconf.h
@@ -121,7 +121,6 @@ typedef struct {
121 int challenge_response_authentication; 121 int challenge_response_authentication;
122 int zero_knowledge_password_authentication; 122 int zero_knowledge_password_authentication;
123 /* If true, permit jpake auth */ 123 /* If true, permit jpake auth */
124 int permit_blacklisted_keys; /* If true, permit */
125 int permit_empty_passwd; /* If false, do not permit empty 124 int permit_empty_passwd; /* If false, do not permit empty
126 * passwords. */ 125 * passwords. */
127 int permit_user_env; /* If true, read ~/.ssh/environment */ 126 int permit_user_env; /* If true, read ~/.ssh/environment */
diff --git a/ssh-add.1 b/ssh-add.1
index d394b2696..44846b67e 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -81,10 +81,6 @@ environment variable must contain the name of its socket for
81.Nm 81.Nm
82to work. 82to work.
83.Pp 83.Pp
84Any keys recorded in the blacklist of known-compromised keys (see
85.Xr ssh-vulnkey 1 )
86will be refused.
87.Pp
88The options are as follows: 84The options are as follows:
89.Bl -tag -width Ds 85.Bl -tag -width Ds
90.It Fl c 86.It Fl c
@@ -190,7 +186,6 @@ is unable to contact the authentication agent.
190.Xr ssh 1 , 186.Xr ssh 1 ,
191.Xr ssh-agent 1 , 187.Xr ssh-agent 1 ,
192.Xr ssh-keygen 1 , 188.Xr ssh-keygen 1 ,
193.Xr ssh-vulnkey 1 ,
194.Xr sshd 8 189.Xr sshd 8
195.Sh AUTHORS 190.Sh AUTHORS
196OpenSSH is a derivative of the original and free 191OpenSSH is a derivative of the original and free
diff --git a/ssh-add.c b/ssh-add.c
index b309582f5..5e8166f66 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -167,7 +167,7 @@ static int
167add_file(AuthenticationConnection *ac, const char *filename, int key_only) 167add_file(AuthenticationConnection *ac, const char *filename, int key_only)
168{ 168{
169 Key *private, *cert; 169 Key *private, *cert;
170 char *comment = NULL, *fp; 170 char *comment = NULL;
171 char msg[1024], *certpath = NULL; 171 char msg[1024], *certpath = NULL;
172 int fd, perms_ok, ret = -1; 172 int fd, perms_ok, ret = -1;
173 Buffer keyblob; 173 Buffer keyblob;
@@ -243,14 +243,6 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only)
243 } else { 243 } else {
244 fprintf(stderr, "Could not add identity: %s\n", filename); 244 fprintf(stderr, "Could not add identity: %s\n", filename);
245 } 245 }
246 if (blacklisted_key(private, &fp) == 1) {
247 fprintf(stderr, "Public key %s blacklisted (see "
248 "ssh-vulnkey(1)); refusing to add it\n", fp);
249 free(fp);
250 key_free(private);
251 free(comment);
252 return -1;
253 }
254 246
255 /* Skip trying to load the cert if requested */ 247 /* Skip trying to load the cert if requested */
256 if (key_only) 248 if (key_only)
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 753cc625b..151cab0ef 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -805,7 +805,6 @@ The file format is described in
805.Xr ssh 1 , 805.Xr ssh 1 ,
806.Xr ssh-add 1 , 806.Xr ssh-add 1 ,
807.Xr ssh-agent 1 , 807.Xr ssh-agent 1 ,
808.Xr ssh-vulnkey 1 ,
809.Xr moduli 5 , 808.Xr moduli 5 ,
810.Xr sshd 8 809.Xr sshd 8
811.Rs 810.Rs
diff --git a/ssh-vulnkey.1 b/ssh-vulnkey.1
deleted file mode 100644
index bcb9d31c6..000000000
--- a/ssh-vulnkey.1
+++ /dev/null
@@ -1,242 +0,0 @@
1.\" Copyright (c) 2008 Canonical Ltd. All rights reserved.
2.\"
3.\" Redistribution and use in source and binary forms, with or without
4.\" modification, are permitted provided that the following conditions
5.\" are met:
6.\" 1. Redistributions of source code must retain the above copyright
7.\" notice, this list of conditions and the following disclaimer.
8.\" 2. Redistributions in binary form must reproduce the above copyright
9.\" notice, this list of conditions and the following disclaimer in the
10.\" documentation and/or other materials provided with the distribution.
11.\"
12.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
13.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22.\"
23.Dd $Mdocdate: May 12 2008 $
24.Dt SSH-VULNKEY 1
25.Os
26.Sh NAME
27.Nm ssh-vulnkey
28.Nd check blacklist of compromised keys
29.Sh SYNOPSIS
30.Nm
31.Op Fl q | Fl v
32.Ar file ...
33.Nm
34.Fl a
35.Sh DESCRIPTION
36.Nm
37checks a key against a blacklist of compromised keys.
38.Pp
39A substantial number of keys are known to have been generated using a broken
40version of OpenSSL distributed by Debian which failed to seed its random
41number generator correctly.
42Keys generated using these OpenSSL versions should be assumed to be
43compromised.
44This tool may be useful in checking for such keys.
45.Pp
46Keys that are compromised cannot be repaired; replacements must be generated
47using
48.Xr ssh-keygen 1 .
49Make sure to update
50.Pa authorized_keys
51files on all systems where compromised keys were permitted to authenticate.
52.Pp
53The argument list will be interpreted as a list of paths to public key files
54or
55.Pa authorized_keys
56files.
57If no suitable file is found at a given path,
58.Nm
59will append
60.Pa .pub
61and retry, in case it was given a private key file.
62If no files are given as arguments,
63.Nm
64will check
65.Pa ~/.ssh/id_rsa ,
66.Pa ~/.ssh/id_dsa ,
67.Pa ~/.ssh/identity ,
68.Pa ~/.ssh/authorized_keys
69and
70.Pa ~/.ssh/authorized_keys2 ,
71as well as the system's host keys if readable.
72.Pp
73If
74.Dq -
75is given as an argument,
76.Nm
77will read from standard input.
78This can be used to process output from
79.Xr ssh-keyscan 1 ,
80for example:
81.Pp
82.Dl $ ssh-keyscan -t rsa remote.example.org | ssh-vulnkey -
83.Pp
84Unless the
85.Cm PermitBlacklistedKeys
86option is used,
87.Xr sshd 8
88will reject attempts to authenticate with keys in the compromised list.
89.Pp
90The output from
91.Nm
92looks like this:
93.Pp
94.Bd -literal -offset indent
95/etc/ssh/ssh_host_key:1: COMPROMISED: RSA1 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx root@host
96/home/user/.ssh/id_dsa:1: Not blacklisted: DSA 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx /home/user/.ssh/id_dsa.pub
97/home/user/.ssh/authorized_keys:3: Unknown (blacklist file not installed): RSA 1024 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx user@host
98.Ed
99.Pp
100Each line is of the following format (any lines beginning with
101.Dq #
102should be ignored by scripts):
103.Pp
104.Dl Ar filename : Ns Ar line : Ar status : Ar type Ar size Ar fingerprint Ar comment
105.Pp
106It is important to distinguish between the possible values of
107.Ar status :
108.Pp
109.Bl -tag -width Ds
110.It COMPROMISED
111These keys are listed in a blacklist file, normally because their
112corresponding private keys are well-known.
113Replacements must be generated using
114.Xr ssh-keygen 1 .
115.It Not blacklisted
116A blacklist file exists for this key type and size, but this key is not
117listed in it.
118Unless there is some particular reason to believe otherwise, this key
119may be used safely.
120(Note that DSA keys used with the broken version of OpenSSL distributed
121by Debian may be compromised in the event that anyone captured a network
122trace, even if they were generated with a secure version of OpenSSL.)
123.It Unknown (blacklist file not installed)
124No blacklist file exists for this key type and size.
125You should find a suitable published blacklist and install it before
126deciding whether this key is safe to use.
127.El
128.Pp
129The options are as follows:
130.Bl -tag -width Ds
131.It Fl a
132Check keys of all users on the system.
133You will typically need to run
134.Nm
135as root to use this option.
136For each user,
137.Nm
138will check
139.Pa ~/.ssh/id_rsa ,
140.Pa ~/.ssh/id_dsa ,
141.Pa ~/.ssh/identity ,
142.Pa ~/.ssh/authorized_keys
143and
144.Pa ~/.ssh/authorized_keys2 .
145It will also check the system's host keys.
146.It Fl q
147Quiet mode.
148Normally,
149.Nm
150outputs the fingerprint of each key scanned, with a description of its
151status.
152This option suppresses that output.
153.It Fl v
154Verbose mode.
155Normally,
156.Nm
157does not output anything for keys that are not listed in their corresponding
158blacklist file (although it still produces output for keys for which there
159is no blacklist file, since their status is unknown).
160This option causes
161.Nm
162to produce output for all keys.
163.El
164.Sh EXIT STATUS
165.Nm
166will exit zero if any of the given keys were in the compromised list,
167otherwise non-zero.
168.Sh BLACKLIST FILE FORMAT
169The blacklist file may start with comments, on lines starting with
170.Dq # .
171After these initial comments, it must follow a strict format:
172.Pp
173.Bl -bullet -offset indent -compact
174.It
175All the lines must be exactly the same length (20 characters followed by a
176newline) and must be in sorted order.
177.It
178Each line must consist of the lower-case hexadecimal MD5 key fingerprint,
179without colons, and with the first 12 characters removed (that is, the least
180significant 80 bits of the fingerprint).
181.El
182.Pp
183The key fingerprint may be generated using
184.Xr ssh-keygen 1 :
185.Pp
186.Dl $ ssh-keygen -l -f /path/to/key
187.Pp
188This strict format is necessary to allow the blacklist file to be checked
189quickly, using a binary-search algorithm.
190.Sh FILES
191.Bl -tag -width Ds
192.It Pa ~/.ssh/id_rsa
193If present, contains the protocol version 2 RSA authentication identity of
194the user.
195.It Pa ~/.ssh/id_dsa
196If present, contains the protocol version 2 DSA authentication identity of
197the user.
198.It Pa ~/.ssh/identity
199If present, contains the protocol version 1 RSA authentication identity of
200the user.
201.It Pa ~/.ssh/authorized_keys
202If present, lists the public keys (RSA/DSA) that can be used for logging in
203as this user.
204.It Pa ~/.ssh/authorized_keys2
205Obsolete name for
206.Pa ~/.ssh/authorized_keys .
207This file may still be present on some old systems, but should not be
208created if it is missing.
209.It Pa /etc/ssh/ssh_host_rsa_key
210If present, contains the protocol version 2 RSA identity of the system.
211.It Pa /etc/ssh/ssh_host_dsa_key
212If present, contains the protocol version 2 DSA identity of the system.
213.It Pa /etc/ssh/ssh_host_key
214If present, contains the protocol version 1 RSA identity of the system.
215.It Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH
216If present, lists the blacklisted keys of type
217.Ar TYPE
218.Pf ( Dq RSA
219or
220.Dq DSA )
221and bit length
222.Ar LENGTH .
223The format of this file is described above.
224RSA1 keys are converted to RSA before being checked in the blacklist.
225Note that the fingerprints of RSA1 keys are computed differently, so you
226will not be able to find them in the blacklist by hand.
227.It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH
228Same as
229.Pa /usr/share/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH ,
230but may be edited by the system administrator to add new blacklist entries.
231.El
232.Sh SEE ALSO
233.Xr ssh-keygen 1 ,
234.Xr sshd 8
235.Sh AUTHORS
236.An -nosplit
237.An Colin Watson Aq cjwatson@ubuntu.com
238.Pp
239Florian Weimer suggested the option to check keys of all users, and the idea
240of processing
241.Xr ssh-keyscan 1
242output.
diff --git a/ssh-vulnkey.c b/ssh-vulnkey.c
deleted file mode 100644
index ca1a5be74..000000000
--- a/ssh-vulnkey.c
+++ /dev/null
@@ -1,386 +0,0 @@
1/*
2 * Copyright (c) 2008 Canonical Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26
27#include <sys/types.h>
28#include <sys/stat.h>
29
30#include <errno.h>
31#include <string.h>
32#include <stdio.h>
33#include <fcntl.h>
34#include <unistd.h>
35
36#include <openssl/evp.h>
37
38#include "xmalloc.h"
39#include "ssh.h"
40#include "log.h"
41#include "key.h"
42#include "authfile.h"
43#include "pathnames.h"
44#include "uidswap.h"
45#include "misc.h"
46
47extern char *__progname;
48
49/* Default files to check */
50static char *default_host_files[] = {
51 _PATH_HOST_RSA_KEY_FILE,
52 _PATH_HOST_DSA_KEY_FILE,
53 _PATH_HOST_KEY_FILE,
54 NULL
55};
56static char *default_files[] = {
57 _PATH_SSH_CLIENT_ID_RSA,
58 _PATH_SSH_CLIENT_ID_DSA,
59 _PATH_SSH_CLIENT_IDENTITY,
60 _PATH_SSH_USER_PERMITTED_KEYS,
61 _PATH_SSH_USER_PERMITTED_KEYS2,
62 NULL
63};
64
65static int verbosity = 0;
66
67static int some_keys = 0;
68static int some_unknown = 0;
69static int some_compromised = 0;
70
71static void
72usage(void)
73{
74 fprintf(stderr, "usage: %s [-aqv] [file ...]\n", __progname);
75 fprintf(stderr, "Options:\n");
76 fprintf(stderr, " -a Check keys of all users.\n");
77 fprintf(stderr, " -q Quiet mode.\n");
78 fprintf(stderr, " -v Verbose mode.\n");
79 exit(1);
80}
81
82static void
83describe_key(const char *filename, u_long linenum, const char *msg,
84 Key *key, const char *comment, int min_verbosity)
85{
86 char *fp;
87
88 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
89 if (verbosity >= min_verbosity) {
90 if (strchr(filename, ':'))
91 printf("\"%s\"", filename);
92 else
93 printf("%s", filename);
94 printf(":%lu: %s: %s %u %s %s\n", linenum, msg,
95 key_type(key), key_size(key), fp, comment);
96 }
97 free(fp);
98}
99
100static int
101do_key(const char *filename, u_long linenum,
102 Key *key, const char *comment)
103{
104 Key *public;
105 int blacklist_status;
106 int ret = 1;
107
108 some_keys = 1;
109
110 public = key_demote(key);
111 if (public->type == KEY_RSA1)
112 public->type = KEY_RSA;
113
114 blacklist_status = blacklisted_key(public, NULL);
115 if (blacklist_status == -1) {
116 describe_key(filename, linenum,
117 "Unknown (blacklist file not installed)", key, comment, 0);
118 some_unknown = 1;
119 } else if (blacklist_status == 1) {
120 describe_key(filename, linenum,
121 "COMPROMISED", key, comment, 0);
122 some_compromised = 1;
123 ret = 0;
124 } else
125 describe_key(filename, linenum,
126 "Not blacklisted", key, comment, 1);
127
128 key_free(public);
129
130 return ret;
131}
132
133static int
134do_filename(const char *filename, int quiet_open)
135{
136 FILE *f;
137 char line[SSH_MAX_PUBKEY_BYTES];
138 char *cp;
139 u_long linenum = 0;
140 Key *key;
141 char *comment = NULL;
142 int found = 0, ret = 1;
143
144 /* Copy much of key_load_public's logic here so that we can read
145 * several keys from a single file (e.g. authorized_keys).
146 */
147
148 if (strcmp(filename, "-") != 0) {
149 int save_errno;
150 f = fopen(filename, "r");
151 save_errno = errno;
152 if (!f) {
153 char pubfile[MAXPATHLEN];
154 if (strlcpy(pubfile, filename, sizeof pubfile) <
155 sizeof(pubfile) &&
156 strlcat(pubfile, ".pub", sizeof pubfile) <
157 sizeof(pubfile))
158 f = fopen(pubfile, "r");
159 }
160 errno = save_errno; /* earlier errno is more useful */
161 if (!f) {
162 if (!quiet_open)
163 perror(filename);
164 return -1;
165 }
166 if (verbosity > 0)
167 printf("# %s\n", filename);
168 } else
169 f = stdin;
170 while (read_keyfile_line(f, filename, line, sizeof(line),
171 &linenum) != -1) {
172 int i;
173 char *space;
174 int type;
175 char *end;
176
177 /* Chop trailing newline. */
178 i = strlen(line) - 1;
179 if (line[i] == '\n')
180 line[i] = '\0';
181
182 /* Skip leading whitespace, empty and comment lines. */
183 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
184 ;
185 if (!*cp || *cp == '\n' || *cp == '#')
186 continue;
187
188 /* Cope with ssh-keyscan output and options in
189 * authorized_keys files.
190 */
191 space = strchr(cp, ' ');
192 if (!space)
193 continue;
194 *space = '\0';
195 type = key_type_from_name(cp);
196 *space = ' ';
197 /* Leading number (RSA1) or valid type (RSA/DSA) indicates
198 * that we have no host name or options to skip.
199 */
200 if ((strtol(cp, &end, 10) == 0 || *end != ' ') &&
201 type == KEY_UNSPEC) {
202 int quoted = 0;
203
204 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
205 if (*cp == '\\' && cp[1] == '"')
206 cp++; /* Skip both */
207 else if (*cp == '"')
208 quoted = !quoted;
209 }
210 /* Skip remaining whitespace. */
211 for (; *cp == ' ' || *cp == '\t'; cp++)
212 ;
213 if (!*cp)
214 continue;
215 }
216
217 /* Read and process the key itself. */
218 key = key_new(KEY_RSA1);
219 if (key_read(key, &cp) == 1) {
220 while (*cp == ' ' || *cp == '\t')
221 cp++;
222 if (!do_key(filename, linenum,
223 key, *cp ? cp : filename))
224 ret = 0;
225 found = 1;
226 } else {
227 key_free(key);
228 key = key_new(KEY_UNSPEC);
229 if (key_read(key, &cp) == 1) {
230 while (*cp == ' ' || *cp == '\t')
231 cp++;
232 if (!do_key(filename, linenum,
233 key, *cp ? cp : filename))
234 ret = 0;
235 found = 1;
236 }
237 }
238 key_free(key);
239 }
240 if (f != stdin)
241 fclose(f);
242
243 if (!found && filename) {
244 key = key_load_public(filename, &comment);
245 if (key) {
246 if (!do_key(filename, 1, key, comment))
247 ret = 0;
248 found = 1;
249 }
250 free(comment);
251 }
252
253 return ret;
254}
255
256static int
257do_host(int quiet_open)
258{
259 int i;
260 struct stat st;
261 int ret = 1;
262
263 for (i = 0; default_host_files[i]; i++) {
264 if (stat(default_host_files[i], &st) < 0 && errno == ENOENT)
265 continue;
266 if (!do_filename(default_host_files[i], quiet_open))
267 ret = 0;
268 }
269
270 return ret;
271}
272
273static int
274do_user(const char *dir)
275{
276 int i;
277 char *file;
278 struct stat st;
279 int ret = 1;
280
281 for (i = 0; default_files[i]; i++) {
282 xasprintf(&file, "%s/%s", dir, default_files[i]);
283 if (stat(file, &st) < 0 && errno == ENOENT) {
284 free(file);
285 continue;
286 }
287 if (!do_filename(file, 0))
288 ret = 0;
289 free(file);
290 }
291
292 return ret;
293}
294
295int
296main(int argc, char **argv)
297{
298 int opt, all_users = 0;
299 int ret = 1;
300 extern int optind;
301
302 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
303 sanitise_stdfd();
304
305 __progname = ssh_get_progname(argv[0]);
306
307 SSLeay_add_all_algorithms();
308 log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
309
310 /* We don't need the RNG ourselves, but symbol references here allow
311 * ld to link us properly.
312 */
313 seed_rng();
314
315 while ((opt = getopt(argc, argv, "ahqv")) != -1) {
316 switch (opt) {
317 case 'a':
318 all_users = 1;
319 break;
320 case 'q':
321 verbosity--;
322 break;
323 case 'v':
324 verbosity++;
325 break;
326 case 'h':
327 default:
328 usage();
329 }
330 }
331
332 if (all_users) {
333 struct passwd *pw;
334
335 if (!do_host(0))
336 ret = 0;
337
338 while ((pw = getpwent()) != NULL) {
339 if (pw->pw_dir) {
340 temporarily_use_uid(pw);
341 if (!do_user(pw->pw_dir))
342 ret = 0;
343 restore_uid();
344 }
345 }
346 } else if (optind == argc) {
347 struct passwd *pw;
348
349 if (!do_host(1))
350 ret = 0;
351
352 if ((pw = getpwuid(geteuid())) == NULL)
353 fprintf(stderr, "No user found with uid %u\n",
354 (u_int)geteuid());
355 else {
356 if (!do_user(pw->pw_dir))
357 ret = 0;
358 }
359 } else {
360 while (optind < argc)
361 if (!do_filename(argv[optind++], 0))
362 ret = 0;
363 }
364
365 if (verbosity >= 0) {
366 if (some_unknown) {
367 printf("#\n");
368 printf("# The status of some keys on your system is unknown.\n");
369 printf("# You may need to install additional blacklist files.\n");
370 }
371 if (some_compromised) {
372 printf("#\n");
373 printf("# Some keys on your system have been compromised!\n");
374 printf("# You must replace them using ssh-keygen(1).\n");
375 }
376 if (some_unknown || some_compromised) {
377 printf("#\n");
378 printf("# See the ssh-vulnkey(1) manual page for further advice.\n");
379 } else if (some_keys && verbosity > 0) {
380 printf("#\n");
381 printf("# No blacklisted keys!\n");
382 }
383 }
384
385 return ret;
386}
diff --git a/ssh.1 b/ssh.1
index c0cc12f43..63b057336 100644
--- a/ssh.1
+++ b/ssh.1
@@ -1454,7 +1454,6 @@ if an error occurred.
1454.Xr ssh-argv0 1 , 1454.Xr ssh-argv0 1 ,
1455.Xr ssh-keygen 1 , 1455.Xr ssh-keygen 1 ,
1456.Xr ssh-keyscan 1 , 1456.Xr ssh-keyscan 1 ,
1457.Xr ssh-vulnkey 1 ,
1458.Xr tun 4 , 1457.Xr tun 4 ,
1459.Xr hosts.equiv 5 , 1458.Xr hosts.equiv 5 ,
1460.Xr ssh_config 5 , 1459.Xr ssh_config 5 ,
diff --git a/ssh.c b/ssh.c
index 219a46677..550288919 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1525,7 +1525,7 @@ ssh_session2(void)
1525static void 1525static void
1526load_public_identity_files(void) 1526load_public_identity_files(void)
1527{ 1527{
1528 char *filename, *cp, thishost[NI_MAXHOST], *fp; 1528 char *filename, *cp, thishost[NI_MAXHOST];
1529 char *pwdir = NULL, *pwname = NULL; 1529 char *pwdir = NULL, *pwname = NULL;
1530 int i = 0; 1530 int i = 0;
1531 Key *public; 1531 Key *public;
@@ -1583,22 +1583,6 @@ load_public_identity_files(void)
1583 public = key_load_public(filename, NULL); 1583 public = key_load_public(filename, NULL);
1584 debug("identity file %s type %d", filename, 1584 debug("identity file %s type %d", filename,
1585 public ? public->type : -1); 1585 public ? public->type : -1);
1586 if (public && blacklisted_key(public, &fp) == 1) {
1587 if (options.use_blacklisted_keys)
1588 logit("Public key %s blacklisted (see "
1589 "ssh-vulnkey(1)); continuing anyway", fp);
1590 else
1591 logit("Public key %s blacklisted (see "
1592 "ssh-vulnkey(1)); refusing to send it",
1593 fp);
1594 free(fp);
1595 if (!options.use_blacklisted_keys) {
1596 key_free(public);
1597 free(filename);
1598 filename = NULL;
1599 public = NULL;
1600 }
1601 }
1602 free(options.identity_files[i]); 1586 free(options.identity_files[i]);
1603 identity_files[n_ids] = filename; 1587 identity_files[n_ids] = filename;
1604 identity_keys[n_ids] = public; 1588 identity_keys[n_ids] = public;
diff --git a/ssh_config.5 b/ssh_config.5
index 127540a60..01e7b6f23 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -1269,23 +1269,6 @@ is not specified, it defaults to
1269.Dq any . 1269.Dq any .
1270The default is 1270The default is
1271.Dq any:any . 1271.Dq any:any .
1272.It Cm UseBlacklistedKeys
1273Specifies whether
1274.Xr ssh 1
1275should use keys recorded in its blacklist of known-compromised keys (see
1276.Xr ssh-vulnkey 1 )
1277for authentication.
1278If
1279.Dq yes ,
1280then attempts to use compromised keys for authentication will be logged but
1281accepted.
1282It is strongly recommended that this be used only to install new authorized
1283keys on the remote system, and even then only with the utmost care.
1284If
1285.Dq no ,
1286then attempts to use compromised keys for authentication will be prevented.
1287The default is
1288.Dq no .
1289.It Cm UsePrivilegedPort 1272.It Cm UsePrivilegedPort
1290Specifies whether to use a privileged port for outgoing connections. 1273Specifies whether to use a privileged port for outgoing connections.
1291The argument must be 1274The argument must be
diff --git a/sshconnect2.c b/sshconnect2.c
index 93818c991..0b13530ce 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1491,8 +1491,6 @@ pubkey_prepare(Authctxt *authctxt)
1491 1491
1492 /* list of keys stored in the filesystem and PKCS#11 */ 1492 /* list of keys stored in the filesystem and PKCS#11 */
1493 for (i = 0; i < options.num_identity_files; i++) { 1493 for (i = 0; i < options.num_identity_files; i++) {
1494 if (options.identity_files[i] == NULL)
1495 continue;
1496 key = options.identity_keys[i]; 1494 key = options.identity_keys[i];
1497 if (key && key->type == KEY_RSA1) 1495 if (key && key->type == KEY_RSA1)
1498 continue; 1496 continue;
@@ -1610,7 +1608,7 @@ userauth_pubkey(Authctxt *authctxt)
1610 debug("Offering %s public key: %s", key_type(id->key), 1608 debug("Offering %s public key: %s", key_type(id->key),
1611 id->filename); 1609 id->filename);
1612 sent = send_pubkey_test(authctxt, id); 1610 sent = send_pubkey_test(authctxt, id);
1613 } else if (id->key == NULL && id->filename) { 1611 } else if (id->key == NULL) {
1614 debug("Trying private key: %s", id->filename); 1612 debug("Trying private key: %s", id->filename);
1615 id->key = load_identity_file(id->filename, 1613 id->key = load_identity_file(id->filename,
1616 id->userprovided); 1614 id->userprovided);
diff --git a/sshd.8 b/sshd.8
index b91f08cff..8e4017b4e 100644
--- a/sshd.8
+++ b/sshd.8
@@ -957,7 +957,6 @@ The content of this file is not sensitive; it can be world-readable.
957.Xr ssh-agent 1 , 957.Xr ssh-agent 1 ,
958.Xr ssh-keygen 1 , 958.Xr ssh-keygen 1 ,
959.Xr ssh-keyscan 1 , 959.Xr ssh-keyscan 1 ,
960.Xr ssh-vulnkey 1 ,
961.Xr chroot 2 , 960.Xr chroot 2 ,
962.Xr hosts_access 5 , 961.Xr hosts_access 5 ,
963.Xr moduli 5 , 962.Xr moduli 5 ,
diff --git a/sshd.c b/sshd.c
index 72e9eaf47..fd7f182a4 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1689,11 +1689,6 @@ main(int ac, char **av)
1689 sensitive_data.host_pubkeys[i] = NULL; 1689 sensitive_data.host_pubkeys[i] = NULL;
1690 continue; 1690 continue;
1691 } 1691 }
1692 if (auth_key_is_revoked(key != NULL ? key : pubkey, 1)) {
1693 sensitive_data.host_keys[i] = NULL;
1694 sensitive_data.host_pubkeys[i] = NULL;
1695 continue;
1696 }
1697 1692
1698 switch (keytype) { 1693 switch (keytype) {
1699 case KEY_RSA1: 1694 case KEY_RSA1:
diff --git a/sshd_config.5 b/sshd_config.5
index faf93fc90..ca4cb193a 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -916,20 +916,6 @@ are refused if the number of unauthenticated connections reaches
916Specifies whether password authentication is allowed. 916Specifies whether password authentication is allowed.
917The default is 917The default is
918.Dq yes . 918.Dq yes .
919.It Cm PermitBlacklistedKeys
920Specifies whether
921.Xr sshd 8
922should allow keys recorded in its blacklist of known-compromised keys (see
923.Xr ssh-vulnkey 1 ) .
924If
925.Dq yes ,
926then attempts to authenticate with compromised keys will be logged but
927accepted.
928If
929.Dq no ,
930then attempts to authenticate with compromised keys will be rejected.
931The default is
932.Dq no .
933.It Cm PermitEmptyPasswords 919.It Cm PermitEmptyPasswords
934When password authentication is allowed, it specifies whether the 920When password authentication is allowed, it specifies whether the
935server allows login to accounts with empty password strings. 921server allows login to accounts with empty password strings.