]> git.pld-linux.org Git - packages/openssh.git/blame - openssh-blacklist.diff
- fix ssh-ldap-helper path
[packages/openssh.git] / openssh-blacklist.diff
CommitLineData
a66b6504
JK
1This patch is against OpenSSH 4.7p1, although should apply to other versions
2without too much difficulty. It makes the following changes:
3
4 * Add key blacklisting support. Keys listed in
5 /etc/ssh/blacklist.TYPE-LENGTH will be rejected for authentication by
6 sshd, unless "PermitBlacklistedKeys yes" is set in /etc/ssh/sshd_config.
7
8 * Add a new program, ssh-vulnkey, which can be used to check keys against
9 these blacklists.
10
11This patch is up to date with respect to Debian openssh 1:4.7p1-10.
12
13--- openssh-4.7p1.orig/sshd_config.5
14+++ openssh-4.7p1/sshd_config.5
15@@ -615,6 +615,20 @@
16 Specifies whether password authentication is allowed.
17 The default is
18 .Dq yes .
19+.It Cm PermitBlacklistedKeys
20+Specifies whether
21+.Xr sshd 8
22+should allow keys recorded in its blacklist of known-compromised keys (see
23+.Xr ssh-vulnkey 1 ) .
24+If
25+.Dq yes ,
26+then attempts to authenticate with compromised keys will be logged but
27+accepted.
28+If
29+.Dq no ,
30+then attempts to authenticate with compromised keys will be rejected.
31+The default is
32+.Dq no .
33 .It Cm PermitEmptyPasswords
34 When password authentication is allowed, it specifies whether the
35 server allows login to accounts with empty password strings.
36--- openssh-4.7p1.orig/sshd.c
37+++ openssh-4.7p1/sshd.c
38@@ -1466,6 +1466,21 @@
39
40 for (i = 0; i < options.num_host_key_files; i++) {
41 key = key_load_private(options.host_key_files[i], "", NULL);
42+ if (key && blacklisted_key(key)) {
43+ char *fp;
44+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
45+ if (options.permit_blacklisted_keys)
46+ error("Host key %s blacklisted (see "
47+ "ssh-vulnkey(1)); continuing anyway", fp);
48+ else
49+ error("Host key %s blacklisted (see "
50+ "ssh-vulnkey(1))", fp);
51+ xfree(fp);
52+ if (!options.permit_blacklisted_keys) {
53+ sensitive_data.host_keys[i] = NULL;
54+ continue;
55+ }
56+ }
57 sensitive_data.host_keys[i] = key;
58 if (key == NULL) {
59 error("Could not load host key: %s",
60--- openssh-4.7p1.orig/servconf.c
61+++ openssh-4.7p1/servconf.c
62@@ -96,6 +96,7 @@
63 options->password_authentication = -1;
64 options->kbd_interactive_authentication = -1;
65 options->challenge_response_authentication = -1;
66+ options->permit_blacklisted_keys = -1;
67 options->permit_empty_passwd = -1;
68 options->permit_user_env = -1;
69 options->use_login = -1;
70@@ -218,6 +219,8 @@
71 options->kbd_interactive_authentication = 0;
72 if (options->challenge_response_authentication == -1)
73 options->challenge_response_authentication = 1;
74+ if (options->permit_blacklisted_keys == -1)
75+ options->permit_blacklisted_keys = 0;
76 if (options->permit_empty_passwd == -1)
77 options->permit_empty_passwd = 0;
78 if (options->permit_user_env == -1)
79@@ -287,7 +290,7 @@
80 sListenAddress, sAddressFamily,
81 sPrintMotd, sPrintLastLog, sIgnoreRhosts,
82 sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
83- sStrictModes, sEmptyPasswd, sTCPKeepAlive,
84+ sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive,
85 sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
86 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
87 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
88@@ -387,6 +390,7 @@
89 { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
90 { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
91 { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
92+ { "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL },
898e7d18 93 { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
a66b6504
JK
94 { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
95 { "uselogin", sUseLogin, SSHCFG_GLOBAL },
96@@ -943,6 +947,10 @@
97 intptr = &options->tcp_keep_alive;
98 goto parse_flag;
99
100+ case sPermitBlacklistedKeys:
101+ intptr = &options->permit_blacklisted_keys;
102+ goto parse_flag;
103+
104 case sEmptyPasswd:
105 intptr = &options->permit_empty_passwd;
106 goto parse_flag;
107--- openssh-4.7p1.orig/servconf.h
108+++ openssh-4.7p1/servconf.h
109@@ -94,6 +94,7 @@
6b22dba3 110 * authentication. /
a66b6504
JK
111 int kbd_interactive_authentication; /* If true, permit */
112 int challenge_response_authentication;
113+ int permit_blacklisted_keys; /* If true, permit */
898e7d18
JR
114 int zero_knowledge_password_authentication;
115 /* If true, permit jpake auth */
a66b6504 116 int permit_empty_passwd; /* If false, do not permit empty
a66b6504
JK
117--- openssh-4.7p1.orig/Makefile.in
118+++ openssh-4.7p1/Makefile.in
50835229 119@@ -62,7 +62,7 @@
a66b6504
JK
120 INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
121 INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
122
501aed94
AM
123-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-ldap-helper$(EXEEXT)
124+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-ldap-helper$(EXEEXT) ssh-vulnkey$(EXEEXT)
a66b6504
JK
125
126 LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
127 canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
50835229
AM
128@@ -93,8 +93,8 @@
129 audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
130 roaming_common.o roaming_serv.o ldapauth.o
a66b6504 131
501aed94
AM
132-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-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out
133-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-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5
134+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-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out ssh-vulnkey.1.out
135+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-ldap-helper.8 sshd_config.5 ssh_config.5 ssh-ldap.conf.5 ssh-vulnkey.1
a66b6504
JK
136 MANTYPE = @MANTYPE@
137
138 CONFIGFILES=sshd_config.out ssh_config.out moduli.out
139@@ -165,6 +165,9 @@
140 ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
141 $(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
142
143+ssh-vulnkey$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-vulnkey.o
144+ $(LD) -o $@ ssh-vulnkey.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
145+
146 # test driver for the loginrec code - not built by default
147 logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
148 $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
6b22dba3
AM
149@@ -271,6 +271,7 @@
150 $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
151 $(INSTALL) -m 0755 $(STRIP_OPT) sftp$(EXEEXT) $(DESTDIR)$(bindir)/sftp$(EXEEXT)
152 $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server$(EXEEXT) $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
153+ $(INSTALL) -m 0755 $(STRIP_OPT) ssh-vulnkey$(EXEEXT) $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
a66b6504
JK
154 $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
155 $(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
156 $(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
50835229 157@@ -289,6 +289,7 @@
a66b6504
JK
158 $(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
159 $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
160 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
161+ $(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
50835229 162 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8
a66b6504 163 -rm -f $(DESTDIR)$(bindir)/slogin
50835229 164 ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
a66b6504
JK
165@@ -361,6 +366,7 @@
166 -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
167 -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
168 -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
169+ -rm -f $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
170 -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
171 -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
172 -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
173@@ -373,6 +379,7 @@
174 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
175 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
176 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
177+ -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
178 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
179 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8
180 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
181--- openssh-4.7p1.orig/auth-rh-rsa.c
182+++ openssh-4.7p1/auth-rh-rsa.c
183@@ -20,6 +20,7 @@
184 #include <pwd.h>
185 #include <stdarg.h>
186
187+#include "xmalloc.h"
188 #include "packet.h"
189 #include "uidswap.h"
190 #include "log.h"
191@@ -27,6 +28,7 @@
192 #include "servconf.h"
193 #include "key.h"
194 #include "hostfile.h"
195+#include "authfile.h"
196 #include "pathnames.h"
197 #include "auth.h"
198 #include "canohost.h"
199@@ -42,8 +44,22 @@
200 auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
201 Key *client_host_key)
202 {
203+ char *fp;
204 HostStatus host_status;
205
206+ if (blacklisted_key(client_host_key)) {
207+ fp = key_fingerprint(client_host_key, SSH_FP_MD5, SSH_FP_HEX);
208+ if (options.permit_blacklisted_keys)
209+ logit("Public key %s blacklisted (see "
210+ "ssh-vulnkey(1)); continuing anyway", fp);
211+ else
212+ logit("Public key %s blacklisted (see "
213+ "ssh-vulnkey(1))", fp);
214+ xfree(fp);
215+ if (!options.permit_blacklisted_keys)
216+ return 0;
217+ }
218+
50835229 219 if (auth_key_is_revoked(client_host_key))
a66b6504 220 return 0;
50835229 221
a66b6504
JK
222--- openssh-4.7p1.orig/authfile.h
223+++ openssh-4.7p1/authfile.h
224@@ -23,4 +23,7 @@
225 Key *key_load_private_pem(int, int, const char *, char **);
226 int key_perm_ok(int, const char *);
227
228+char *blacklist_filename(const Key *key);
229+int blacklisted_key(const Key *key);
230+
231 #endif
232--- openssh-4.7p1.orig/ssh-vulnkey.1
233+++ openssh-4.7p1/ssh-vulnkey.1
234@@ -0,0 +1,187 @@
235+.\" Copyright (c) 2008 Canonical Ltd. All rights reserved.
236+.\"
237+.\" Redistribution and use in source and binary forms, with or without
238+.\" modification, are permitted provided that the following conditions
239+.\" are met:
240+.\" 1. Redistributions of source code must retain the above copyright
241+.\" notice, this list of conditions and the following disclaimer.
242+.\" 2. Redistributions in binary form must reproduce the above copyright
243+.\" notice, this list of conditions and the following disclaimer in the
244+.\" documentation and/or other materials provided with the distribution.
245+.\"
246+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
247+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
248+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
249+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
250+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
251+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
253+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
255+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
256+.\"
257+.Dd $Mdocdate: May 12 2008 $
258+.Dt SSH-VULNKEY 1
259+.Os
260+.Sh NAME
261+.Nm ssh-vulnkey
262+.Nd check blacklist of compromised keys
263+.Sh SYNOPSIS
264+.Nm
265+.Op Fl q
266+.Ar file ...
267+.Nm
268+.Fl a
269+.Sh DESCRIPTION
270+.Nm
271+checks a key against a blacklist of compromised keys.
272+.Pp
273+A substantial number of keys are known to have been generated using a broken
274+version of OpenSSL distributed by Debian which failed to seed its random
275+number generator correctly.
276+Keys generated using these OpenSSL versions should be assumed to be
277+compromised.
278+This tool may be useful in checking for such keys.
279+.Pp
280+Keys that are compromised cannot be repaired; replacements must be generated
281+using
282+.Xr ssh-keygen 1 .
283+Make sure to update
284+.Pa authorized_keys
285+files on all systems where compromised keys were permitted to authenticate.
286+.Pp
287+The argument list will be interpreted as a list of paths to public key files
288+or
289+.Pa authorized_keys
290+files.
291+If no suitable file is found at a given path,
292+.Nm
293+will append
294+.Pa .pub
295+and retry, in case it was given a private key file.
296+If no files are given as arguments,
297+.Nm
298+will check
299+.Pa ~/.ssh/id_rsa ,
300+.Pa ~/.ssh/id_dsa ,
301+.Pa ~/.ssh/identity ,
302+.Pa ~/.ssh/authorized_keys
303+and
304+.Pa ~/.ssh/authorized_keys2 ,
305+as well as the system's host keys if readable.
306+.Pp
307+If
308+.Dq -
309+is given as an argument,
310+.Nm
311+will read from standard input.
312+This can be used to process output from
313+.Xr ssh-keyscan 1 ,
314+for example:
315+.Pp
316+.Dl $ ssh-keyscan -t rsa remote.example.org | ssh-vulnkey -
317+.Pp
318+.Nm
319+will exit zero if any of the given keys were in the compromised list,
320+otherwise non-zero.
321+.Pp
322+Unless the
323+.Cm PermitBlacklistedKeys
324+option is used,
325+.Xr sshd 8
326+will reject attempts to authenticate with keys in the compromised list.
327+.Pp
328+The options are as follows:
329+.Bl -tag -width Ds
330+.It Fl a
331+Check keys of all users on the system.
332+You will typically need to run
333+.Nm
334+as root to use this option.
335+For each user,
336+.Nm
337+will check
338+.Pa ~/.ssh/id_rsa ,
339+.Pa ~/.ssh/id_dsa ,
340+.Pa ~/.ssh/identity ,
341+.Pa ~/.ssh/authorized_keys
342+and
343+.Pa ~/.ssh/authorized_keys2 .
344+It will also check the system's host keys.
345+.It Fl q
346+Quiet mode.
347+Normally,
348+.Nm
349+outputs the fingerprint of each key scanned, with a description of its
350+status.
351+This option suppresses that output.
352+.El
353+.Sh BLACKLIST FILE FORMAT
354+The blacklist file may start with comments, on lines starting with
355+.Dq # .
356+After these initial comments, it must follow a strict format:
357+.Pp
358+.Bl -bullet -offset indent -compact
359+.It
360+All the lines must be exactly the same length (20 characters followed by a
361+newline) and must be in sorted order.
362+.It
363+Each line must consist of the lower-case hexadecimal MD5 key fingerprint,
364+without colons, and with the first 12 characters removed (that is, the least
365+significant 80 bits of the fingerprint).
366+.El
367+.Pp
368+The key fingerprint may be generated using
369+.Xr ssh-keygen 1 :
370+.Pp
371+.Dl $ ssh-keygen -l -f /path/to/key
372+.Pp
373+This strict format is necessary to allow the blacklist file to be checked
374+quickly, using a binary-search algorithm.
375+.Sh FILES
376+.Bl -tag -width Ds
377+.It Pa ~/.ssh/id_rsa
378+If present, contains the protocol version 2 RSA authentication identity of
379+the user.
380+.It Pa ~/.ssh/id_dsa
381+If present, contains the protocol version 2 DSA authentication identity of
382+the user.
383+.It Pa ~/.ssh/identity
384+If present, contains the protocol version 1 RSA authentication identity of
385+the user.
386+.It Pa ~/.ssh/authorized_keys
387+If present, lists the public keys (RSA/DSA) that can be used for logging in
388+as this user.
389+.It Pa ~/.ssh/authorized_keys2
390+Obsolete name for
391+.Pa ~/.ssh/authorized_keys .
392+This file may still be present on some old systems, but should not be
393+created if it is missing.
394+.It Pa /etc/ssh/ssh_host_rsa_key
395+If present, contains the protocol version 2 RSA identity of the system.
396+.It Pa /etc/ssh/ssh_host_dsa_key
397+If present, contains the protocol version 2 DSA identity of the system.
398+.It Pa /etc/ssh/ssh_host_key
399+If present, contains the protocol version 1 RSA identity of the system.
400+.It Pa /etc/ssh/blacklist. Ns Ar TYPE Ns Pa - Ns Ar LENGTH
401+If present, lists the blacklisted keys of type
402+.Ar TYPE
403+.Pf ( Dq RSA1 ,
404+.Dq RSA ,
405+or
406+.Dq DSA )
407+and bit length
408+.Ar LENGTH .
409+The format of this file is described above.
410+.El
411+.Sh SEE ALSO
412+.Xr ssh-keygen 1 ,
413+.Xr sshd 8
414+.Sh AUTHORS
415+.An -nosplit
416+.An Colin Watson Aq cjwatson@ubuntu.com
417+.Pp
418+Florian Weimer suggested the option to check keys of all users, and the idea
419+of processing
420+.Xr ssh-keyscan 1
421+output.
0f6e8103
ER
422--- openssh-5.6p1/auth2-hostbased.c~ 2010-08-24 14:10:03.000000000 +0300
423+++ openssh-5.6p1/auth2-hostbased.c 2010-08-24 14:12:10.632553591 +0300
a66b6504
JK
424@@ -40,6 +40,7 @@
425 #include "compat.h"
426 #include "key.h"
427 #include "hostfile.h"
428+#include "authfile.h"
429 #include "auth.h"
430 #include "canohost.h"
431 #ifdef GSSAPI
0f6e8103 432@@ -147,6 +147,19 @@
a66b6504 433 int len;
0f6e8103 434 char *fp;
a66b6504
JK
435
436+ if (blacklisted_key(key)) {
437+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
438+ if (options.permit_blacklisted_keys)
439+ logit("Public key %s blacklisted (see "
440+ "ssh-vulnkey(1)); continuing anyway", fp);
441+ else
442+ logit("Public key %s blacklisted (see "
443+ "ssh-vulnkey(1))", fp);
444+ xfree(fp);
445+ if (!options.permit_blacklisted_keys)
446+ return 0;
447+ }
448+
50835229
AM
449 if (auth_key_is_revoked(key))
450 return 0;
a66b6504
JK
451
452--- openssh-4.7p1.orig/authfile.c
453+++ openssh-4.7p1/authfile.c
454@@ -65,6 +65,7 @@
455 #include "rsa.h"
456 #include "misc.h"
457 #include "atomicio.h"
458+#include "pathnames.h"
459
460 /* Version identification string for SSH v1 identity files. */
461 static const char authfile_id_string[] =
462@@ -677,3 +678,113 @@
50835229 463 return ret;
a66b6504 464 }
50835229 465
a66b6504
JK
466+
467+char *
468+blacklist_filename(const Key *key)
469+{
470+ char *name;
471+
472+ xasprintf(&name, "%s.%s-%u",
473+ _PATH_BLACKLIST, key_type(key), key_size(key));
474+ return name;
475+}
476+
477+/* Scan a blacklist of known-vulnerable keys. */
478+int
479+blacklisted_key(const Key *key)
480+{
481+ char *blacklist_file;
482+ int fd = -1;
483+ char *dgst_hex = NULL;
484+ char *dgst_packed = NULL, *p;
485+ int i;
486+ size_t line_len;
487+ struct stat st;
488+ char buf[256];
489+ off_t start, lower, upper;
490+ int ret = 0;
491+
492+ blacklist_file = blacklist_filename(key);
493+ debug("Checking blacklist file %s", blacklist_file);
494+ fd = open(blacklist_file, O_RDONLY);
495+ if (fd < 0)
496+ goto out;
497+
498+ dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
499+ /* Remove all colons */
500+ dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
501+ for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
502+ if (dgst_hex[i] != ':')
503+ *p++ = dgst_hex[i];
504+ /* Only compare least-significant 80 bits (to keep the blacklist
505+ * size down)
506+ */
507+ line_len = strlen(dgst_packed + 12);
508+ if (line_len > 32)
509+ goto out;
510+
511+ /* Skip leading comments */
512+ start = 0;
513+ for (;;) {
514+ ssize_t r;
515+ char *newline;
516+
517+ r = atomicio(read, fd, buf, 256);
518+ if (r <= 0)
519+ goto out;
520+ if (buf[0] != '#')
521+ break;
522+
523+ newline = memchr(buf, '\n', 256);
524+ if (!newline)
525+ goto out;
526+ start += newline + 1 - buf;
527+ if (lseek(fd, start, SEEK_SET) < 0)
528+ goto out;
529+ }
530+
531+ /* Initialise binary search record numbers */
532+ if (fstat(fd, &st) < 0)
533+ goto out;
534+ lower = 0;
535+ upper = (st.st_size - start) / (line_len + 1);
536+
537+ while (lower != upper) {
538+ off_t cur;
539+ char buf[32];
540+ int cmp;
541+
542+ cur = lower + (upper - lower) / 2;
543+
544+ /* Read this line and compare to digest; this is
545+ * overflow-safe since cur < max(off_t) / (line_len + 1) */
546+ if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
547+ break;
548+ if (atomicio(read, fd, buf, line_len) != line_len)
549+ break;
550+ cmp = memcmp(buf, dgst_packed + 12, line_len);
551+ if (cmp < 0) {
552+ if (cur == lower)
553+ break;
554+ lower = cur;
555+ } else if (cmp > 0) {
556+ if (cur == upper)
557+ break;
558+ upper = cur;
559+ } else {
560+ debug("Found %s in blacklist", dgst_hex);
561+ ret = 1;
562+ break;
563+ }
564+ }
565+
566+out:
567+ if (dgst_packed)
568+ xfree(dgst_packed);
569+ if (dgst_hex)
570+ xfree(dgst_hex);
571+ if (fd >= 0)
572+ close(fd);
573+ xfree(blacklist_file);
574+ return ret;
575+}
576--- openssh-4.7p1.orig/ssh-vulnkey.c
577+++ openssh-4.7p1/ssh-vulnkey.c
578@@ -0,0 +1,325 @@
579+/*
580+ * Copyright (c) 2008 Canonical Ltd. All rights reserved.
581+ *
582+ * Redistribution and use in source and binary forms, with or without
583+ * modification, are permitted provided that the following conditions
584+ * are met:
585+ * 1. Redistributions of source code must retain the above copyright
586+ * notice, this list of conditions and the following disclaimer.
587+ * 2. Redistributions in binary form must reproduce the above copyright
588+ * notice, this list of conditions and the following disclaimer in the
589+ * documentation and/or other materials provided with the distribution.
590+ *
591+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
592+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
593+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
594+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
595+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
596+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
597+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
598+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
599+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
600+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
601+ */
602+
603+#include "includes.h"
604+
605+#include <sys/types.h>
606+#include <sys/stat.h>
607+
608+#include <string.h>
609+#include <stdio.h>
610+#include <fcntl.h>
611+#include <unistd.h>
612+
613+#include <openssl/evp.h>
614+
615+#include "xmalloc.h"
616+#include "ssh.h"
617+#include "log.h"
618+#include "key.h"
619+#include "authfile.h"
620+#include "pathnames.h"
621+#include "misc.h"
622+
623+extern char *__progname;
624+
625+/* Default files to check */
626+static char *default_host_files[] = {
627+ _PATH_HOST_RSA_KEY_FILE,
628+ _PATH_HOST_DSA_KEY_FILE,
629+ _PATH_HOST_KEY_FILE,
630+ NULL
631+};
632+static char *default_files[] = {
633+ _PATH_SSH_CLIENT_ID_RSA,
634+ _PATH_SSH_CLIENT_ID_DSA,
635+ _PATH_SSH_CLIENT_IDENTITY,
636+ _PATH_SSH_USER_PERMITTED_KEYS,
637+ _PATH_SSH_USER_PERMITTED_KEYS2,
638+ NULL
639+};
640+
641+static int quiet = 0;
642+
643+static void
644+usage(void)
645+{
646+ fprintf(stderr, "usage: %s [-aq] [file ...]\n", __progname);
647+ fprintf(stderr, "Options:\n");
648+ fprintf(stderr, " -a Check keys of all users.\n");
649+ fprintf(stderr, " -q Quiet mode.\n");
650+ exit(1);
651+}
652+
653+void
654+describe_key(const char *msg, const Key *key, const char *comment)
655+{
656+ char *fp;
657+
658+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
659+ if (!quiet)
660+ printf("%s: %u %s %s\n", msg, key_size(key), fp, comment);
661+ xfree(fp);
662+}
663+
664+int
665+do_key(const Key *key, const char *comment)
666+{
667+ char *blacklist_file;
668+ struct stat st;
669+ int ret = 1;
670+
671+ blacklist_file = blacklist_filename(key);
672+ if (stat(blacklist_file, &st) < 0)
673+ describe_key("Unknown (no blacklist information)",
674+ key, comment);
675+ else if (blacklisted_key(key)) {
676+ describe_key("COMPROMISED", key, comment);
677+ ret = 0;
678+ } else
679+ describe_key("Not blacklisted", key, comment);
680+ xfree(blacklist_file);
681+
682+ return ret;
683+}
684+
685+int
686+do_filename(const char *filename, int quiet_open)
687+{
688+ FILE *f;
689+ char line[SSH_MAX_PUBKEY_BYTES];
690+ char *cp;
691+ u_long linenum = 0;
692+ Key *key;
693+ char *comment = NULL;
694+ int found = 0, ret = 1;
695+
696+ /* Copy much of key_load_public's logic here so that we can read
697+ * several keys from a single file (e.g. authorized_keys).
698+ */
699+
700+ if (strcmp(filename, "-") != 0) {
701+ f = fopen(filename, "r");
702+ if (!f) {
703+ char pubfile[MAXPATHLEN];
704+ if (strlcpy(pubfile, filename, sizeof pubfile) <
705+ sizeof(pubfile) &&
706+ strlcat(pubfile, ".pub", sizeof pubfile) <
707+ sizeof(pubfile))
708+ f = fopen(pubfile, "r");
709+ }
710+ if (!f) {
711+ if (!quiet_open)
712+ perror(filename);
713+ return -1;
714+ }
715+ } else
716+ f = stdin;
717+ while (read_keyfile_line(f, filename, line, sizeof(line),
718+ &linenum) != -1) {
719+ int i;
720+ char *space;
721+ int type;
722+
723+ /* Chop trailing newline. */
724+ i = strlen(line) - 1;
725+ if (line[i] == '\n')
726+ line[i] = '\0';
727+
728+ /* Skip leading whitespace, empty and comment lines. */
729+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
730+ ;
731+ if (!*cp || *cp == '\n' || *cp == '#')
732+ continue;
733+
734+ /* Cope with ssh-keyscan output and options in
735+ * authorized_keys files.
736+ */
737+ space = strchr(cp, ' ');
738+ if (!space)
739+ continue;
740+ *space = '\0';
741+ type = key_type_from_name(cp);
742+ *space = ' ';
743+ /* Leading number (RSA1) or valid type (RSA/DSA) indicates
744+ * that we have no host name or options to skip.
745+ */
746+ if (atoi(cp) == 0 && type == KEY_UNSPEC) {
747+ int quoted = 0;
748+
749+ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
750+ if (*cp == '\\' && cp[1] == '"')
751+ cp++; /* Skip both */
752+ else if (*cp == '"')
753+ quoted = !quoted;
754+ }
755+ /* Skip remaining whitespace. */
756+ for (; *cp == ' ' || *cp == '\t'; cp++)
757+ ;
758+ if (!*cp)
759+ continue;
760+ }
761+
762+ /* Read and process the key itself. */
763+ key = key_new(KEY_RSA1);
764+ if (key_read(key, &cp) == 1) {
765+ while (*cp == ' ' || *cp == '\t')
766+ cp++;
767+ if (!do_key(key, *cp ? cp : filename))
768+ ret = 0;
769+ found = 1;
770+ } else {
771+ key_free(key);
772+ key = key_new(KEY_UNSPEC);
773+ if (key_read(key, &cp) == 1) {
774+ while (*cp == ' ' || *cp == '\t')
775+ cp++;
776+ if (!do_key(key, *cp ? cp : filename))
777+ ret = 0;
778+ found = 1;
779+ }
780+ }
781+ key_free(key);
782+ }
783+ if (f != stdin)
784+ fclose(f);
785+
786+ if (!found && filename) {
787+ key = key_load_public(filename, &comment);
788+ if (key) {
789+ if (!do_key(key, comment))
790+ ret = 0;
791+ found = 1;
792+ }
793+ if (comment)
794+ xfree(comment);
795+ }
796+
797+ return ret;
798+}
799+
800+int
801+do_host(void)
802+{
803+ int i;
804+ struct stat st;
805+ int ret = 1;
806+
807+ for (i = 0; default_host_files[i]; i++) {
808+ if (stat(default_host_files[i], &st) < 0)
809+ continue;
810+ if (!do_filename(default_host_files[i], 1))
811+ ret = 0;
812+ }
813+
814+ return ret;
815+}
816+
817+int
818+do_user(const char *dir)
819+{
820+ int i;
821+ char buf[MAXPATHLEN];
822+ struct stat st;
823+ int ret = 1;
824+
825+ for (i = 0; default_files[i]; i++) {
826+ snprintf(buf, sizeof(buf), "%s/%s", dir, default_files[i]);
827+ if (stat(buf, &st) < 0)
828+ continue;
829+ if (!do_filename(buf, 0))
830+ ret = 0;
831+ }
832+
833+ return ret;
834+}
835+
836+int
837+main(int argc, char **argv)
838+{
839+ int opt, all_users = 0;
840+ int ret = 1;
841+ extern int optind;
842+
843+ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
844+ sanitise_stdfd();
845+
846+ __progname = ssh_get_progname(argv[0]);
847+
848+ SSLeay_add_all_algorithms();
849+ log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
850+
851+ /* We don't need the RNG ourselves, but symbol references here allow
852+ * ld to link us properly.
853+ */
afde20c1
AM
854+ //init_rng();
855+ //seed_rng();
a66b6504
JK
856+
857+ while ((opt = getopt(argc, argv, "ahq")) != -1) {
858+ switch (opt) {
859+ case 'a':
860+ all_users = 1;
861+ break;
862+ case 'q':
863+ quiet = 1;
864+ break;
865+ case 'h':
866+ default:
867+ usage();
868+ }
869+ }
870+
871+ if (all_users) {
872+ struct passwd *pw;
873+
874+ if (!do_host())
875+ ret = 0;
876+
877+ while ((pw = getpwent()) != NULL) {
878+ if (pw->pw_dir) {
879+ if (!do_user(pw->pw_dir))
880+ ret = 0;
881+ }
882+ }
883+ } else if (optind == argc) {
884+ struct passwd *pw;
885+
886+ if (!do_host())
887+ ret = 0;
888+
889+ if ((pw = getpwuid(getuid())) == NULL)
890+ fprintf(stderr, "No user found with uid %u\n",
891+ (u_int)getuid());
892+ else {
893+ if (!do_user(pw->pw_dir))
894+ ret = 0;
895+ }
896+ } else {
897+ while (optind < argc)
898+ if (!do_filename(argv[optind++], 0))
899+ ret = 0;
900+ }
901+
902+ return ret;
903+}
904--- openssh-4.7p1.orig/auth-rsa.c
905+++ openssh-4.7p1/auth-rsa.c
906@@ -40,6 +40,7 @@
907 #include "servconf.h"
908 #include "key.h"
909 #include "hostfile.h"
910+#include "authfile.h"
911 #include "auth.h"
912 #ifdef GSSAPI
913 #include "ssh-gss.h"
914@@ -221,6 +222,7 @@
915 char *cp;
916 char *key_options;
917 int keybits;
918+ char *fp;
919
920 /* Skip leading whitespace, empty and comment lines. */
921 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
922@@ -265,6 +267,19 @@
923 "actual %d vs. announced %d.",
924 file, linenum, BN_num_bits(key->rsa->n), bits);
925
926+ if (blacklisted_key(key)) {
927+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
928+ if (options.permit_blacklisted_keys)
929+ logit("Public key %s blacklisted (see "
930+ "ssh-vulnkey(1)); continuing anyway", fp);
931+ else
932+ logit("Public key %s blacklisted (see "
933+ "ssh-vulnkey(1))", fp);
934+ xfree(fp);
935+ if (!options.permit_blacklisted_keys)
936+ continue;
937+ }
938+
939 /* We have found the desired key. */
940 /*
941 * If our options do not allow this key to be used,
942--- openssh-4.7p1.orig/pathnames.h
943+++ openssh-4.7p1/pathnames.h
944@@ -43,6 +43,8 @@
945 /* Backwards compatibility */
946 #define _PATH_DH_PRIMES SSHDIR "/primes"
947
948+#define _PATH_BLACKLIST SSHDIR "/blacklist"
949+
950 #ifndef _PATH_SSH_PROGRAM
951 #define _PATH_SSH_PROGRAM "/usr/bin/ssh"
952 #endif
108bb9ae
ER
953--- openssh-5.9p1/auth2-pubkey.c~ 2011-09-29 00:36:17.000000000 +0300
954+++ openssh-5.9p1/auth2-pubkey.c 2011-09-29 00:37:17.847762648 +0300
a66b6504
JK
955@@ -42,6 +42,7 @@
956 #include "compat.h"
957 #include "key.h"
958 #include "hostfile.h"
959+#include "authfile.h"
960 #include "auth.h"
961 #include "pathnames.h"
962 #include "uidswap.h"
108bb9ae 963@@ -596,9 +596,23 @@
a66b6504
JK
964 int
965 user_key_allowed(struct passwd *pw, Key *key)
966 {
967+ char *fp;
afde20c1 968 u_int success, i;
a66b6504
JK
969 char *file;
970
971+ if (blacklisted_key(key)) {
972+ fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
973+ if (options.permit_blacklisted_keys)
974+ logit("Public key %s blacklisted (see "
975+ "ssh-vulnkey(1)); continuing anyway", fp);
976+ else
977+ logit("Public key %s blacklisted (see "
978+ "ssh-vulnkey(1))", fp);
979+ xfree(fp);
980+ if (!options.permit_blacklisted_keys)
981+ return 0;
982+ }
983+
108bb9ae
ER
984 #ifdef WITH_AUTHORIZED_KEYS_COMMAND
985 success = user_key_via_command_allowed2(pw, key);
986 if (success > 0)
This page took 0.213064 seconds and 4 git commands to generate.