View | Details | Raw Unified | Return to bug 2436 | Differences between
and this patch

Collapse All | Expand All

(-)a/readconf.c (+48 lines)
Lines 135-140 typedef enum { Link Here
135
	oPasswordAuthentication, oRSAAuthentication,
135
	oPasswordAuthentication, oRSAAuthentication,
136
	oChallengeResponseAuthentication, oXAuthLocation,
136
	oChallengeResponseAuthentication, oXAuthLocation,
137
	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
137
	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
138
	oCertificateFile,
138
	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
139
	oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
139
	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
140
	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
140
	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
141
	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
Lines 202-207 static struct { Link Here
202
	{ "identityfile", oIdentityFile },
203
	{ "identityfile", oIdentityFile },
203
	{ "identityfile2", oIdentityFile },			/* obsolete */
204
	{ "identityfile2", oIdentityFile },			/* obsolete */
204
	{ "identitiesonly", oIdentitiesOnly },
205
	{ "identitiesonly", oIdentitiesOnly },
206
	{ "certificatefile", oCertificateFile },
205
	{ "hostname", oHostName },
207
	{ "hostname", oHostName },
206
	{ "hostkeyalias", oHostKeyAlias },
208
	{ "hostkeyalias", oHostKeyAlias },
207
	{ "proxycommand", oProxyCommand },
209
	{ "proxycommand", oProxyCommand },
Lines 366-371 clear_forwardings(Options *options) Link Here
366
}
368
}
367
369
368
void
370
void
371
add_certificate_file(Options *options, const char *dir, const char *filename,
372
    int userprovided)
373
{
374
	char *path;
375
	int i;
376
377
	if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
378
		fatal("Too many certificate files specified (max %d)",
379
		    SSH_MAX_CERTIFICATE_FILES);
380
381
	if (dir == NULL) /* no dir, filename is absolute */
382
		path = xstrdup(filename);
383
	else
384
		(void)xasprintf(&path, "%.100s%.100s", dir, filename);
385
386
	/* Avoid registering duplicates */
387
	for (i = 0; i < options->num_certificate_files; i++) {
388
		if (options->certificate_file_userprovided[i] == userprovided &&
389
		    strcmp(options->certificate_files[i], path) == 0) {
390
			debug2("%s: ignoring duplicate key %s", __func__, path);
391
			free(path);
392
			return;
393
		}
394
	}
395
396
	options->certificate_file_userprovided[options->num_certificate_files] =
397
	    userprovided;
398
	options->certificate_files[options->num_certificate_files++] = path;
399
}
400
401
void
369
add_identity_file(Options *options, const char *dir, const char *filename,
402
add_identity_file(Options *options, const char *dir, const char *filename,
370
    int userprovided)
403
    int userprovided)
371
{
404
{
Lines 981-986 parse_time: Link Here
981
		}
1014
		}
982
		break;
1015
		break;
983
1016
1017
	case oCertificateFile:
1018
		arg = strdelim(&s);
1019
		if (!arg || *arg == '\0')
1020
			fatal("%.200s line %d: Missing argument.", filename, linenum);
1021
		if (*activep) {
1022
			intptr = &options->num_certificate_files;
1023
			if (*intptr >= SSH_MAX_CERTIFICATE_FILES)
1024
				fatal("%.200s line %d: Too many identity files specified (max %d).",
1025
				    filename, linenum, SSH_MAX_CERTIFICATE_FILES);
1026
			add_certificate_file(options, NULL,
1027
			    arg, flags & SSHCONF_USERCONF);
1028
		}
1029
		break;
1030
984
	case oXAuthLocation:
1031
	case oXAuthLocation:
985
		charptr=&options->xauth_location;
1032
		charptr=&options->xauth_location;
986
		goto parse_string;
1033
		goto parse_string;
Lines 1625-1630 initialize_options(Options * options) Link Here
1625
	options->hostkeyalgorithms = NULL;
1672
	options->hostkeyalgorithms = NULL;
1626
	options->protocol = SSH_PROTO_UNKNOWN;
1673
	options->protocol = SSH_PROTO_UNKNOWN;
1627
	options->num_identity_files = 0;
1674
	options->num_identity_files = 0;
1675
	options->num_certificate_files = 0; 
1628
	options->hostname = NULL;
1676
	options->hostname = NULL;
1629
	options->host_key_alias = NULL;
1677
	options->host_key_alias = NULL;
1630
	options->proxy_command = NULL;
1678
	options->proxy_command = NULL;
(-)a/readconf.h (+6 lines)
Lines 94-99 typedef struct { Link Here
94
	char   *identity_files[SSH_MAX_IDENTITY_FILES];
94
	char   *identity_files[SSH_MAX_IDENTITY_FILES];
95
	int    identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
95
	int    identity_file_userprovided[SSH_MAX_IDENTITY_FILES];
96
	struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
96
	struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
97
	
98
	int	num_certificate_files; /* Number of extra certificates for ssh. */
99
	char	*certificate_files[SSH_MAX_CERTIFICATE_FILES];
100
	int	certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
101
	struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
97
102
98
	/* Local TCP/IP forward requests. */
103
	/* Local TCP/IP forward requests. */
99
	int     num_local_forwards;
104
	int     num_local_forwards;
Lines 194-198 void dump_client_config(Options *o, const char *host); Link Here
194
void	 add_local_forward(Options *, const struct Forward *);
199
void	 add_local_forward(Options *, const struct Forward *);
195
void	 add_remote_forward(Options *, const struct Forward *);
200
void	 add_remote_forward(Options *, const struct Forward *);
196
void	 add_identity_file(Options *, const char *, const char *, int);
201
void	 add_identity_file(Options *, const char *, const char *, int);
202
void	 add_certificate_file(Options *, const char *, const char *, int);
197
203
198
#endif				/* READCONF_H */
204
#endif				/* READCONF_H */
(-)a/regress/Makefile (+1 lines)
Lines 74-79 LTESTS= connect \ Link Here
74
		hostkey-agent \
74
		hostkey-agent \
75
		keygen-knownhosts \
75
		keygen-knownhosts \
76
		hostkey-rotate \
76
		hostkey-rotate \
77
		ssh-cert \
77
		principals-command
78
		principals-command
78
79
79
80
(-)a/regress/ssh-cert.sh (+136 lines)
Line 0 Link Here
1
#	$OpenBSD: multicert.sh,v 1.1 2014/12/22 08:06:03 djm Exp $
2
#	Placed in the Public Domain.
3
4
tid="ssh with certificates"
5
6
rm -f $OBJ/user_ca_key* $OBJ/user_key*
7
rm -f $OBJ/cert_user_key*
8
9
# Create a CA key
10
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key1 ||\
11
	fatal "ssh-keygen failed"
12
${SSHKEYGEN} -q -N '' -t ed25519  -f $OBJ/user_ca_key2 ||\
13
	fatal "ssh-keygen failed"
14
15
# Make some keys and certificates.
16
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \
17
	fatal "ssh-keygen failed"
18
${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \
19
	fatal "ssh-keygen failed"
20
# Move the certificate to a different address to better control
21
# when it is offered.
22
${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \
23
	-z $$ -n ${USER} $OBJ/user_key1 ||
24
		fail "couldn't sign user_key1 with user_ca_key1"
25
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_1.pub
26
${SSHKEYGEN} -q -s $OBJ/user_ca_key2 -I "regress user key for $USER" \
27
	-z $$ -n ${USER} $OBJ/user_key1 ||
28
		fail "couldn't sign user_key1 with user_ca_key2"
29
mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub
30
31
trace 'try with identity files'
32
opts="-F $OBJ/ssh_proxy -oIdentitiesOnly=yes"
33
opts2="$opts -i $OBJ/user_key1 -i $OBJ/user_key2"
34
echo "cert-authority $(cat $OBJ/user_ca_key1.pub)" > $OBJ/authorized_keys_$USER
35
36
for p in ${SSH_PROTOCOLS}; do
37
	# Just keys should fail
38
	${SSH} $opts2 somehost exit 5$p
39
	r=$?
40
	if [ $r -eq 5$p ]; then
41
		fail "ssh succeeded with no certs in protocol $p"
42
	fi
43
44
	# Keys with untrusted cert should fail.
45
	opts3="$opts2 -z $OBJ/cert_user_key1_2.pub"
46
	${SSH} $opts3 somehost exit 5$p
47
	r=$?
48
	if [ $r -eq 5$p ]; then
49
		fail "ssh succeeded with bad cert in protocol $p"
50
	fi
51
52
	# Good cert with bad key should fail.
53
	opts3="$opts -i $OBJ/user_key2 -z $OBJ/cert_user_key1_1.pub"
54
	${SSH} $opts3 somehost exit 5$p
55
	r=$?
56
	if [ $r -eq 5$p ]; then
57
		fail "ssh succeeded with no matching key in protocol $p"
58
	fi
59
60
	# Keys with one trusted cert, should succeed.
61
	opts3="$opts2 -z $OBJ/cert_user_key1_1.pub"
62
	${SSH} $opts3 somehost exit 5$p
63
	r=$?
64
	if [ $r -ne 5$p ]; then
65
		fail "ssh failed with trusted cert and key in protocol $p"
66
	fi
67
68
	# Multiple certs and keys, with one trusted cert, should succeed.
69
	opts3="$opts2 -z $OBJ/cert_user_key1_2.pub -z $OBJ/cert_user_key1_1.pub"
70
	${SSH} $opts3 somehost exit 5$p
71
	r=$?
72
	if [ $r -ne 5$p ]; then
73
		fail "ssh failed with multiple certs in protocol $p"
74
	fi
75
76
	#Keys with trusted certificate specified in config options, should succeed.
77
	opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
78
	${SSH} $opts3 somehost exit 5$p
79
	r=$?
80
	if [ $r -ne 5$p ]; then
81
		fail "ssh failed with trusted cert in config in protocol $p"
82
	fi
83
done
84
85
#next, using an agent in combination with the keys
86
SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
87
if [ $? -ne 2 ]; then
88
	fatal "ssh-add -l did not fail with exit code 2"
89
fi
90
91
trace "start agent"
92
eval `${SSHAGENT} -s` > /dev/null
93
r=$?
94
if [ $r -ne 0 ]; then
95
	fatal "could not start ssh-agent: exit code $r"
96
fi
97
98
# add private keys to agent
99
${SSHADD} -k $OBJ/user_key2 > /dev/null 2>&1
100
if [ $? -ne 0 ]; then
101
	fatal "ssh-add did not succeed with exit code 0"
102
fi
103
${SSHADD} -k $OBJ/user_key1 > /dev/null 2>&1
104
if [ $? -ne 0 ]; then
105
	fatal "ssh-add did not succeed with exit code 0"
106
fi
107
108
# try ssh with the agent and certificates
109
# note: ssh agent only uses certificates in protocol 2
110
opts="-F $OBJ/ssh_proxy"
111
# with no certificates, shoud fail
112
${SSH} -2 $opts somehost exit 52
113
if [ $? -eq 52 ]; then
114
	fail "ssh connect with agent in protocol 2 succeeded with no cert"
115
fi
116
117
#with an untrusted certificate, should fail
118
opts="$opts -z $OBJ/cert_user_key1_2.pub"
119
${SSH} -2 $opts somehost exit 52
120
if [ $? -eq 52 ]; then
121
	fail "ssh connect with agent in protocol 2 succeeded with bad cert"
122
fi
123
124
#with an additional trusted certificate, should succeed
125
opts="$opts -z $OBJ/cert_user_key1_1.pub"
126
${SSH} -2 $opts somehost exit 52
127
if [ $? -ne 52 ]; then
128
	fail "ssh connect with agent in protocol 2 failed with good cert"
129
fi
130
131
trace "kill agent"
132
${SSHAGENT} -k > /dev/null
133
134
#cleanup
135
rm -f $OBJ/user_ca_key* $OBJ/user_key*
136
rm -f $OBJ/cert_user_key*
(-)a/ssh.1 (+17 lines)
Lines 63-68 Link Here
63
.Op Fl S Ar ctl_path
63
.Op Fl S Ar ctl_path
64
.Op Fl W Ar host : Ns Ar port
64
.Op Fl W Ar host : Ns Ar port
65
.Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun
65
.Op Fl w Ar local_tun Ns Op : Ns Ar remote_tun
66
.Op Fl z Ar certificate_file
66
.Oo Ar user Ns @ Oc Ns Ar hostname
67
.Oo Ar user Ns @ Oc Ns Ar hostname
67
.Op Ar command
68
.Op Ar command
68
.Ek
69
.Ek
Lines 468-473 For full details of the options listed below, and their possible values, see Link Here
468
.It CanonicalizeHostname
469
.It CanonicalizeHostname
469
.It CanonicalizeMaxDots
470
.It CanonicalizeMaxDots
470
.It CanonicalizePermittedCNAMEs
471
.It CanonicalizePermittedCNAMEs
472
.It CertificateFile
471
.It ChallengeResponseAuthentication
473
.It ChallengeResponseAuthentication
472
.It CheckHostIP
474
.It CheckHostIP
473
.It Cipher
475
.It Cipher
Lines 768-773 Send log information using the Link Here
768
.Xr syslog 3
770
.Xr syslog 3
769
system module.
771
system module.
770
By default this information is sent to stderr.
772
By default this information is sent to stderr.
773
.It Fl z Ar certificate_file
774
Selects a file from which certificate information is loaded for public
775
key authentication. For the certificate to be signed, the private key
776
corresponding to 
777
.Ar certificate_file
778
must also be provided for authentication, whether through
779
.Xr ssh_agent 1 .
780
or through an
781
.Ar identity_file
782
specified on the command line or in configuration files.
783
Certificate files may also be specified on a per-host basis in
784
the configuration file. It is possible to have multiple
785
.Fl z
786
options (and multiple certificates specified in
787
configuration files).
771
.El
788
.El
772
.Pp
789
.Pp
773
.Nm
790
.Nm
(-)a/ssh.c (-2 / +83 lines)
Lines 207-213 usage(void) Link Here
207
"           [-O ctl_cmd] [-o option] [-p port]\n"
207
"           [-O ctl_cmd] [-o option] [-p port]\n"
208
"           [-Q cipher | cipher-auth | mac | kex | key]\n"
208
"           [-Q cipher | cipher-auth | mac | kex | key]\n"
209
"           [-R address] [-S ctl_path] [-W host:port]\n"
209
"           [-R address] [-S ctl_path] [-W host:port]\n"
210
"           [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
210
"           [-w local_tun[:remote_tun]] [-z certificate_file]\n"
211
"           [user@]hostname [command]\n"
211
	);
212
	);
212
	exit(255);
213
	exit(255);
213
}
214
}
Lines 215-220 usage(void) Link Here
215
static int ssh_session(void);
216
static int ssh_session(void);
216
static int ssh_session2(void);
217
static int ssh_session2(void);
217
static void load_public_identity_files(void);
218
static void load_public_identity_files(void);
219
static void load_certificate_files(void);
218
static void main_sigchld_handler(int);
220
static void main_sigchld_handler(int);
219
221
220
/* from muxclient.c */
222
/* from muxclient.c */
Lines 595-601 main(int ac, char **av) Link Here
595
597
596
 again:
598
 again:
597
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
599
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
598
	    "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
600
	    "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYyz:")) != -1) {
599
		switch (opt) {
601
		switch (opt) {
600
		case '1':
602
		case '1':
601
			options.protocol = SSH_PROTO_1;
603
			options.protocol = SSH_PROTO_1;
Lines 906-911 main(int ac, char **av) Link Here
906
		case 'F':
908
		case 'F':
907
			config = optarg;
909
			config = optarg;
908
			break;
910
			break;
911
		case 'z':
912
			add_certificate_file(&options, NULL, optarg, 1);
913
			break;
909
		default:
914
		default:
910
			usage();
915
			usage();
911
		}
916
		}
Lines 1013-1018 main(int ac, char **av) Link Here
1013
		options.hostname = xstrdup(host);
1018
		options.hostname = xstrdup(host);
1014
	}
1019
	}
1015
1020
1021
	/* If the user has specified certificate(s), load it now. */
1022
	load_certificate_files();
1023
1016
	/* If canonicalization requested then try to apply it */
1024
	/* If canonicalization requested then try to apply it */
1017
	lowercase(host);
1025
	lowercase(host);
1018
	if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
1026
	if (options.canonicalize_hostname != SSH_CANONICALISE_NO)
Lines 1353-1358 main(int ac, char **av) Link Here
1353
		}
1361
		}
1354
	}
1362
	}
1355
1363
1364
	for (i = 0; i < options.num_certificate_files; i++) {
1365
		free(options.certificate_files[i]);
1366
		options.certificate_files[i] = NULL;
1367
	}
1368
1369
1370
1356
	exit_status = compat20 ? ssh_session2() : ssh_session();
1371
	exit_status = compat20 ? ssh_session2() : ssh_session();
1357
	packet_close();
1372
	packet_close();
1358
1373
Lines 1938-1943 ssh_session2(void) Link Here
1938
	    options.escape_char : SSH_ESCAPECHAR_NONE, id);
1953
	    options.escape_char : SSH_ESCAPECHAR_NONE, id);
1939
}
1954
}
1940
1955
1956
/* Load certificate file(s) specified in options. */
1957
static void 
1958
load_certificate_files(void)
1959
{
1960
	char *filename, *cp, thishost[NI_MAXHOST];
1961
	char *pwdir = NULL, *pwname = NULL;
1962
	struct passwd *pw;
1963
	int i, n_ids;
1964
	struct sshkey *cert;
1965
	char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
1966
	struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
1967
1968
	n_ids = 0;
1969
	memset(certificate_files, 0, sizeof(certificate_files));
1970
	memset(certificates, 0, sizeof(certificates));
1971
	
1972
	if ((pw = getpwuid(original_real_uid)) == NULL)
1973
		fatal("load_certificate_files: getpwuid failed");
1974
	pwname = xstrdup(pw->pw_name);
1975
	pwdir = xstrdup(pw->pw_dir);
1976
	if (gethostname(thishost, sizeof(thishost)) == -1)
1977
		fatal("load_certificate_files: gethostname: %s",
1978
		    strerror(errno));
1979
	
1980
	if (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES)
1981
		fatal("load_certificate_files: too many certificates");
1982
	for (i = 0; i < options.num_certificate_files; i++) {
1983
		cp = tilde_expand_filename(options.certificate_files[i],
1984
		    original_real_uid);
1985
		filename = percent_expand(cp, "d", pwdir,
1986
		    "u", pwname, "l", thishost, "h", host,
1987
		    "r", options.user, (char *)NULL);
1988
		free(cp);
1989
		
1990
		cert = key_load_public(filename, NULL);
1991
		debug("certificate file %s type %d", filename,
1992
		    cert ? cert->type : -1);
1993
		free(options.certificate_files[i]);
1994
		if (cert == NULL) {
1995
			free(filename);
1996
			continue;
1997
		}
1998
		if (!key_is_cert(cert)) {
1999
			debug("%s: key %s type %s is not a certificate",
2000
			    __func__, filename, key_type(cert));
2001
			key_free(cert);
2002
			free(filename);
2003
			continue;
2004
		}
2005
2006
		certificate_files[n_ids] = filename;
2007
		certificates[n_ids] = cert;
2008
		++n_ids;
2009
	}
2010
	options.num_certificate_files = n_ids;
2011
	memcpy(options.certificate_files, certificate_files, sizeof(certificate_files));
2012
	memcpy(options.certificates, certificates, sizeof(certificates));
2013
2014
	explicit_bzero(pwname, strlen(pwname));
2015
	free(pwname);
2016
	explicit_bzero(pwdir, strlen(pwdir));
2017
	free(pwdir);
2018
}
2019
2020
2021
1941
static void
2022
static void
1942
load_public_identity_files(void)
2023
load_public_identity_files(void)
1943
{
2024
{
(-)a/ssh.h (+7 lines)
Lines 19-24 Link Here
19
#define SSH_DEFAULT_PORT	22
19
#define SSH_DEFAULT_PORT	22
20
20
21
/*
21
/*
22
 * Maximum number of certificate files that can be specified
23
 * in configuration files or on the command line.
24
 */
25
#define SSH_MAX_CERTIFICATE_FILES	100
26
27
28
/*
22
 * Maximum number of RSA authentication identity files that can be specified
29
 * Maximum number of RSA authentication identity files that can be specified
23
 * in configuration files or on the command line.
30
 * in configuration files or on the command line.
24
 */
31
 */
(-)a/ssh_config.5 (+33 lines)
Lines 325-330 to be canonicalized to names in the Link Here
325
or
325
or
326
.Dq *.c.example.com
326
.Dq *.c.example.com
327
domains.
327
domains.
328
.It Cm CertificateFile
329
Specifies a file from which the user's certificate is read.
330
A corresponding private key must be provided separately in order
331
to use this certificate.
332
.Xr ssh 1
333
will attempt to use private keys provided as identity files
334
or in the agent for such authentication.
335
.Pp
336
The file name may use the tilde
337
syntax to refer to a user's home directory or one of the following
338
escape characters:
339
.Ql %d
340
(local user's home directory),
341
.Ql %u
342
(local user name),
343
.Ql %l
344
(local host name),
345
.Ql %h
346
(remote host name) or
347
.Ql %r
348
(remote user name).
349
.Pp
350
It is possible to have multiple certificate files specified in
351
configuration files; these certificates will be tried in sequence.
352
Multiple
353
.Cm CertificateFile
354
directives will add to the list of certificates used for
355
authentication.
328
.It Cm ChallengeResponseAuthentication
356
.It Cm ChallengeResponseAuthentication
329
Specifies whether to use challenge-response authentication.
357
Specifies whether to use challenge-response authentication.
330
The argument to this keyword must be
358
The argument to this keyword must be
Lines 911-916 differs from that of other configuration directives). Link Here
911
may be used in conjunction with
939
may be used in conjunction with
912
.Cm IdentitiesOnly
940
.Cm IdentitiesOnly
913
to select which identities in an agent are offered during authentication.
941
to select which identities in an agent are offered during authentication.
942
.Cm IdentityFile
943
may also be used in conjunction with
944
.Cm CertificateFile
945
in order to provide any certificate also needed for authentication with
946
the identity.
914
.It Cm IgnoreUnknown
947
.It Cm IgnoreUnknown
915
Specifies a pattern-list of unknown options to be ignored if they are
948
Specifies a pattern-list of unknown options to be ignored if they are
916
encountered in configuration parsing.
949
encountered in configuration parsing.
(-)a/sshconnect2.c (-4 / +44 lines)
Lines 1016-1021 sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Link Here
1016
	u_int skip = 0;
1016
	u_int skip = 0;
1017
	int ret = -1;
1017
	int ret = -1;
1018
	int have_sig = 1;
1018
	int have_sig = 1;
1019
	int i;
1019
	char *fp;
1020
	char *fp;
1020
1021
1021
	if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
1022
	if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
Lines 1053-1058 sign_and_send_pubkey(Authctxt *authctxt, Identity *id) Link Here
1053
	}
1054
	}
1054
	buffer_put_string(&b, blob, bloblen);
1055
	buffer_put_string(&b, blob, bloblen);
1055
1056
1057
	/* If the key is an input certificate, sign its private key instead. 
1058
	 * If no such private key exists, return failure and continue with
1059
	 * other methods of authentication.
1060
	 * Else, just continue with the normal signing process. */
1061
	if (key_is_cert(id->key)) {
1062
		for (i = 0; i < options.num_certificate_files; i++) {
1063
			if (key_equal(id->key, options.certificates[i])) {
1064
				Identity *id2;
1065
				int matched = 0;
1066
				TAILQ_FOREACH(id2, &authctxt->keys, next) {
1067
					if (sshkey_equal_public(id->key, id2->key) &&
1068
					    id->key->type != id2->key->type) {
1069
						id = id2;
1070
						matched = 1;
1071
						break;
1072
					}
1073
				}
1074
				if (!matched) {
1075
					free(blob);
1076
					buffer_free(&b);
1077
					return 0;
1078
				}
1079
				break;
1080
			}
1081
		}
1082
	}
1083
	
1056
	/* generate signature */
1084
	/* generate signature */
1057
	ret = identity_sign(id, &signature, &slen,
1085
	ret = identity_sign(id, &signature, &slen,
1058
	    buffer_ptr(&b), buffer_len(&b), datafellows);
1086
	    buffer_ptr(&b), buffer_len(&b), datafellows);
Lines 1189-1197 load_identity_file(char *filename, int userprovided) Link Here
1189
1217
1190
/*
1218
/*
1191
 * try keys in the following order:
1219
 * try keys in the following order:
1192
 *	1. agent keys that are found in the config file
1220
 * 	1. certificates listed in the config file
1193
 *	2. other agent keys
1221
 * 	2. other input certificates
1194
 *	3. keys that are only listed in the config file
1222
 *	3. agent keys that are found in the config file
1223
 *	4. other agent keys
1224
 *	5. keys that are only listed in the config file
1195
 */
1225
 */
1196
static void
1226
static void
1197
pubkey_prepare(Authctxt *authctxt)
1227
pubkey_prepare(Authctxt *authctxt)
Lines 1245-1250 pubkey_prepare(Authctxt *authctxt) Link Here
1245
			free(id);
1275
			free(id);
1246
		}
1276
		}
1247
	}
1277
	}
1278
	/* list of certificates specified by user */
1279
	for (i = 0; i < options.num_certificate_files; i++) {
1280
		key = options.certificates[i];
1281
		if (!key_is_cert(key))
1282
			continue;
1283
		id = xcalloc(1, sizeof(*id));
1284
		id->key = key;
1285
		id->filename = xstrdup(options.certificate_files[i]);
1286
		id->userprovided = options.certificate_file_userprovided[i];
1287
		TAILQ_INSERT_TAIL(preferred, id, next);
1288
	}
1248
	/* list of keys supported by the agent */
1289
	/* list of keys supported by the agent */
1249
	if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
1290
	if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
1250
		if (r != SSH_ERR_AGENT_NOT_PRESENT)
1291
		if (r != SSH_ERR_AGENT_NOT_PRESENT)
1251
- 

Return to bug 2436