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

Collapse All | Expand All

(-)usr.bin/ssh/auth.h (+9 lines)
Lines 68-73 Link Here
68
	char		*krb5_ticket_file;
68
	char		*krb5_ticket_file;
69
#endif
69
#endif
70
	void		*methoddata;
70
	void		*methoddata;
71
	union {
72
		struct {
73
			unsigned passwd : 1;
74
			unsigned pubkey : 1;
75
		} pubkey_passwd;
76
		unsigned flags;
77
	} multiple_auth;
78
	unsigned multiple_auth_failure : 1; 
71
};
79
};
72
/*
80
/*
73
 * Every authentication method has to handle authentication requests for
81
 * Every authentication method has to handle authentication requests for
Lines 135-140 Link Here
135
143
136
int	auth2_challenge(Authctxt *, char *);
144
int	auth2_challenge(Authctxt *, char *);
137
void	auth2_challenge_stop(Authctxt *);
145
void	auth2_challenge_stop(Authctxt *);
146
void	auth2_multiple_auth(const char *, Authctxt *, int *);
138
int	bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
147
int	bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
139
int	bsdauth_respond(void *, u_int, char **);
148
int	bsdauth_respond(void *, u_int, char **);
140
int	skey_query(void *, char **, char **, u_int *, char ***, u_int **);
149
int	skey_query(void *, char **, char **, u_int *, char ***, u_int **);
(-)usr.bin/ssh/auth2-passwd.c (+1 lines)
Lines 59-64 Link Here
59
		authenticated = 1;
59
		authenticated = 1;
60
	memset(password, 0, len);
60
	memset(password, 0, len);
61
	xfree(password);
61
	xfree(password);
62
	auth2_multiple_auth("password", authctxt, &authenticated);
62
	return authenticated;
63
	return authenticated;
63
}
64
}
64
65
(-)usr.bin/ssh/auth2-pubkey.c (+1 lines)
Lines 129-134 Link Here
129
			authenticated = 1;
129
			authenticated = 1;
130
		buffer_free(&b);
130
		buffer_free(&b);
131
		xfree(sig);
131
		xfree(sig);
132
		auth2_multiple_auth("publickey", authctxt, &authenticated);
132
	} else {
133
	} else {
133
		debug("test whether pkalg/pkblob are acceptable");
134
		debug("test whether pkalg/pkblob are acceptable");
134
		packet_check_eom();
135
		packet_check_eom();
(-)usr.bin/ssh/auth2.c (-1 / +44 lines)
Lines 210-217 Link Here
210
	/* Log before sending the reply */
210
	/* Log before sending the reply */
211
	auth_log(authctxt, authenticated, method, " ssh2");
211
	auth_log(authctxt, authenticated, method, " ssh2");
212
212
213
	if (authctxt->postponed)
213
	if (authctxt->postponed) {
214
		if (!authctxt->multiple_auth_failure &&
215
			authctxt->multiple_auth.flags)
216
			goto fake_auth_failure;
214
		return;
217
		return;
218
	}
215
219
216
	/* XXX todo: check if multiple auth methods are needed */
220
	/* XXX todo: check if multiple auth methods are needed */
217
	if (authenticated == 1) {
221
	if (authenticated == 1) {
Lines 225-230 Link Here
225
	} else {
229
	} else {
226
		if (authctxt->failures++ > options.max_authtries)
230
		if (authctxt->failures++ > options.max_authtries)
227
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
231
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
232
fake_auth_failure:
228
		methods = authmethods_get();
233
		methods = authmethods_get();
229
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
234
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
230
		packet_put_cstring(methods);
235
		packet_put_cstring(methods);
Lines 233-238 Link Here
233
		packet_write_wait();
238
		packet_write_wait();
234
		xfree(methods);
239
		xfree(methods);
235
	}
240
	}
241
}
242
243
void
244
auth2_multiple_auth(const char *method, Authctxt *authctxt, int *authenticated)
245
{
246
	debug3("%s[%d],entry,method %s,auth(%d,%d,%d),*auth %d,postponed %d",
247
		__func__, getpid(), method, authctxt->multiple_auth_failure,
248
		authctxt->multiple_auth.pubkey_passwd.passwd,
249
		authctxt->multiple_auth.pubkey_passwd.pubkey, *authenticated,
250
		authctxt->postponed);
251
252
	if (options.require_both_password_and_pub_key == 1 &&
253
		(!strcasecmp(method, "password") ||
254
		!strcasecmp(method, "publickey"))) {
255
		if (!*authenticated && !strcasecmp(method, "publickey"))
256
			authctxt->multiple_auth_failure = 1;
257
		else if (!authctxt->multiple_auth_failure) {
258
			if (!strcasecmp(method, "password"))
259
				authctxt->
260
					multiple_auth.pubkey_passwd.passwd = 1;
261
			else if (!strcasecmp(method, "publickey"))
262
				authctxt->
263
					multiple_auth.pubkey_passwd.pubkey = 1;
264
265
			if (!authctxt->multiple_auth.pubkey_passwd.passwd ||
266
				!authctxt->multiple_auth.pubkey_passwd.pubkey) {
267
				authctxt->postponed = 1;
268
				*authenticated = 0;
269
			}
270
		}
271
		else
272
			*authenticated = 0;
273
	}
274
	debug3("%s[%d],exit,multiple_auth (%d,%d,%d),*auth %d,postponed %d",
275
		__func__, getpid(), authctxt->multiple_auth_failure,
276
		authctxt->multiple_auth.pubkey_passwd.passwd,
277
		authctxt->multiple_auth.pubkey_passwd.pubkey, *authenticated,
278
		authctxt->postponed);
236
}
279
}
237
280
238
#define	DELIM	","
281
#define	DELIM	","
(-)usr.bin/ssh/monitor.c (+3 lines)
Lines 290-295 Link Here
290
			if (!authenticated)
290
			if (!authenticated)
291
				authctxt->failures++;
291
				authctxt->failures++;
292
		}
292
		}
293
		if ((ent->type == MONITOR_REQ_KEYVERIFY ||
294
			ent->type == MONITOR_REQ_AUTHPASSWORD))
295
			auth2_multiple_auth(auth_method, authctxt, &authenticated);
293
	}
296
	}
294
297
295
	if (!authctxt->valid)
298
	if (!authctxt->valid)
(-)usr.bin/ssh/servconf.c (+12 lines)
Lines 96-101 Link Here
96
	options->authorized_keys_file = NULL;
96
	options->authorized_keys_file = NULL;
97
	options->authorized_keys_file2 = NULL;
97
	options->authorized_keys_file2 = NULL;
98
	options->num_accept_env = 0;
98
	options->num_accept_env = 0;
99
	options->require_both_password_and_pub_key = -1;
99
100
100
	/* Needs to be accessable in many places */
101
	/* Needs to be accessable in many places */
101
	use_privsep = -1;
102
	use_privsep = -1;
Lines 219-224 Link Here
219
	}
220
	}
220
	if (options->authorized_keys_file == NULL)
221
	if (options->authorized_keys_file == NULL)
221
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
222
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
223
	if (options->require_both_password_and_pub_key == -1)
224
		options->require_both_password_and_pub_key = 0;
225
	else if (options->require_both_password_and_pub_key == 1)
226
		options->password_authentication =
227
			options->pubkey_authentication = 1;
222
228
223
	/* Turn privilege separation on by default */
229
	/* Turn privilege separation on by default */
224
	if (use_privsep == -1)
230
	if (use_privsep == -1)
Lines 249-254 Link Here
249
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
255
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
250
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
256
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv,
251
	sUsePrivilegeSeparation,
257
	sUsePrivilegeSeparation,
258
	sRequireBothPasswordAndPubKey,
252
	sDeprecated, sUnsupported
259
	sDeprecated, sUnsupported
253
} ServerOpCodes;
260
} ServerOpCodes;
254
261
Lines 338-343 Link Here
338
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
345
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
339
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
346
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
340
	{ "acceptenv", sAcceptEnv },
347
	{ "acceptenv", sAcceptEnv },
348
	{ "requirebothpasswordandpubkey", sRequireBothPasswordAndPubKey },
341
	{ NULL, sBadOption }
349
	{ NULL, sBadOption }
342
};
350
};
343
351
Lines 894-899 Link Here
894
			    xstrdup(arg);
902
			    xstrdup(arg);
895
		}
903
		}
896
		break;
904
		break;
905
906
	case sRequireBothPasswordAndPubKey:
907
		intptr = &options->require_both_password_and_pub_key;
908
		goto parse_flag;
897
909
898
	case sDeprecated:
910
	case sDeprecated:
899
		logit("%s line %d: Deprecated option %s",
911
		logit("%s line %d: Deprecated option %s",
(-)usr.bin/ssh/servconf.h (+1 lines)
Lines 93-98 Link Here
93
						 * authentication. */
93
						 * authentication. */
94
	int     kbd_interactive_authentication;	/* If true, permit */
94
	int     kbd_interactive_authentication;	/* If true, permit */
95
	int     challenge_response_authentication;
95
	int     challenge_response_authentication;
96
	int	require_both_password_and_pub_key;
96
	int     permit_empty_passwd;	/* If false, do not permit empty
97
	int     permit_empty_passwd;	/* If false, do not permit empty
97
					 * passwords. */
98
					 * passwords. */
98
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
99
	int     permit_user_env;	/* If true, read ~/.ssh/environment */
(-)usr.bin/ssh/sshd_config.5 (+14 lines)
Lines 566-571 Link Here
566
The default is
566
The default is
567
.Dq yes .
567
.Dq yes .
568
Note that this option applies to protocol version 2 only.
568
Note that this option applies to protocol version 2 only.
569
.It Cm RequireBothPasswordAndPubKey
570
Specifies whether both password and public key authentication must
571
be successful before authentication is allowed.  If 
572
.Dq yes ,
573
then this option performs both types of authentication, overriding any
574
values for the
575
.Cm PubkeyAuthentication
576
and
577
.Cm PasswordAuthentication
578
options, setting both implicitly to 
579
.Dq yes .
580
The default is
581
.Dq no .
582
This option applies to protocol version 2 only.
569
.It Cm RhostsRSAAuthentication
583
.It Cm RhostsRSAAuthentication
570
Specifies whether rhosts or /etc/hosts.equiv authentication together
584
Specifies whether rhosts or /etc/hosts.equiv authentication together
571
with successful RSA host authentication is allowed.
585
with successful RSA host authentication is allowed.

Return to bug 983