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

Collapse All | Expand All

(-)auth.c (-3 / +59 lines)
Lines 245-251 allowed_user(struct passwd * pw) Link Here
245
}
245
}
246
246
247
void
247
void
248
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
248
auth_log(Authctxt *authctxt, int authenticated, const char *method,
249
    const char *submethod, const char *info)
249
{
250
{
250
	void (*authlog) (const char *fmt,...) = verbose;
251
	void (*authlog) (const char *fmt,...) = verbose;
251
	char *authmsg;
252
	char *authmsg;
Lines 265-273 auth_log(Authctxt *authctxt, int authent Link Here
265
	else
266
	else
266
		authmsg = authenticated ? "Accepted" : "Failed";
267
		authmsg = authenticated ? "Accepted" : "Failed";
267
268
268
	authlog("%s %s for %s%.100s from %.200s port %d%s",
269
	authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
269
	    authmsg,
270
	    authmsg,
270
	    method,
271
	    method,
272
	    submethod == NULL ? "" : "/", submethod == NULL ? "" : submethod,
271
	    authctxt->valid ? "" : "invalid user ",
273
	    authctxt->valid ? "" : "invalid user ",
272
	    authctxt->user,
274
	    authctxt->user,
273
	    get_remote_ipaddr(),
275
	    get_remote_ipaddr(),
Lines 297-303 auth_log(Authctxt *authctxt, int authent Link Here
297
 * Check whether root logins are disallowed.
299
 * Check whether root logins are disallowed.
298
 */
300
 */
299
int
301
int
300
auth_root_allowed(char *method)
302
auth_root_allowed(const char *method)
301
{
303
{
302
	switch (options.permit_root_login) {
304
	switch (options.permit_root_login) {
303
	case PERMIT_YES:
305
	case PERMIT_YES:
Lines 619-622 fakepw(void) Link Here
619
	fake.pw_shell = "/nonexist";
621
	fake.pw_shell = "/nonexist";
620
622
621
	return (&fake);
623
	return (&fake);
624
}
625
626
int
627
auth_method_in_list(const char *list, const char *method)
628
{
629
	char *cp;
630
631
	cp = match_list(method, list, NULL);
632
	if (cp != NULL) {
633
		xfree(cp);
634
		return 1;
635
	}
636
637
	return 0;
638
}
639
640
#define	DELIM	","
641
int
642
auth_remove_from_list(char **list, const char *method)
643
{
644
	char *oldlist, *cp, *newlist = NULL;
645
	u_int len = 0, ret = 0;
646
647
	if (list == NULL || *list == NULL)
648
		return (0);
649
650
	oldlist = *list;
651
	len = strlen(oldlist) + 1;
652
	newlist = xmalloc(len);
653
	memset(newlist, '\0', len);
654
655
	/* Remove method from list, if present */
656
	for (;;) {
657
		if ((cp = strsep(&oldlist, DELIM)) == NULL)
658
			break;
659
		if (*cp == '\0')
660
			continue;
661
		if (strcmp(cp, method) != 0) {
662
			if (*newlist != '\0')
663
				strlcat(newlist, DELIM, len);
664
			strlcat(newlist, cp, len);
665
		} else
666
			ret++;
667
	}
668
669
	/* Return NULL instead of empty list */
670
	if (*newlist == '\0') {
671
		xfree(newlist);
672
		newlist = NULL;
673
	}
674
	xfree(*list);
675
	*list = newlist;
676
	
677
	return (ret);
622
}
678
}
(-)auth.h (-3 / +9 lines)
Lines 141-150 void disable_forwarding(void); Link Here
141
void	do_authentication(Authctxt *);
141
void	do_authentication(Authctxt *);
142
void	do_authentication2(Authctxt *);
142
void	do_authentication2(Authctxt *);
143
143
144
void	auth_log(Authctxt *, int, char *, char *);
144
void	auth_log(Authctxt *, int, const char *, const char *, const char *);
145
void	userauth_finish(Authctxt *, int, char *);
145
void	userauth_finish(Authctxt *, int, const char *, const char *);
146
int	auth_root_allowed(const char *);
147
146
void	userauth_send_banner(const char *);
148
void	userauth_send_banner(const char *);
147
int	auth_root_allowed(char *);
148
149
149
char	*auth2_read_banner(void);
150
char	*auth2_read_banner(void);
150
151
Lines 188-193 void auth_debug_send(void); Link Here
188
void	 auth_debug_reset(void);
189
void	 auth_debug_reset(void);
189
190
190
struct passwd *fakepw(void);
191
struct passwd *fakepw(void);
192
int	 auth_method_in_list(const char *, const char *);
193
int	 auth_remove_from_list(char **, const char *);
194
195
int	 auth1_check_required(const char *);
196
int	 auth2_check_required(const char *);
191
197
192
int	 sys_auth_passwd(Authctxt *, const char *);
198
int	 sys_auth_passwd(Authctxt *, const char *);
193
199
(-)auth1.c (-5 / +89 lines)
Lines 98-103 static const struct AuthMethod1 Link Here
98
	return (NULL);
98
	return (NULL);
99
}
99
}
100
100
101
static const struct AuthMethod1 *
102
lookup_authmethod1_by_name(const char *name)
103
{
104
	int i;
105
106
	for (i = 0; auth1_methods[i].name != NULL; i++)
107
		if (strcmp(auth1_methods[i].name, name) == 0)
108
			return (&(auth1_methods[i]));
109
110
	return NULL;
111
}
112
113
#define	DELIM	","
114
int
115
auth1_check_required(const char *list)
116
{
117
	char *orig_methods, *methods, *cp;
118
	static const struct AuthMethod1 *m;
119
	int ret = 0;
120
121
	orig_methods = methods = xstrdup(list);
122
	for(;;) { /* XXX maybe: while ((cp = ...) != NULL) ? */
123
		if ((cp = strsep(&methods, DELIM)) == NULL)
124
			break;
125
		debug2("auth1_check_required: method \"%s\"", cp);
126
		if (*cp == '\0') {
127
			debug("auth1_check_required: empty method");
128
			ret = -1;
129
		}
130
		if ((m = lookup_authmethod1_by_name(cp)) == NULL) {
131
			debug("auth1_check_required: unknown method "
132
			    "\"%s\"", cp);
133
			ret = -1;
134
		}
135
		if (*(m->enabled) == 0) {
136
			debug("auth1_check_required: method %s explicitly "
137
			    "disabled", cp);
138
			ret = -1;
139
		}
140
		/* Activate method if it isn't already */
141
		if (*(m->enabled) == -1)
142
			*(m->enabled) = 1;
143
        }
144
	xfree(orig_methods);
145
	return (ret);
146
}
147
148
101
static char *
149
static char *
102
get_authname(int type)
150
get_authname(int type)
103
{
151
{
Lines 237-242 do_authloop(Authctxt *authctxt) Link Here
237
{
285
{
238
	int authenticated = 0;
286
	int authenticated = 0;
239
	char info[1024];
287
	char info[1024];
288
	const char *meth_name;
240
	int prev = 0, type = 0;
289
	int prev = 0, type = 0;
241
	const struct AuthMethod1 *meth;
290
	const struct AuthMethod1 *meth;
242
291
Lines 244-250 do_authloop(Authctxt *authctxt) Link Here
244
	    authctxt->valid ? "" : "invalid user ", authctxt->user);
293
	    authctxt->valid ? "" : "invalid user ", authctxt->user);
245
294
246
	/* If the user has no password, accept authentication immediately. */
295
	/* If the user has no password, accept authentication immediately. */
247
	if (options.password_authentication &&
296
	if (options.required_auth1 == NULL && options.password_authentication &&
248
#ifdef KRB5
297
#ifdef KRB5
249
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
298
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
250
#endif
299
#endif
Lines 253-259 do_authloop(Authctxt *authctxt) Link Here
253
		if (options.use_pam && (PRIVSEP(do_pam_account())))
302
		if (options.use_pam && (PRIVSEP(do_pam_account())))
254
#endif
303
#endif
255
		{
304
		{
256
			auth_log(authctxt, 1, "without authentication", "");
305
			auth_log(authctxt, 1, "without authentication", NULL, "");
257
			return;
306
			return;
258
		}
307
		}
259
	}
308
	}
Lines 272-277 do_authloop(Authctxt *authctxt) Link Here
272
		/* Get a packet from the client. */
321
		/* Get a packet from the client. */
273
		prev = type;
322
		prev = type;
274
		type = packet_read();
323
		type = packet_read();
324
		meth_name = get_authname(type);
275
325
276
		/*
326
		/*
277
		 * If we started challenge-response authentication but the
327
		 * If we started challenge-response authentication but the
Lines 287-294 do_authloop(Authctxt *authctxt) Link Here
287
		if (authctxt->failures >= options.max_authtries)
337
		if (authctxt->failures >= options.max_authtries)
288
			goto skip;
338
			goto skip;
289
		if ((meth = lookup_authmethod1(type)) == NULL) {
339
		if ((meth = lookup_authmethod1(type)) == NULL) {
290
			logit("Unknown message during authentication: "
340
			logit("Unknown message during authentication: type %d",
291
			    "type %d", type);
341
			    type);
292
			goto skip;
342
			goto skip;
293
		}
343
		}
294
344
Lines 297-302 do_authloop(Authctxt *authctxt) Link Here
297
			goto skip;
347
			goto skip;
298
		}
348
		}
299
349
350
		/*
351
		 * Skip methods not in required list, until all the required
352
		 * ones are done
353
		 */
354
		if (options.required_auth1 != NULL &&
355
		    !auth_method_in_list(options.required_auth1, meth_name)) {
356
			debug("Skipping method \"%s\" until required "
357
			    "authentication completed", meth_name);
358
			goto skip;
359
		}
360
300
		authenticated = meth->method(authctxt, info, sizeof(info));
361
		authenticated = meth->method(authctxt, info, sizeof(info));
301
		if (authenticated == -1)
362
		if (authenticated == -1)
302
			continue; /* "postponed" */
363
			continue; /* "postponed" */
Lines 352-358 do_authloop(Authctxt *authctxt) Link Here
352
413
353
 skip:
414
 skip:
354
		/* Log before sending the reply */
415
		/* Log before sending the reply */
355
		auth_log(authctxt, authenticated, get_authname(type), info);
416
		auth_log(authctxt, authenticated, meth_name, NULL, info);
417
418
		/* Loop until the required authmethods are done */
419
		if (authenticated && options.required_auth1 != NULL) {
420
			if (auth_remove_from_list(&options.required_auth1,
421
			    meth_name) != 1)
422
				fatal("INTERNAL ERROR: authenticated method "
423
				    "\"%s\" not in required list \"%s\"",
424
				    meth_name, options.required_auth1);
425
			debug2("do_authloop: required list now: %s",
426
			    options.required_auth1 == NULL ?
427
			    "DONE" : options.required_auth1);
428
			if (options.required_auth1 == NULL)
429
				return;
430
			authenticated = 0;
431
			/*
432
			 * Disable method so client can't authenticate with it
433
			 * after the required authentications are complete.
434
			 */
435
			*(meth->enabled) = 0;
436
			packet_send_debug("Further authentication required");
437
			goto send_fail;
438
		}
356
439
357
		if (client_user != NULL) {
440
		if (client_user != NULL) {
358
			xfree(client_user);
441
			xfree(client_user);
Lines 368-373 do_authloop(Authctxt *authctxt) Link Here
368
#endif
451
#endif
369
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
452
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
370
		}
453
		}
454
 send_fail:
371
455
372
		packet_start(SSH_SMSG_FAILURE);
456
		packet_start(SSH_SMSG_FAILURE);
373
		packet_send();
457
		packet_send();
(-)auth2.c (-12 / +94 lines)
Lines 215-221 input_userauth_request(int type, u_int32 Link Here
215
{
215
{
216
	Authctxt *authctxt = ctxt;
216
	Authctxt *authctxt = ctxt;
217
	Authmethod *m = NULL;
217
	Authmethod *m = NULL;
218
	char *user, *service, *method, *style = NULL;
218
	char *user, *service, *method, *active_methods, *style = NULL;
219
	int authenticated = 0;
219
	int authenticated = 0;
220
220
221
	if (authctxt == NULL)
221
	if (authctxt == NULL)
Lines 276-297 input_userauth_request(int type, u_int32 Link Here
276
	authctxt->postponed = 0;
276
	authctxt->postponed = 0;
277
277
278
	/* try to authenticate user */
278
	/* try to authenticate user */
279
	m = authmethod_lookup(method);
279
	active_methods = authmethods_get();
280
	if (m != NULL && authctxt->failures < options.max_authtries) {
280
	if (strcmp(method, "none") == 0 || 
281
		debug2("input_userauth_request: try method %s", method);
281
	    auth_method_in_list(active_methods, method)) {
282
		authenticated =	m->userauth(authctxt);
282
		m = authmethod_lookup(method);
283
	}
283
		if (m != NULL) {
284
	userauth_finish(authctxt, authenticated, method);
284
			debug2("input_userauth_request: try method %s", method);
285
			authenticated =	m->userauth(authctxt);
286
		}
285
287
288
	}
289
	xfree(active_methods);
290
	userauth_finish(authctxt, authenticated, method, NULL);
291
 
286
	xfree(service);
292
	xfree(service);
287
	xfree(user);
293
	xfree(user);
288
	xfree(method);
294
	xfree(method);
289
}
295
}
290
296
291
void
297
void
292
userauth_finish(Authctxt *authctxt, int authenticated, char *method)
298
userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
299
    const char *submethod)
293
{
300
{
294
	char *methods;
301
	char *methods;
302
	Authmethod *m = NULL;
303
	u_int partial = 0;
295
304
296
	if (!authctxt->valid && authenticated)
305
	if (!authctxt->valid && authenticated)
297
		fatal("INTERNAL ERROR: authenticated invalid user %s",
306
		fatal("INTERNAL ERROR: authenticated invalid user %s",
Lines 329-340 userauth_finish(Authctxt *authctxt, int Link Here
329
#endif /* _UNICOS */
338
#endif /* _UNICOS */
330
339
331
	/* Log before sending the reply */
340
	/* Log before sending the reply */
332
	auth_log(authctxt, authenticated, method, " ssh2");
341
	auth_log(authctxt, authenticated, method, submethod, " ssh2");
333
342
334
	if (authctxt->postponed)
343
	if (authctxt->postponed)
335
		return;
344
		return;
336
345
337
	/* XXX todo: check if multiple auth methods are needed */
346
	/* Handle RequiredAuthentications2: loop until required methods done */
347
	if (authenticated && options.required_auth2 != NULL) {
348
		if ((m = authmethod_lookup(method)) == NULL)
349
			fatal("INTERNAL ERROR: authenticated method "
350
			    "\"%s\" unknown", method);
351
		if (auth_remove_from_list(&options.required_auth2, method) != 1)
352
			fatal("INTERNAL ERROR: authenticated method "
353
			    "\"%s\" not in required list \"%s\"", 
354
			    method, options.required_auth2);
355
		debug2("userauth_finish: required list now: %s",
356
		    options.required_auth2 == NULL ?
357
		    "DONE" : options.required_auth2);
358
		/*
359
		 * if authenticated and no more required methods 
360
		 * then declare success
361
		 */
362
		if ( authenticated && options.required_auth2 == NULL ) {
363
			debug2("userauth_finish: authenticated and no more required methods");
364
		} else {
365
			/*
366
			 * Disable method so client can't authenticate with it after
367
			 * the required authentications are complete.
368
			 */
369
			if (m->enabled != NULL)
370
			*(m->enabled) = 0;
371
			authenticated = 0;
372
			partial = 1;
373
			goto send_fail;
374
		}
375
	}
376
338
	if (authenticated == 1) {
377
	if (authenticated == 1) {
339
		/* turn off userauth */
378
		/* turn off userauth */
340
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
379
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
Lines 344-350 userauth_finish(Authctxt *authctxt, int Link Here
344
		/* now we can break out */
383
		/* now we can break out */
345
		authctxt->success = 1;
384
		authctxt->success = 1;
346
	} else {
385
	} else {
347
348
		/* Allow initial try of "none" auth without failure penalty */
386
		/* Allow initial try of "none" auth without failure penalty */
349
		if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
387
		if (authctxt->attempt > 1 || strcmp(method, "none") != 0)
350
			authctxt->failures++;
388
			authctxt->failures++;
Lines 354-363 userauth_finish(Authctxt *authctxt, int Link Here
354
#endif
392
#endif
355
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
393
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
356
		}
394
		}
395
 send_fail:
357
		methods = authmethods_get();
396
		methods = authmethods_get();
358
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
397
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
359
		packet_put_cstring(methods);
398
		packet_put_cstring(methods);
360
		packet_put_char(0);	/* XXX partial success, unused */
399
		packet_put_char(partial);
361
		packet_send();
400
		packet_send();
362
		packet_write_wait();
401
		packet_write_wait();
363
		xfree(methods);
402
		xfree(methods);
Lines 371-376 authmethods_get(void) Link Here
371
	char *list;
410
	char *list;
372
	int i;
411
	int i;
373
412
413
	if (options.required_auth2 != NULL)
414
		return xstrdup(options.required_auth2);
415
374
	buffer_init(&b);
416
	buffer_init(&b);
375
	for (i = 0; authmethods[i] != NULL; i++) {
417
	for (i = 0; authmethods[i] != NULL; i++) {
376
		if (strcmp(authmethods[i]->name, "none") == 0)
418
		if (strcmp(authmethods[i]->name, "none") == 0)
Lines 403-407 authmethod_lookup(const char *name) Link Here
403
	debug2("Unrecognized authentication method name: %s",
445
	debug2("Unrecognized authentication method name: %s",
404
	    name ? name : "NULL");
446
	    name ? name : "NULL");
405
	return NULL;
447
	return NULL;
448
}
449
450
#define DELIM ","
451
452
int
453
auth2_check_required(const char *list)
454
{
455
	char *orig_methods, *methods, *cp;
456
	struct Authmethod *m;
457
	int i, ret = 0;
458
459
	orig_methods = methods = xstrdup(list);
460
	for(;;) {
461
		if ((cp = strsep(&methods, DELIM)) == NULL)
462
			break;
463
		debug2("auth2_check_required: method \"%s\"", cp);
464
		if (*cp == '\0') {
465
			debug("auth2_check_required: empty method");
466
			ret = -1;
467
		}
468
		for (i = 0; authmethods[i] != NULL; i++)
469
			if (strcmp(cp, authmethods[i]->name) == 0)
470
				break;
471
		if ((m = authmethods[i]) == NULL) {
472
			debug("auth2_check_required: unknown method "
473
			    "\"%s\"", cp);
474
			ret = -1;
475
			break;
476
		}
477
		if (m->enabled == NULL || *(m->enabled) == 0) {
478
			debug("auth2_check_required: method %s explicitly "
479
			    "disabled", cp);
480
			ret = -1;
481
		}
482
		/* Activate method if it isn't already */
483
		if (*(m->enabled) == -1)
484
			*(m->enabled) = 1;
485
	}
486
	xfree(orig_methods);
487
	return (ret);
406
}
488
}
407
489
(-)auth2-none.c (-1 / +1 lines)
Lines 61-67 userauth_none(Authctxt *authctxt) Link Here
61
{
61
{
62
	none_enabled = 0;
62
	none_enabled = 0;
63
	packet_check_eom();
63
	packet_check_eom();
64
	if (options.password_authentication)
64
	if (options.password_authentication && options.required_auth2 == NULL)
65
		return (PRIVSEP(auth_password(authctxt, "")));
65
		return (PRIVSEP(auth_password(authctxt, "")));
66
	return (0);
66
	return (0);
67
}
67
}
(-)auth2-chall.c (-2 / +2 lines)
Lines 341-348 input_userauth_info_response(int type, u Link Here
341
			auth2_challenge_start(authctxt);
341
			auth2_challenge_start(authctxt);
342
		}
342
		}
343
	}
343
	}
344
	userauth_finish(authctxt, authenticated, method);
344
	userauth_finish(authctxt, authenticated, "keyboard-interactive",
345
	xfree(method);
345
	    kbdintctxt->device->name);
346
}
346
}
347
347
348
void
348
void
(-)auth2-gss.c (-3 / +3 lines)
Lines 161-167 input_gssapi_token(int type, u_int32_t p Link Here
161
		}
161
		}
162
		authctxt->postponed = 0;
162
		authctxt->postponed = 0;
163
		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
163
		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
164
		userauth_finish(authctxt, 0, "gssapi-with-mic");
164
		userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
165
	} else {
165
	} else {
166
		if (send_tok.length != 0) {
166
		if (send_tok.length != 0) {
167
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
167
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
Lines 249-255 input_gssapi_exchange_complete(int type, Link Here
249
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
249
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
250
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
250
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
251
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
251
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
252
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
252
	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
253
}
253
}
254
254
255
static void
255
static void
Lines 289-295 input_gssapi_mic(int type, u_int32_t ple Link Here
289
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
289
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
290
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
290
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
291
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
291
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
292
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
292
	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
293
}
293
}
294
294
295
Authmethod method_gssapi = {
295
Authmethod method_gssapi = {
(-)monitor.c (-4 / +21 lines)
Lines 342-348 void Link Here
342
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
342
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
343
{
343
{
344
	struct mon_table *ent;
344
	struct mon_table *ent;
345
	int authenticated = 0;
345
	int no_increment, authenticated = 0;
346
	char **req_auth;
346
347
347
	debug3("preauth child monitor started");
348
	debug3("preauth child monitor started");
348
349
Lines 353-364 monitor_child_preauth(Authctxt *_authctx Link Here
353
354
354
	if (compat20) {
355
	if (compat20) {
355
		mon_dispatch = mon_dispatch_proto20;
356
		mon_dispatch = mon_dispatch_proto20;
357
		req_auth = &options.required_auth2;
356
358
357
		/* Permit requests for moduli and signatures */
359
		/* Permit requests for moduli and signatures */
358
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
360
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
359
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
361
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
360
	} else {
362
	} else {
361
		mon_dispatch = mon_dispatch_proto15;
363
		mon_dispatch = mon_dispatch_proto15;
364
		req_auth = &options.required_auth1;
362
365
363
		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
366
		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
364
	}
367
	}
Lines 366-371 monitor_child_preauth(Authctxt *_authctx Link Here
366
	/* The first few requests do not require asynchronous access */
369
	/* The first few requests do not require asynchronous access */
367
	while (!authenticated) {
370
	while (!authenticated) {
368
		auth_method = "unknown";
371
		auth_method = "unknown";
372
		no_increment = 1;
369
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
373
		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
370
		if (authenticated) {
374
		if (authenticated) {
371
			if (!(ent->flags & MON_AUTHDECIDE))
375
			if (!(ent->flags & MON_AUTHDECIDE))
Lines 387-397 monitor_child_preauth(Authctxt *_authctx Link Here
387
			}
391
			}
388
#endif
392
#endif
389
		}
393
		}
394
		/* Loop until the required authmethods are done */
395
		if (authenticated && *req_auth != NULL) {
396
			if (auth_remove_from_list(req_auth, auth_method) != 1)
397
				fatal("INTERNAL ERROR: authenticated method "
398
				    "\"%s\" not in required list \"%s\"",
399
				    auth_method, *req_auth);
400
			debug2("monitor_child_preauth: required list now: %s",
401
			    *req_auth == NULL ? "DONE" : *req_auth);
402
			if (*req_auth != NULL)
403
				authenticated = 0;
404
			no_increment = 1;
405
		}
390
406
391
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
407
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
392
			auth_log(authctxt, authenticated, auth_method,
408
			auth_log(authctxt, authenticated, auth_method, NULL,
393
			    compat20 ? " ssh2" : "");
409
			    compat20 ? " ssh2" : "");
394
			if (!authenticated)
410
			if (!authenticated && !no_increment)
395
				authctxt->failures++;
411
				authctxt->failures++;
396
		}
412
		}
397
#ifdef JPAKE
413
#ifdef JPAKE
Lines 1077-1083 mm_answer_keyallowed(int sock, Buffer *m Link Here
1077
		hostbased_chost = chost;
1093
		hostbased_chost = chost;
1078
	} else {
1094
	} else {
1079
		/* Log failed attempt */
1095
		/* Log failed attempt */
1080
		auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
1096
		auth_log(authctxt, 0, auth_method, NULL,
1097
		    compat20 ? " ssh2" : "");
1081
		xfree(blob);
1098
		xfree(blob);
1082
		xfree(cuser);
1099
		xfree(cuser);
1083
		xfree(chost);
1100
		xfree(chost);
(-)servconf.c (+34 lines)
Lines 38-43 Link Here
38
#include "key.h"
38
#include "key.h"
39
#include "kex.h"
39
#include "kex.h"
40
#include "mac.h"
40
#include "mac.h"
41
#include "hostfile.h"
42
#include "auth.h"
41
#include "match.h"
43
#include "match.h"
42
#include "channels.h"
44
#include "channels.h"
43
#include "groupaccess.h"
45
#include "groupaccess.h"
Lines 124-129 initialize_server_options(ServerOptions Link Here
124
	options->authorized_keys_file2 = NULL;
126
	options->authorized_keys_file2 = NULL;
125
	options->num_accept_env = 0;
127
	options->num_accept_env = 0;
126
	options->permit_tun = -1;
128
	options->permit_tun = -1;
129
	options->required_auth1 = NULL;
130
	options->required_auth2 = NULL;
127
	options->num_permitted_opens = -1;
131
	options->num_permitted_opens = -1;
128
	options->adm_forced_command = NULL;
132
	options->adm_forced_command = NULL;
129
	options->chroot_directory = NULL;
133
	options->chroot_directory = NULL;
Lines 303-308 typedef enum { Link Here
303
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
307
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
304
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
308
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
305
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
309
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
310
	sRequiredAuthentications1, sRequiredAuthentications2,
306
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
311
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
307
	sUsePrivilegeSeparation, sAllowAgentForwarding,
312
	sUsePrivilegeSeparation, sAllowAgentForwarding,
308
	sZeroKnowledgePasswordAuthentication,
313
	sZeroKnowledgePasswordAuthentication,
Lines 420-425 static struct { Link Here
420
	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
425
	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
421
	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
426
	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
422
	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
427
	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
428
	{ "requiredauthentications1", sRequiredAuthentications1 },
429
	{ "requiredauthentications2", sRequiredAuthentications2 },
423
	{ "match", sMatch, SSHCFG_ALL },
430
	{ "match", sMatch, SSHCFG_ALL },
424
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
431
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
425
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
432
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
Lines 1164-1169 process_server_config_line(ServerOptions Link Here
1164
			    filename, linenum);
1171
			    filename, linenum);
1165
		else
1172
		else
1166
			options->max_startups = options->max_startups_begin;
1173
			options->max_startups = options->max_startups_begin;
1174
		break;
1175
1176
1177
	case sRequiredAuthentications1:
1178
		charptr = &options->required_auth1;
1179
		arg = strdelim(&cp);
1180
		if (auth1_check_required(arg) != 0)
1181
			fatal("%.200s line %d: Invalid required authentication "
1182
			    "list", filename, linenum);
1183
		if (!arg || *arg == '\0')
1184
			fatal("%.200s line %d: Missing argument.",
1185
			    filename, linenum);
1186
		if (*charptr == NULL)
1187
			*charptr = xstrdup(arg);
1188
		break;
1189
1190
	case sRequiredAuthentications2:
1191
		charptr = &options->required_auth2;
1192
		arg = strdelim(&cp);
1193
		if (auth2_check_required(arg) != 0)
1194
			fatal("%.200s line %d: Invalid required authentication "
1195
			    "list", filename, linenum);
1196
		if (!arg || *arg == '\0')
1197
			fatal("%.200s line %d: Missing argument.",
1198
			    filename, linenum);
1199
		if (*charptr == NULL)
1200
			*charptr = xstrdup(arg);
1167
		break;
1201
		break;
1168
1202
1169
	case sMaxAuthTries:
1203
	case sMaxAuthTries:
(-)servconf.h (+3 lines)
Lines 142-147 typedef struct { Link Here
142
	char   *authorized_keys_file;	/* File containing public keys */
142
	char   *authorized_keys_file;	/* File containing public keys */
143
	char   *authorized_keys_file2;
143
	char   *authorized_keys_file2;
144
144
145
	char   *required_auth1; /* Required, but not sufficient */
146
	char   *required_auth2;
147
145
	char   *adm_forced_command;
148
	char   *adm_forced_command;
146
149
147
	int	use_pam;		/* Enable auth via PAM */
150
	int	use_pam;		/* Enable auth via PAM */
(-)sshd_config.5 (-1 / +17 lines)
Lines 614-619 Available keywords are Link Here
614
.Cm PermitEmptyPasswords ,
614
.Cm PermitEmptyPasswords ,
615
.Cm PermitOpen ,
615
.Cm PermitOpen ,
616
.Cm PermitRootLogin ,
616
.Cm PermitRootLogin ,
617
.Cm RequiredMethods1,
618
.Cm RequiredMethods2,
617
.Cm PubkeyAuthentication ,
619
.Cm PubkeyAuthentication ,
618
.Cm RhostsRSAAuthentication ,
620
.Cm RhostsRSAAuthentication ,
619
.Cm RSAAuthentication ,
621
.Cm RSAAuthentication ,
Lines 805-811 is identical to Link Here
805
Specifies whether public key authentication is allowed.
807
Specifies whether public key authentication is allowed.
806
The default is
808
The default is
807
.Dq yes .
809
.Dq yes .
808
Note that this option applies to protocol version 2 only.
810
.It Cm RequiredMethods[12]
811
 Requires two authentication methods to succeed before authorizing the connection.
812
 (RequiredAuthentication1 for Protocol version 1, and RequiredAuthentication2 for v2)
813
814
 RequiredAuthentications1 method[,method...] 
815
 RequiredAuthentications2 method[,method...]
816
817
.Pp
818
Example 1:
819
820
 RequiredAuthentications2 password,hostbased
821
822
Example 2:
823
 RequiredAuthentications2 publickey,password
824
809
.It Cm RhostsRSAAuthentication
825
.It Cm RhostsRSAAuthentication
810
Specifies whether rhosts or /etc/hosts.equiv authentication together
826
Specifies whether rhosts or /etc/hosts.equiv authentication together
811
with successful RSA host authentication is allowed.
827
with successful RSA host authentication is allowed.

Return to bug 983