]>
Commit | Line | Data |
---|---|---|
a66b6504 JK |
1 | This patch is against OpenSSH 4.7p1, although should apply to other versions |
2 | without 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 | ||
11 | This 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); | |
0fab2cab | 51 | + free(fp); |
a66b6504 JK |
52 | + if (!options.permit_blacklisted_keys) { |
53 | + sensitive_data.host_keys[i] = NULL; | |
54 | + continue; | |
55 | + } | |
56 | + } | |
0fab2cab | 57 | pubkey = key_load_public(options.host_key_files[i], NULL); |
a66b6504 | 58 | sensitive_data.host_keys[i] = key; |
0fab2cab | 59 | sensitive_data.host_pubkeys[i] = pubkey; |
a66b6504 JK |
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) | |
0fab2cab | 149 | @@ -271,6 +274,7 @@ |
6b22dba3 AM |
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 | |
0fab2cab | 157 | @@ -289,6 +293,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); | |
0fab2cab | 214 | + free(fp); |
a66b6504 JK |
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 | |
0fab2cab | 432 | @@ -147,6 +148,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); | |
0fab2cab | 444 | + free(fp); |
a66b6504 JK |
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) | |
0fab2cab | 568 | + free(dgst_packed); |
a66b6504 | 569 | + if (dgst_hex) |
0fab2cab | 570 | + free(dgst_hex); |
a66b6504 JK |
571 | + if (fd >= 0) |
572 | + close(fd); | |
0fab2cab | 573 | + free(blacklist_file); |
a66b6504 JK |
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); | |
0fab2cab | 661 | + free(fp); |
a66b6504 JK |
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); | |
0fab2cab | 680 | + free(blacklist_file); |
a66b6504 JK |
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) | |
0fab2cab | 794 | + free(comment); |
a66b6504 JK |
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); | |
0fab2cab | 934 | + free(fp); |
a66b6504 JK |
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" | |
0fab2cab | 963 | @@ -608,6 +609,20 @@ |
a66b6504 | 964 | { |
afde20c1 | 965 | u_int success, i; |
a66b6504 | 966 | char *file; |
ec3e8a5a AM |
967 | + char *fp; |
968 | + | |
a66b6504 JK |
969 | + if (blacklisted_key(key)) { |
970 | + fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); | |
971 | + if (options.permit_blacklisted_keys) | |
972 | + logit("Public key %s blacklisted (see " | |
ec3e8a5a | 973 | + "ssh-vulnkey(1)); continuing anyway", fp); |
a66b6504 JK |
974 | + else |
975 | + logit("Public key %s blacklisted (see " | |
ec3e8a5a | 976 | + "ssh-vulnkey(1))", fp); |
0fab2cab | 977 | + free(fp); |
a66b6504 JK |
978 | + if (!options.permit_blacklisted_keys) |
979 | + return 0; | |
980 | + } | |
ec3e8a5a AM |
981 | |
982 | if (auth_key_is_revoked(key)) | |
983 | return 0; | |
984 |