Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 221759 | Differences between
and this patch

Collapse All | Expand All

(-)openssh-4.7p1/sshd_config.5 (+14 lines)
Lines 677-682 are refused if the number of unauthentic Link Here
677
Specifies whether password authentication is allowed.
677
Specifies whether password authentication is allowed.
678
The default is
678
The default is
679
.Dq yes .
679
.Dq yes .
680
.It Cm PermitBlacklistedKeys
681
Specifies whether
682
.Xr sshd 8
683
should allow keys recorded in its blacklist of known-compromised keys (see
684
.Xr ssh-vulnkey 1 ) .
685
If
686
.Dq yes ,
687
then attempts to authenticate with compromised keys will be logged but
688
accepted.
689
If
690
.Dq no ,
691
then attempts to authenticate with compromised keys will be rejected.
692
The default is
693
.Dq no .
680
.It Cm PermitEmptyPasswords
694
.It Cm PermitEmptyPasswords
681
When password authentication is allowed, it specifies whether the
695
When password authentication is allowed, it specifies whether the
682
server allows login to accounts with empty password strings.
696
server allows login to accounts with empty password strings.
(-)openssh-4.7p1/sshd.c (+15 lines)
Lines 1469-1474 main(int ac, char **av) Link Here
1469
1469
1470
	for (i = 0; i < options.num_host_key_files; i++) {
1470
	for (i = 0; i < options.num_host_key_files; i++) {
1471
		key = key_load_private(options.host_key_files[i], "", NULL);
1471
		key = key_load_private(options.host_key_files[i], "", NULL);
1472
		if (key && blacklisted_key(key)) {
1473
			char *fp;
1474
			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1475
			if (options.permit_blacklisted_keys)
1476
				error("Host key %s blacklisted (see "
1477
				    "ssh-vulnkey(1)); continuing anyway", fp);
1478
			else
1479
				error("Host key %s blacklisted (see "
1480
				    "ssh-vulnkey(1))", fp);
1481
			xfree(fp);
1482
			if (!options.permit_blacklisted_keys) {
1483
				sensitive_data.host_keys[i] = NULL;
1484
				continue;
1485
			}
1486
		}
1472
		sensitive_data.host_keys[i] = key;
1487
		sensitive_data.host_keys[i] = key;
1473
		if (key == NULL) {
1488
		if (key == NULL) {
1474
			error("Could not load host key: %s",
1489
			error("Could not load host key: %s",
(-)openssh-4.7p1/servconf.c (-1 / +9 lines)
Lines 130-135 initialize_server_options(ServerOptions Link Here
130
	options->password_authentication = -1;
130
	options->password_authentication = -1;
131
	options->kbd_interactive_authentication = -1;
131
	options->kbd_interactive_authentication = -1;
132
	options->challenge_response_authentication = -1;
132
	options->challenge_response_authentication = -1;
133
	options->permit_blacklisted_keys = -1;
133
	options->permit_empty_passwd = -1;
134
	options->permit_empty_passwd = -1;
134
	options->permit_user_env = -1;
135
	options->permit_user_env = -1;
135
	options->use_login = -1;
136
	options->use_login = -1;
Lines 248-253 fill_default_server_options(ServerOption Link Here
248
		options->kbd_interactive_authentication = 0;
249
		options->kbd_interactive_authentication = 0;
249
	if (options->challenge_response_authentication == -1)
250
	if (options->challenge_response_authentication == -1)
250
		options->challenge_response_authentication = 1;
251
		options->challenge_response_authentication = 1;
252
	if (options->permit_blacklisted_keys == -1)
253
		options->permit_blacklisted_keys = 0;
251
	if (options->permit_empty_passwd == -1)
254
	if (options->permit_empty_passwd == -1)
252
		options->permit_empty_passwd = 0;
255
		options->permit_empty_passwd = 0;
253
	if (options->permit_user_env == -1)
256
	if (options->permit_user_env == -1)
Lines 349-355 typedef enum { Link Here
349
	sListenAddress, sAddressFamily,
352
	sListenAddress, sAddressFamily,
350
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
353
	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
351
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
354
	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
352
	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
355
	sStrictModes, sPermitBlacklistedKeys, sEmptyPasswd, sTCPKeepAlive,
353
	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
356
	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
354
	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
357
	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
355
	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
358
	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
Lines 439-444 static struct { Link Here
439
	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
442
	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
440
	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
443
	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
441
	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
444
	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
445
	{ "permitblacklistedkeys", sPermitBlacklistedKeys, SSHCFG_GLOBAL },
442
	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
446
	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
443
	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
447
	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
444
	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
448
	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
Lines 1003-1008 parse_flag: Link Here
1003
		intptr = &options->tcp_keep_alive;
1007
		intptr = &options->tcp_keep_alive;
1004
		goto parse_flag;
1008
		goto parse_flag;
1005
1009
1010
	case sPermitBlacklistedKeys:
1011
		intptr = &options->permit_blacklisted_keys;
1012
		goto parse_flag;
1013
1006
	case sEmptyPasswd:
1014
	case sEmptyPasswd:
1007
		intptr = &options->permit_empty_passwd;
1015
		intptr = &options->permit_empty_passwd;
1008
		goto parse_flag;
1016
		goto parse_flag;
(-)openssh-4.7p1/servconf.h (+1 lines)
Lines 117-122 typedef struct { Link Here
117
						 * authentication. */
117
						 * authentication. */
118
	int     kbd_interactive_authentication;	/* If true, permit */
118
	int     kbd_interactive_authentication;	/* If true, permit */
119
	int     challenge_response_authentication;
119
	int     challenge_response_authentication;
120
	int     permit_blacklisted_keys;	/* If true, permit */
120
	int     permit_empty_passwd;	/* If false, do not permit empty
121
	int     permit_empty_passwd;	/* If false, do not permit empty
121
					 * passwords. */
122
					 * passwords. */
122
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
123
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
(-)openssh-4.7p1/Makefile.in (-3 / +10 lines)
Lines 73-79 INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAN Link Here
73
SSHX509_OBJS=ssh-x509.o ssh-xkalg.o x509_nm_cmp.o
73
SSHX509_OBJS=ssh-x509.o ssh-xkalg.o x509_nm_cmp.o
74
X509STORE_OBJS=x509store.o $(LDAP_OBJS) $(OCSP_OBJS)
74
X509STORE_OBJS=x509store.o $(LDAP_OBJS) $(OCSP_OBJS)
75
75
76
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
76
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-vulnkey$(EXEEXT)
77
77
78
LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
78
LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
79
	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
79
	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
Lines 101-108 SSHDOBJS=sshd.o auth-rhosts.o auth-passw Link Here
101
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
101
	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
102
	audit.o audit-bsm.o platform.o $(X509STORE_OBJS)
102
	audit.o audit-bsm.o platform.o $(X509STORE_OBJS)
103
103
104
MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
104
MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-vulnkey.1.out sshd_config.5.out ssh_config.5.out
105
MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
105
MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 ssh-vulnkey.1 sshd_config.5 ssh_config.5
106
MANTYPE		= @MANTYPE@
106
MANTYPE		= @MANTYPE@
107
107
108
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
108
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
Lines 182-187 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sft Link Here
182
ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
182
ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
183
	$(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
183
	$(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
184
184
185
ssh-vulnkey$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-vulnkey.o
186
	$(LD) -o $@ ssh-vulnkey.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
187
185
# test driver for the loginrec code - not built by default
188
# test driver for the loginrec code - not built by default
186
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
189
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
187
	$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
190
	$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
Lines 284-289 install-files: scard-install Link Here
284
	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN)
287
	$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN)
285
	$(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp
288
	$(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp
286
	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER)
289
	$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER)
290
	$(INSTALL) -m 0755 $(STRIP_OPT) ssh-vulnkey $(DESTDIR)$(bindir)/ssh-vulnkey
287
	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
291
	$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
288
	$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
292
	$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
289
	$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
293
	$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
Lines 299-304 install-files: scard-install Link Here
299
	$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
303
	$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
300
	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
304
	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
301
	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
305
	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
306
	$(INSTALL) -m 644 ssh-vulnkey.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
302
	-rm -f $(DESTDIR)$(bindir)/slogin
307
	-rm -f $(DESTDIR)$(bindir)/slogin
303
	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
308
	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
304
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
309
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
Lines 380-385 uninstall: Link Here
380
	-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
385
	-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
381
	-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
386
	-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
382
	-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
387
	-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
388
	-rm -f $(DESTDIR)$(bindir)/ssh-vulnkey$(EXEEXT)
383
	-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
389
	-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
384
	-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
390
	-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
385
	-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
391
	-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
Lines 392-397 uninstall: Link Here
392
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
398
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
393
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
399
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
394
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
400
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
401
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-vulnkey.1
395
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
402
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
396
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8
403
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8
397
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
404
	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
(-)openssh-4.7p1/auth-rh-rsa.c (+16 lines)
Lines 20-25 Link Here
20
#include <pwd.h>
20
#include <pwd.h>
21
#include <stdarg.h>
21
#include <stdarg.h>
22
22
23
#include "xmalloc.h"
23
#include "packet.h"
24
#include "packet.h"
24
#include "uidswap.h"
25
#include "uidswap.h"
25
#include "log.h"
26
#include "log.h"
Lines 27-32 Link Here
27
#include "servconf.h"
28
#include "servconf.h"
28
#include "key.h"
29
#include "key.h"
29
#include "hostfile.h"
30
#include "hostfile.h"
31
#include "authfile.h"
30
#include "pathnames.h"
32
#include "pathnames.h"
31
#include "auth.h"
33
#include "auth.h"
32
#include "canohost.h"
34
#include "canohost.h"
Lines 42-49 int Link Here
42
auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
44
auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
43
    Key *client_host_key)
45
    Key *client_host_key)
44
{
46
{
47
	char *fp;
45
	HostStatus host_status;
48
	HostStatus host_status;
46
49
50
	if (blacklisted_key(client_host_key)) {
51
		fp = key_fingerprint(client_host_key, SSH_FP_MD5, SSH_FP_HEX);
52
		if (options.permit_blacklisted_keys)
53
			logit("Public key %s blacklisted (see "
54
			    "ssh-vulnkey(1)); continuing anyway", fp);
55
		else
56
			logit("Public key %s blacklisted (see "
57
			    "ssh-vulnkey(1))", fp);
58
		xfree(fp);
59
		if (!options.permit_blacklisted_keys)
60
			return 0;
61
	}
62
47
	/* Check if we would accept it using rhosts authentication. */
63
	/* Check if we would accept it using rhosts authentication. */
48
	if (!auth_rhosts(pw, cuser))
64
	if (!auth_rhosts(pw, cuser))
49
		return 0;
65
		return 0;
(-)openssh-4.7p1/authfile.h (+3 lines)
Lines 23-26 Key *key_load_private_type(int, const ch Link Here
23
Key	*key_load_private_pem(int, int, const char *, char **);
23
Key	*key_load_private_pem(int, int, const char *, char **);
24
int	 key_perm_ok(int, const char *);
24
int	 key_perm_ok(int, const char *);
25
25
26
char	*blacklist_filename(const Key *key);
27
int	 blacklisted_key(const Key *key);
28
26
#endif
29
#endif
(-)openssh-4.7p1/ssh-vulnkey.1 (+151 lines)
Line 0 Link Here
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
32
.Ar file ...
33
.Nm
34
.Fl a
35
.Sh DESCRIPTION
36
.Nm
37
checks a key against a blacklist of compromised keys.
38
.Pp
39
A substantial number of keys are known to have been generated using a broken
40
version of OpenSSL distributed by Debian which failed to seed its random
41
number generator correctly.
42
Keys generated using these OpenSSL versions should be assumed to be
43
compromised.
44
This tool may be useful in checking for such keys.
45
.Pp
46
Keys that are compromised cannot be repaired; replacements must be generated
47
using
48
.Xr ssh-keygen 1 .
49
Make sure to update
50
.Pa authorized_keys
51
files on all systems where compromised keys were permitted to authenticate.
52
.Pp
53
The argument list will be interpreted as a list of paths to public key files
54
or
55
.Pa authorized_keys
56
files.
57
If no suitable file is found at a given path,
58
.Nm
59
will append
60
.Pa .pub
61
and retry, in case it was given a private key file.
62
If no files are given as arguments,
63
.Nm
64
will check
65
.Pa ~/.ssh/id_rsa ,
66
.Pa ~/.ssh/id_dsa ,
67
.Pa ~/.ssh/identity ,
68
.Pa ~/.ssh/authorized_keys
69
and
70
.Pa ~/.ssh/authorized_keys2 ,
71
as well as the system's host keys if readable.
72
.Pp
73
If
74
.Dq -
75
is given as an argument,
76
.Nm
77
will read from standard input.
78
This can be used to process output from
79
.Xr ssh-keyscan 1 ,
80
for example:
81
.Pp
82
.Dl $ ssh-keyscan -t rsa remote.example.org | ssh-vulnkey -
83
.Pp
84
.Nm
85
will exit zero if any of the given keys were in the compromised list,
86
otherwise non-zero.
87
.Pp
88
Unless the
89
.Cm PermitBlacklistedKeys
90
option is used,
91
.Xr sshd 8
92
will reject attempts to authenticate with keys in the compromised list.
93
.Pp
94
The options are as follows:
95
.Bl -tag -width Ds
96
.It Fl a
97
Check keys of all users on the system.
98
You will typically need to run
99
.Nm
100
as root to use this option.
101
For each user,
102
.Nm
103
will check
104
.Pa ~/.ssh/id_rsa ,
105
.Pa ~/.ssh/id_dsa ,
106
.Pa ~/.ssh/identity ,
107
.Pa ~/.ssh/authorized_keys
108
and
109
.Pa ~/.ssh/authorized_keys2 .
110
It will also check the system's host keys.
111
.It Fl q
112
Quiet mode.
113
Normally,
114
.Nm
115
outputs the fingerprint of each key scanned, with a description of its
116
status.
117
This option suppresses that output.
118
.El
119
.Sh BLACKLIST FILE FORMAT
120
The blacklist file may start with comments, on lines starting with
121
.Dq # .
122
After these initial comments, it must follow a strict format:
123
.Pp
124
.Bl -bullet -offset indent -compact
125
.It
126
All the lines must be exactly the same length (20 characters followed by a
127
newline) and must be in sorted order.
128
.It
129
Each line must consist of the lower-case hexadecimal MD5 key fingerprint,
130
without colons, and with the first 12 characters removed (that is, the least
131
significant 80 bits of the fingerprint).
132
.El
133
.Pp
134
The key fingerprint may be generated using
135
.Xr ssh-keygen 1 :
136
.Pp
137
.Dl $ ssh-keygen -l -f /path/to/key
138
.Pp
139
This strict format is necessary to allow the blacklist file to be checked
140
quickly, using a binary-search algorithm.
141
.Sh SEE ALSO
142
.Xr ssh-keygen 1 ,
143
.Xr sshd 8
144
.Sh AUTHORS
145
.An -nosplit
146
.An Colin Watson Aq cjwatson@ubuntu.com
147
.Pp
148
Florian Weimer suggested the option to check keys of all users, and the idea
149
of processing
150
.Xr ssh-keyscan 1
151
output.
(-)openssh-4.7p1/auth2-hostbased.c (+15 lines)
Lines 40-45 Link Here
40
#include "compat.h"
40
#include "compat.h"
41
#include "key.h"
41
#include "key.h"
42
#include "hostfile.h"
42
#include "hostfile.h"
43
#include "authfile.h"
43
#include "auth.h"
44
#include "auth.h"
44
#include "canohost.h"
45
#include "canohost.h"
45
#ifdef GSSAPI
46
#ifdef GSSAPI
Lines 170-179 int Link Here
170
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
171
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
171
    Key *key)
172
    Key *key)
172
{
173
{
174
	char *fp;
173
	const char *resolvedname, *ipaddr, *lookup;
175
	const char *resolvedname, *ipaddr, *lookup;
174
	HostStatus host_status;
176
	HostStatus host_status;
175
	int len;
177
	int len;
176
178
179
	if (blacklisted_key(key)) {
180
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
181
		if (options.permit_blacklisted_keys)
182
			logit("Public key %s blacklisted (see "
183
			    "ssh-vulnkey(1)); continuing anyway", fp);
184
		else
185
			logit("Public key %s blacklisted (see "
186
			    "ssh-vulnkey(1))", fp);
187
		xfree(fp);
188
		if (!options.permit_blacklisted_keys)
189
			return 0;
190
	}
191
177
	resolvedname = get_canonical_hostname(options.use_dns);
192
	resolvedname = get_canonical_hostname(options.use_dns);
178
	ipaddr = get_remote_ipaddr();
193
	ipaddr = get_remote_ipaddr();
179
194
(-)openssh-4.7p1/authfile.c (+111 lines)
Lines 68-73 Link Here
68
#include "ssh-x509.h"
68
#include "ssh-x509.h"
69
#include "misc.h"
69
#include "misc.h"
70
#include "atomicio.h"
70
#include "atomicio.h"
71
#include "pathnames.h"
71
72
72
/* Version identification string for SSH v1 identity files. */
73
/* Version identification string for SSH v1 identity files. */
73
static const char authfile_id_string[] =
74
static const char authfile_id_string[] =
Lines 696-698 key_load_public(const char *filename, ch Link Here
696
	key_free(pub);
697
	key_free(pub);
697
	return NULL;
698
	return NULL;
698
}
699
}
700
701
char *
702
blacklist_filename(const Key *key)
703
{
704
	char *name;
705
706
	xasprintf(&name, "%s.%s-%u",
707
	    _PATH_BLACKLIST, key_type(key), key_size(key));
708
	return name;
709
}
710
711
/* Scan a blacklist of known-vulnerable keys. */
712
int
713
blacklisted_key(const Key *key)
714
{
715
	char *blacklist_file;
716
	int fd = -1;
717
	char *dgst_hex = NULL;
718
	char *dgst_packed = NULL, *p;
719
	int i;
720
	size_t line_len;
721
	struct stat st;
722
	char buf[256];
723
	off_t start, lower, upper;
724
	int ret = 0;
725
726
	blacklist_file = blacklist_filename(key);
727
	debug("Checking blacklist file %s", blacklist_file);
728
	fd = open(blacklist_file, O_RDONLY);
729
	if (fd < 0)
730
		goto out;
731
732
	dgst_hex = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
733
	/* Remove all colons */
734
	dgst_packed = xcalloc(1, strlen(dgst_hex) + 1);
735
	for (i = 0, p = dgst_packed; dgst_hex[i]; i++)
736
		if (dgst_hex[i] != ':')
737
			*p++ = dgst_hex[i];
738
	/* Only compare least-significant 80 bits (to keep the blacklist
739
	 * size down)
740
	 */
741
	line_len = strlen(dgst_packed + 12);
742
	if (line_len > 32)
743
		goto out;
744
745
	/* Skip leading comments */
746
	start = 0;
747
	for (;;) {
748
		ssize_t r;
749
		char *newline;
750
751
		r = atomicio(read, fd, buf, 256);
752
		if (r <= 0)
753
			goto out;
754
		if (buf[0] != '#')
755
			break;
756
757
		newline = memchr(buf, '\n', 256);
758
		if (!newline)
759
			goto out;
760
		start += newline + 1 - buf;
761
		if (lseek(fd, start, SEEK_SET) < 0)
762
			goto out;
763
	}
764
765
	/* Initialise binary search record numbers */
766
	if (fstat(fd, &st) < 0)
767
		goto out;
768
	lower = 0;
769
	upper = (st.st_size - start) / (line_len + 1);
770
771
	while (lower != upper) {
772
		off_t cur;
773
		char buf[32];
774
		int cmp;
775
776
		cur = lower + (upper - lower) / 2;
777
778
		/* Read this line and compare to digest; this is
779
		 * overflow-safe since cur < max(off_t) / (line_len + 1) */
780
		if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
781
			break;
782
		if (atomicio(read, fd, buf, line_len) != line_len)
783
			break;
784
		cmp = memcmp(buf, dgst_packed + 12, line_len);
785
		if (cmp < 0) {
786
			if (cur == lower)
787
				break;
788
			lower = cur;
789
		} else if (cmp > 0) {
790
			if (cur == upper)
791
				break;
792
			upper = cur;
793
		} else {
794
			debug("Found %s in blacklist", dgst_hex);
795
			ret = 1;
796
			break;
797
		}
798
	}
799
800
out:
801
	if (dgst_packed)
802
		xfree(dgst_packed);
803
	if (dgst_hex)
804
		xfree(dgst_hex);
805
	if (fd >= 0)
806
		close(fd);
807
	xfree(blacklist_file);
808
	return ret;
809
}
(-)openssh-4.7p1/ssh-vulnkey.c (+311 lines)
Line 0 Link Here
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 <string.h>
31
#include <stdio.h>
32
#include <fcntl.h>
33
#include <unistd.h>
34
35
#include <openssl/evp.h>
36
37
#include "xmalloc.h"
38
#include "ssh.h"
39
#include "log.h"
40
#include "key.h"
41
#include "authfile.h"
42
#include "pathnames.h"
43
#include "misc.h"
44
45
extern char *__progname;
46
47
/* Default files to check */
48
static char *default_host_files[] = {
49
	_PATH_HOST_RSA_KEY_FILE,
50
	_PATH_HOST_DSA_KEY_FILE,
51
	_PATH_HOST_KEY_FILE,
52
	NULL
53
};
54
static char *default_files[] = {
55
	_PATH_SSH_CLIENT_ID_RSA,
56
	_PATH_SSH_CLIENT_ID_DSA,
57
	_PATH_SSH_CLIENT_IDENTITY,
58
	_PATH_SSH_USER_PERMITTED_KEYS,
59
	_PATH_SSH_USER_PERMITTED_KEYS2,
60
	NULL
61
};
62
63
static int quiet = 0;
64
65
static void
66
usage(void)
67
{
68
	fprintf(stderr, "usage: %s [-aq] [file ...]\n", __progname);
69
	fprintf(stderr, "Options:\n");
70
	fprintf(stderr, "  -a          Check keys of all users.\n");
71
	fprintf(stderr, "  -q          Quiet mode.\n");
72
	exit(1);
73
}
74
75
void
76
describe_key(const char *msg, const Key *key, const char *comment)
77
{
78
	char *fp;
79
80
	fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
81
	if (!quiet)
82
		printf("%s: %u %s %s\n", msg, key_size(key), fp, comment);
83
	xfree(fp);
84
}
85
86
int
87
do_key(const Key *key, const char *comment)
88
{
89
	char *blacklist_file;
90
	struct stat st;
91
	int ret = 1;
92
93
	blacklist_file = blacklist_filename(key);
94
	if (stat(blacklist_file, &st) < 0)
95
		describe_key("Unknown (no blacklist information)",
96
		    key, comment);
97
	else if (blacklisted_key(key)) {
98
		describe_key("COMPROMISED", key, comment);
99
		ret = 0;
100
	} else
101
		describe_key("Not blacklisted", key, comment);
102
	xfree(blacklist_file);
103
104
	return ret;
105
}
106
107
int
108
do_filename(const char *filename, int quiet_open)
109
{
110
	FILE *f;
111
	char line[SSH_MAX_PUBKEY_BYTES];
112
	char *cp;
113
	u_long linenum = 0;
114
	Key *key;
115
	char *comment = NULL;
116
	int found = 0, ret = 1;
117
118
	/* Copy much of key_load_public's logic here so that we can read
119
	 * several keys from a single file (e.g. authorized_keys).
120
	 */
121
122
	if (strcmp(filename, "-") != 0) {
123
		f = fopen(filename, "r");
124
		if (!f) {
125
			char pubfile[MAXPATHLEN];
126
			if (strlcpy(pubfile, filename, sizeof pubfile) <
127
			    sizeof(pubfile) &&
128
			    strlcat(pubfile, ".pub", sizeof pubfile) <
129
			    sizeof(pubfile))
130
				f = fopen(pubfile, "r");
131
		}
132
		if (!f) {
133
			if (!quiet_open)
134
				perror(filename);
135
			return -1;
136
		}
137
	} else
138
		f = stdin;
139
	while (read_keyfile_line(f, filename, line, sizeof(line),
140
		    &linenum) != -1) {
141
		cp = line;
142
		switch (*cp) {
143
		case '#':
144
		case '\n':
145
		case '\0':
146
			continue;
147
		}
148
		/* Skip leading whitespace. */
149
		for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
150
			;
151
		/* Cope with ssh-keyscan output. */
152
		comment = NULL;
153
		if (*cp) {
154
			char *space;
155
			int type;
156
157
			space = strchr(cp, ' ');
158
			if (!space)
159
				continue;
160
			*space = '\0';
161
			type = key_type_from_name(cp);
162
			if (type == KEY_UNSPEC) {
163
				comment = xstrdup(cp);
164
				cp = space + 1;
165
			}
166
			*space = ' ';
167
		}
168
		if (!comment)
169
			comment = xstrdup(filename);
170
		if (*cp) {
171
			key = key_new(KEY_RSA1);
172
			if (key_read(key, &cp) == 1) {
173
				if (!do_key(key, comment))
174
					ret = 0;
175
				key_free(key);
176
				found = 1;
177
			} else {
178
				key_free(key);
179
				key = key_new(KEY_UNSPEC);
180
				if (key_read(key, &cp) == 1) {
181
					if (!do_key(key, comment))
182
						ret = 0;
183
					key_free(key);
184
					found = 1;
185
				}
186
			}
187
		}
188
		xfree(comment);
189
		comment = NULL;
190
	}
191
	if (f != stdin)
192
		fclose(f);
193
194
	if (!found && filename) {
195
		key = key_load_public(filename, &comment);
196
		if (key) {
197
			if (!do_key(key, comment))
198
				ret = 0;
199
			found = 1;
200
		}
201
		if (comment)
202
			xfree(comment);
203
	}
204
205
	return ret;
206
}
207
208
int
209
do_host(void)
210
{
211
	int i;
212
	struct stat st;
213
	int ret = 1;
214
215
	for (i = 0; default_host_files[i]; i++) {
216
		if (stat(default_host_files[i], &st) < 0)
217
			continue;
218
		if (!do_filename(default_host_files[i], 1))
219
			ret = 0;
220
	}
221
222
	return ret;
223
}
224
225
int
226
do_user(const char *dir)
227
{
228
	int i;
229
	char buf[MAXPATHLEN];
230
	struct stat st;
231
	int ret = 1;
232
233
	for (i = 0; default_files[i]; i++) {
234
		snprintf(buf, sizeof(buf), "%s/%s", dir, default_files[i]);
235
		if (stat(buf, &st) < 0)
236
			continue;
237
		if (!do_filename(buf, 0))
238
			ret = 0;
239
	}
240
241
	return ret;
242
}
243
244
int
245
main(int argc, char **argv)
246
{
247
	int opt, all_users = 0;
248
	int ret = 1;
249
	extern int optind;
250
251
	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
252
	sanitise_stdfd();
253
254
	__progname = ssh_get_progname(argv[0]);
255
256
	SSLeay_add_all_algorithms();
257
	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
258
259
	/* We don't need the RNG ourselves, but symbol references here allow
260
	 * ld to link us properly.
261
	 */
262
	init_rng();
263
	seed_rng();
264
265
	while ((opt = getopt(argc, argv, "ahq")) != -1) {
266
		switch (opt) {
267
		case 'a':
268
			all_users = 1;
269
			break;
270
		case 'q':
271
			quiet = 1;
272
			break;
273
		case 'h':
274
		default:
275
			usage();
276
		}
277
	}
278
279
	if (all_users) {
280
		struct passwd *pw;
281
282
		if (!do_host())
283
			ret = 0;
284
285
		while ((pw = getpwent()) != NULL) {
286
			if (pw->pw_dir) {
287
				if (!do_user(pw->pw_dir))
288
					ret = 0;
289
			}
290
		}
291
	} else if (optind == argc) {
292
		struct passwd *pw;
293
294
		if (!do_host())
295
			ret = 0;
296
297
		if ((pw = getpwuid(getuid())) == NULL)
298
			fprintf(stderr, "No user found with uid %u\n",
299
			    (u_int)getuid());
300
		else {
301
			if (!do_user(pw->pw_dir))
302
				ret = 0;
303
		}
304
	} else {
305
		while (optind < argc)
306
			if (!do_filename(argv[optind++], 0))
307
				ret = 0;
308
	}
309
310
	return ret;
311
}
(-)openssh-4.7p1/auth-rsa.c (+15 lines)
Lines 40-45 Link Here
40
#include "servconf.h"
40
#include "servconf.h"
41
#include "key.h"
41
#include "key.h"
42
#include "hostfile.h"
42
#include "hostfile.h"
43
#include "authfile.h"
43
#include "auth.h"
44
#include "auth.h"
44
#ifdef GSSAPI
45
#ifdef GSSAPI
45
#include "ssh-gss.h"
46
#include "ssh-gss.h"
Lines 221-226 auth_rsa_key_allowed(struct passwd *pw, Link Here
221
		char *cp;
222
		char *cp;
222
		char *key_options;
223
		char *key_options;
223
		int keybits;
224
		int keybits;
225
		char *fp;
224
226
225
		/* Skip leading whitespace, empty and comment lines. */
227
		/* Skip leading whitespace, empty and comment lines. */
226
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
228
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
Lines 265-270 auth_rsa_key_allowed(struct passwd *pw, Link Here
265
			    "actual %d vs. announced %d.",
267
			    "actual %d vs. announced %d.",
266
			    file, linenum, BN_num_bits(key->rsa->n), bits);
268
			    file, linenum, BN_num_bits(key->rsa->n), bits);
267
269
270
		if (blacklisted_key(key)) {
271
			fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
272
			if (options.permit_blacklisted_keys)
273
				logit("Public key %s blacklisted (see "
274
				    "ssh-vulnkey(1)); continuing anyway", fp);
275
			else
276
				logit("Public key %s blacklisted (see "
277
				    "ssh-vulnkey(1))", fp);
278
			xfree(fp);
279
			if (!options.permit_blacklisted_keys)
280
				continue;
281
		}
282
268
		/* We have found the desired key. */
283
		/* We have found the desired key. */
269
		/*
284
		/*
270
		 * If our options do not allow this key to be used,
285
		 * If our options do not allow this key to be used,
(-)openssh-4.7p1/pathnames.h (+2 lines)
Lines 66-71 Link Here
66
/* Backwards compatibility */
66
/* Backwards compatibility */
67
#define _PATH_DH_PRIMES			SSHDIR "/primes"
67
#define _PATH_DH_PRIMES			SSHDIR "/primes"
68
68
69
#define _PATH_BLACKLIST			SSHDIR "/blacklist"
70
69
#ifndef _PATH_SSH_PROGRAM
71
#ifndef _PATH_SSH_PROGRAM
70
#define _PATH_SSH_PROGRAM		"/usr/bin/ssh"
72
#define _PATH_SSH_PROGRAM		"/usr/bin/ssh"
71
#endif
73
#endif
(-)openssh-4.7p1/auth2-pubkey.c (+15 lines)
Lines 47-52 Link Here
47
#include "compat.h"
47
#include "compat.h"
48
#include "key.h"
48
#include "key.h"
49
#include "hostfile.h"
49
#include "hostfile.h"
50
#include "authfile.h"
50
#include "auth.h"
51
#include "auth.h"
51
#include "pathnames.h"
52
#include "pathnames.h"
52
#include "uidswap.h"
53
#include "uidswap.h"
Lines 411-419 user_key_allowed2(struct passwd *pw, Key Link Here
411
int
412
int
412
user_key_allowed(struct passwd *pw, Key *key)
413
user_key_allowed(struct passwd *pw, Key *key)
413
{
414
{
415
	char *fp;
414
	int success;
416
	int success;
415
	char *file;
417
	char *file;
416
418
419
	if (blacklisted_key(key)) {
420
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
421
		if (options.permit_blacklisted_keys)
422
			logit("Public key %s blacklisted (see "
423
			    "ssh-vulnkey(1)); continuing anyway", fp);
424
		else
425
			logit("Public key %s blacklisted (see "
426
			    "ssh-vulnkey(1))", fp);
427
		xfree(fp);
428
		if (!options.permit_blacklisted_keys)
429
			return 0;
430
	}
431
417
	file = authorized_keys_file(pw);
432
	file = authorized_keys_file(pw);
418
	success = user_key_allowed2(pw, key, file);
433
	success = user_key_allowed2(pw, key, file);
419
	xfree(file);
434
	xfree(file);

Return to bug 221759