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

Collapse All | Expand All

(-)openssh/auth2-passwd.c (+1 lines)
Lines 74-79 Link Here
74
#endif
74
#endif
75
	memset(password, 0, len);
75
	memset(password, 0, len);
76
	xfree(password);
76
	xfree(password);
77
	auth2_multiple_auth("password", authctxt, &authenticated);
77
	return authenticated;
78
	return authenticated;
78
}
79
}
79
80
(-)openssh/auth2-pubkey.c (-23 / +10 lines)
Lines 1-4 Link Here
1
/* $OpenBSD: auth2-pubkey.c,v 1.16 2008/06/13 04:40:22 djm Exp $ */
1
/* $OpenBSD: auth2-pubkey.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */
2
/*
2
/*
3
 * Copyright (c) 2000 Markus Friedl.  All rights reserved.
3
 * Copyright (c) 2000 Markus Friedl.  All rights reserved.
4
 *
4
 *
Lines 28-34 Link Here
28
#include <sys/types.h>
28
#include <sys/types.h>
29
#include <sys/stat.h>
29
#include <sys/stat.h>
30
30
31
#include <fcntl.h>
32
#include <pwd.h>
31
#include <pwd.h>
33
#include <stdio.h>
32
#include <stdio.h>
34
#include <stdarg.h>
33
#include <stdarg.h>
Lines 140-145 Link Here
140
			authenticated = 1;
139
			authenticated = 1;
141
		buffer_free(&b);
140
		buffer_free(&b);
142
		xfree(sig);
141
		xfree(sig);
142
		auth2_multiple_auth("publickey", authctxt, &authenticated);
143
	} else {
143
	} else {
144
		debug("test whether pkalg/pkblob are acceptable");
144
		debug("test whether pkalg/pkblob are acceptable");
145
		packet_check_eom();
145
		packet_check_eom();
Lines 181-187 Link Here
181
user_key_allowed2(struct passwd *pw, Key *key, char *file)
181
user_key_allowed2(struct passwd *pw, Key *key, char *file)
182
{
182
{
183
	char line[SSH_MAX_PUBKEY_BYTES];
183
	char line[SSH_MAX_PUBKEY_BYTES];
184
	int found_key = 0, fd;
184
	int found_key = 0;
185
	FILE *f;
185
	FILE *f;
186
	u_long linenum = 0;
186
	u_long linenum = 0;
187
	struct stat st;
187
	struct stat st;
Lines 193-221 Link Here
193
193
194
	debug("trying public key file %s", file);
194
	debug("trying public key file %s", file);
195
195
196
	/*
196
	/* Fail quietly if file does not exist */
197
	 * Open the file containing the authorized keys
197
	if (stat(file, &st) < 0) {
198
	 * Fail quietly if file does not exist
198
		/* Restore the privileged uid. */
199
	 */
200
	if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
201
		restore_uid();
199
		restore_uid();
202
		return 0;
200
		return 0;
203
	}
201
	}
204
	if (fstat(fd, &st) < 0) {
202
	/* Open the file containing the authorized keys. */
205
		close(fd);
203
	f = fopen(file, "r");
206
		restore_uid();
204
	if (!f) {
207
		return 0;
205
		/* Restore the privileged uid. */
208
	}
209
	if (!S_ISREG(st.st_mode)) {
210
		logit("User %s authorized keys %s is not a regular file",
211
		    pw->pw_name, file);
212
		close(fd);
213
		restore_uid();
214
		return 0;
215
	}
216
	unset_nonblock(fd);
217
	if ((f = fdopen(fd, "r")) == NULL) {
218
		close(fd);
219
		restore_uid();
206
		restore_uid();
220
		return 0;
207
		return 0;
221
	}
208
	}
(-)openssh/auth2.c (-1 / +44 lines)
Lines 251-258 Link Here
251
	/* Log before sending the reply */
251
	/* Log before sending the reply */
252
	auth_log(authctxt, authenticated, method, " ssh2");
252
	auth_log(authctxt, authenticated, method, " ssh2");
253
253
254
	if (authctxt->postponed)
254
	if (authctxt->postponed) {
255
		if (!authctxt->multiple_auth_failure &&
256
			authctxt->multiple_auth.flags)
257
			goto fake_auth_failure;
255
		return;
258
		return;
259
	}
256
260
257
	/* XXX todo: check if multiple auth methods are needed */
261
	/* XXX todo: check if multiple auth methods are needed */
258
	if (authenticated == 1) {
262
	if (authenticated == 1) {
Lines 270-275 Link Here
270
#endif
274
#endif
271
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
275
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
272
		}
276
		}
277
fake_auth_failure:
273
		methods = authmethods_get();
278
		methods = authmethods_get();
274
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
279
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
275
		packet_put_cstring(methods);
280
		packet_put_cstring(methods);
Lines 280-285 Link Here
280
	}
285
	}
281
}
286
}
282
287
288
void
289
auth2_multiple_auth(const char *method, Authctxt *authctxt, int *authenticated)
290
{
291
	debug3("%s[%d],entry,method %s,auth(%d,%d,%d),*auth %d,postponed %d",
292
		__func__, getpid(), method, authctxt->multiple_auth_failure,
293
		authctxt->multiple_auth.pubkey_passwd.passwd,
294
		authctxt->multiple_auth.pubkey_passwd.pubkey, *authenticated,
295
		authctxt->postponed);
296
297
	if (options.require_both_password_and_pub_key == 1 &&
298
		(!strcasecmp(method, "password") ||
299
		!strcasecmp(method, "publickey"))) {
300
		if (!*authenticated && !strcasecmp(method, "publickey"))
301
			authctxt->multiple_auth_failure = 1;
302
		else if (!authctxt->multiple_auth_failure) {
303
			if (!strcasecmp(method, "password"))
304
				authctxt->
305
					multiple_auth.pubkey_passwd.passwd = 1;
306
			else if (!strcasecmp(method, "publickey"))
307
				authctxt->
308
					multiple_auth.pubkey_passwd.pubkey = 1;
309
310
			if (!authctxt->multiple_auth.pubkey_passwd.passwd ||
311
				!authctxt->multiple_auth.pubkey_passwd.pubkey) {
312
				authctxt->postponed = 1;
313
				*authenticated = 0;
314
			}
315
		}
316
		else
317
			*authenticated = 0;
318
	}
319
	debug3("%s[%d],exit,multiple_auth (%d,%d,%d),*auth %d,postponed %d",
320
		__func__, getpid(), authctxt->multiple_auth_failure,
321
		authctxt->multiple_auth.pubkey_passwd.passwd,
322
		authctxt->multiple_auth.pubkey_passwd.pubkey, *authenticated,
323
		authctxt->postponed);
324
}
325
283
static char *
326
static char *
284
authmethods_get(void)
327
authmethods_get(void)
285
{
328
{
(-)openssh/monitor.c (+3 lines)
Lines 379-384 Link Here
379
			if (!authenticated)
379
			if (!authenticated)
380
				authctxt->failures++;
380
				authctxt->failures++;
381
		}
381
		}
382
		if ((ent->type == MONITOR_REQ_KEYVERIFY ||
383
			ent->type == MONITOR_REQ_AUTHPASSWORD))
384
			auth2_multiple_auth(auth_method, authctxt, &authenticated);
382
	}
385
	}
383
386
384
	if (!authctxt->valid)
387
	if (!authctxt->valid)
(-)openssh/servconf.c (+12 lines)
Lines 123-128 Link Here
123
	options->authorized_keys_file = NULL;
123
	options->authorized_keys_file = NULL;
124
	options->authorized_keys_file2 = NULL;
124
	options->authorized_keys_file2 = NULL;
125
	options->num_accept_env = 0;
125
	options->num_accept_env = 0;
126
	options->require_both_password_and_pub_key = -1;
126
	options->permit_tun = -1;
127
	options->permit_tun = -1;
127
	options->num_permitted_opens = -1;
128
	options->num_permitted_opens = -1;
128
	options->adm_forced_command = NULL;
129
	options->adm_forced_command = NULL;
Lines 256-261 Link Here
256
	}
257
	}
257
	if (options->authorized_keys_file == NULL)
258
	if (options->authorized_keys_file == NULL)
258
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
259
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
260
	if (options->require_both_password_and_pub_key == -1)
261
		options->require_both_password_and_pub_key = 0;
262
	else if (options->require_both_password_and_pub_key == 1)
263
		options->password_authentication =
264
			options->pubkey_authentication = 1;
259
	if (options->permit_tun == -1)
265
	if (options->permit_tun == -1)
260
		options->permit_tun = SSH_TUNMODE_NO;
266
		options->permit_tun = SSH_TUNMODE_NO;
261
267
Lines 302-307 Link Here
302
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
308
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
303
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
309
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
304
	sUsePrivilegeSeparation, sAllowAgentForwarding,
310
	sUsePrivilegeSeparation, sAllowAgentForwarding,
311
	sRequireBothPasswordAndPubKey,
305
	sDeprecated, sUnsupported
312
	sDeprecated, sUnsupported
306
} ServerOpCodes;
313
} ServerOpCodes;
307
314
Lines 410-415 Link Here
410
	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
417
	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
411
	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
418
	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
412
	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
419
	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
420
	{ "requirebothpasswordandpubkey", sRequireBothPasswordAndPubKey },
413
	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
421
	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
414
 	{ "match", sMatch, SSHCFG_ALL },
422
 	{ "match", sMatch, SSHCFG_ALL },
415
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
423
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
Lines 979-984 Link Here
979
			*intptr = value;
987
			*intptr = value;
980
		break;
988
		break;
981
989
990
	case sRequireBothPasswordAndPubKey:
991
		intptr = &options->require_both_password_and_pub_key;
992
		goto parse_flag;
993
982
	case sGatewayPorts:
994
	case sGatewayPorts:
983
		intptr = &options->gateway_ports;
995
		intptr = &options->gateway_ports;
984
		arg = strdelim(&cp);
996
		arg = strdelim(&cp);
(-)openssh/servconf.h (+1 lines)
Lines 96-101 Link Here
96
						 * authentication. */
96
						 * authentication. */
97
	int     kbd_interactive_authentication;	/* If true, permit */
97
	int     kbd_interactive_authentication;	/* If true, permit */
98
	int     challenge_response_authentication;
98
	int     challenge_response_authentication;
99
	int	require_both_password_and_pub_key;
99
	int     permit_empty_passwd;	/* If false, do not permit empty
100
	int     permit_empty_passwd;	/* If false, do not permit empty
100
					 * passwords. */
101
					 * passwords. */
101
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
102
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
(-)openssh/auth.h (+9 lines)
Lines 71-76 Link Here
71
#endif
71
#endif
72
	Buffer		*loginmsg;
72
	Buffer		*loginmsg;
73
	void		*methoddata;
73
	void		*methoddata;
74
	union {
75
		struct {
76
			unsigned passwd : 1;
77
			unsigned pubkey : 1;
78
		} pubkey_passwd;
79
		unsigned flags;
80
	} multiple_auth;
81
	unsigned multiple_auth_failure : 1; 
74
};
82
};
75
/*
83
/*
76
 * Every authentication method has to handle authentication requests for
84
 * Every authentication method has to handle authentication requests for
Lines 151-156 Link Here
151
159
152
int	auth2_challenge(Authctxt *, char *);
160
int	auth2_challenge(Authctxt *, char *);
153
void	auth2_challenge_stop(Authctxt *);
161
void	auth2_challenge_stop(Authctxt *);
162
void	auth2_multiple_auth(const char *, Authctxt *, int *);
154
int	bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
163
int	bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
155
int	bsdauth_respond(void *, u_int, char **);
164
int	bsdauth_respond(void *, u_int, char **);
156
int	skey_query(void *, char **, char **, u_int *, char ***, u_int **);
165
int	skey_query(void *, char **, char **, u_int *, char ***, u_int **);
(-)openssh/sshd_config.5 (+14 lines)
Lines 796-801 Link Here
796
The default is
796
The default is
797
.Dq yes .
797
.Dq yes .
798
Note that this option applies to protocol version 2 only.
798
Note that this option applies to protocol version 2 only.
799
.It Cm RequireBothPasswordAndPubKey
800
Specifies whether both password and public key authentication must
801
be successful before authentication is allowed.  If 
802
.Dq yes ,
803
then this option performs both types of authentication, overriding any
804
values for the
805
.Cm PubkeyAuthentication
806
and
807
.Cm PasswordAuthentication
808
options, setting both implicitly to 
809
.Dq yes .
810
The default is
811
.Dq no .
812
This option applies to protocol version 2 only.
799
.It Cm RhostsRSAAuthentication
813
.It Cm RhostsRSAAuthentication
800
Specifies whether rhosts or /etc/hosts.equiv authentication together
814
Specifies whether rhosts or /etc/hosts.equiv authentication together
801
with successful RSA host authentication is allowed.
815
with successful RSA host authentication is allowed.

Return to bug 983