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

Collapse All | Expand All

(-)auth.c (-3 / +59 lines)
Lines 163-169 allowed_user(struct passwd * pw) Link Here
163
}
163
}
164
164
165
void
165
void
166
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
166
auth_log(Authctxt *authctxt, int authenticated, const char *method,
167
    const char *submethod, const char *info)
167
{
168
{
168
	void (*authlog) (const char *fmt,...) = verbose;
169
	void (*authlog) (const char *fmt,...) = verbose;
169
	char *authmsg;
170
	char *authmsg;
Lines 183-191 auth_log(Authctxt *authctxt, int authent Link Here
183
	else
184
	else
184
		authmsg = authenticated ? "Accepted" : "Failed";
185
		authmsg = authenticated ? "Accepted" : "Failed";
185
186
186
	authlog("%s %s for %s%.100s from %.200s port %d%s",
187
	authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
187
	    authmsg,
188
	    authmsg,
188
	    method,
189
	    method,
190
	    submethod == NULL ? "" : "/", submethod == NULL ? "" : submethod,
189
	    authctxt->valid ? "" : "invalid user ",
191
	    authctxt->valid ? "" : "invalid user ",
190
	    authctxt->user,
192
	    authctxt->user,
191
	    get_remote_ipaddr(),
193
	    get_remote_ipaddr(),
Lines 197-203 auth_log(Authctxt *authctxt, int authent Link Here
197
 * Check whether root logins are disallowed.
199
 * Check whether root logins are disallowed.
198
 */
200
 */
199
int
201
int
200
auth_root_allowed(char *method)
202
auth_root_allowed(const char *method)
201
{
203
{
202
	switch (options.permit_root_login) {
204
	switch (options.permit_root_login) {
203
	case PERMIT_YES:
205
	case PERMIT_YES:
Lines 467-470 fakepw(void) Link Here
467
	fake.pw_shell = "/nonexist";
469
	fake.pw_shell = "/nonexist";
468
470
469
	return (&fake);
471
	return (&fake);
472
}
473
474
int
475
auth_method_in_list(const char *list, const char *method)
476
{
477
	char *cp;
478
479
	cp = match_list(method, list, NULL);
480
	if (cp != NULL) {
481
		xfree(cp);
482
		return 1;
483
	}
484
485
	return 0;
486
}
487
488
#define	DELIM	","
489
int
490
auth_remove_from_list(char **list, const char *method)
491
{
492
	char *oldlist, *cp, *newlist = NULL;
493
	u_int len = 0, ret = 0;
494
495
	if (list == NULL || *list == NULL)
496
		return (0);
497
498
	oldlist = *list;
499
	len = strlen(oldlist) + 1;
500
	newlist = xmalloc(len);
501
	memset(newlist, '\0', len);
502
503
	/* Remove method from list, if present */
504
	for (;;) {
505
		if ((cp = strsep(&oldlist, DELIM)) == NULL)
506
			break;
507
		if (*cp == '\0')
508
			continue;
509
		if (strcmp(cp, method) != 0) {
510
			if (*newlist != '\0')
511
				strlcat(newlist, DELIM, len);
512
			strlcat(newlist, cp, len);
513
		} else
514
			ret++;
515
	}
516
517
	/* Return NULL instead of empty list */
518
	if (*newlist == '\0') {
519
		xfree(newlist);
520
		newlist = NULL;
521
	}
522
	xfree(*list);
523
	*list = newlist;
524
	
525
	return (ret);
470
}
526
}
(-)auth.h (-3 / +8 lines)
Lines 125-133 void krb5_cleanup_proc(Authctxt *authctx Link Here
125
void	do_authentication(Authctxt *);
125
void	do_authentication(Authctxt *);
126
void	do_authentication2(Authctxt *);
126
void	do_authentication2(Authctxt *);
127
127
128
void	auth_log(Authctxt *, int, char *, char *);
128
void	auth_log(Authctxt *, int, const char *, const char *, const char *);
129
void	userauth_finish(Authctxt *, int, char *);
129
void	userauth_finish(Authctxt *, int, const char *, const char *);
130
int	auth_root_allowed(char *);
130
int	auth_root_allowed(const char *);
131
131
132
char	*auth2_read_banner(void);
132
char	*auth2_read_banner(void);
133
133
Lines 168-173 void auth_debug_send(void); Link Here
168
void	 auth_debug_reset(void);
168
void	 auth_debug_reset(void);
169
169
170
struct passwd *fakepw(void);
170
struct passwd *fakepw(void);
171
int	 auth_method_in_list(const char *, const char *);
172
int	 auth_remove_from_list(char **, const char *);
173
174
int	 auth1_check_required(const char *);
175
int	 auth2_check_required(const char *);
171
176
172
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
177
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
173
178
(-)auth1.c (-5 / +88 lines)
Lines 80-85 static const struct AuthMethod1 Link Here
80
	return (NULL);
80
	return (NULL);
81
}
81
}
82
82
83
static const struct AuthMethod1 *
84
lookup_authmethod1_by_name(const char *name)
85
{
86
	int i;
87
88
	for (i = 0; auth1_methods[i].name != NULL; i++)
89
		if (strcmp(auth1_methods[i].name, name) == 0)
90
			return (&(auth1_methods[i]));
91
92
	return NULL;
93
}
94
95
#define	DELIM	","
96
int
97
auth1_check_required(const char *list)
98
{
99
	char *orig_methods, *methods, *cp;
100
	static const struct AuthMethod1 *m;
101
	int ret = 0;
102
103
	orig_methods = methods = xstrdup(list);
104
	for(;;) { /* XXX maybe: while ((cp = ...) != NULL) ? */
105
		if ((cp = strsep(&methods, DELIM)) == NULL)
106
			break;
107
		debug2("auth1_check_required: method \"%s\"", cp);
108
		if (*cp == '\0') {
109
			debug("auth1_check_required: empty method");
110
			ret = -1;
111
		}
112
		if ((m = lookup_authmethod1_by_name(cp)) == NULL) {
113
			debug("auth1_check_required: unknown method "
114
			    "\"%s\"", cp);
115
			ret = -1;
116
		}
117
		if (*(m->enabled) == 0) {
118
			debug("auth1_check_required: method %s explicitly "
119
			    "disabled", cp);
120
			ret = -1;
121
		}
122
		/* Activate method if it isn't already */
123
		if (*(m->enabled) == -1)
124
			*(m->enabled) = 1;
125
        }
126
	xfree(orig_methods);
127
	return (ret);
128
}
129
83
static char *
130
static char *
84
get_authname(int type)
131
get_authname(int type)
85
{
132
{
Lines 221-226 do_authloop(Authctxt *authctxt) Link Here
221
{
268
{
222
	int authenticated = 0;
269
	int authenticated = 0;
223
	char info[1024];
270
	char info[1024];
271
	const char *meth_name;
224
	int type = 0;
272
	int type = 0;
225
	const struct AuthMethod1 *meth;
273
	const struct AuthMethod1 *meth;
226
274
Lines 228-239 do_authloop(Authctxt *authctxt) Link Here
228
	    authctxt->valid ? "" : "invalid user ", authctxt->user);
276
	    authctxt->valid ? "" : "invalid user ", authctxt->user);
229
277
230
	/* If the user has no password, accept authentication immediately. */
278
	/* If the user has no password, accept authentication immediately. */
231
	if (options.password_authentication &&
279
	if (options.required_auth1 == NULL && options.password_authentication &&
232
#ifdef KRB5
280
#ifdef KRB5
233
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
281
	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
234
#endif
282
#endif
235
	    PRIVSEP(auth_password(authctxt, ""))) {
283
	    PRIVSEP(auth_password(authctxt, ""))) {
236
		auth_log(authctxt, 1, "without authentication", "");
284
		auth_log(authctxt, 1, "without authentication", NULL, "");
237
		return;
285
		return;
238
	}
286
	}
239
287
Lines 250-258 do_authloop(Authctxt *authctxt) Link Here
250
298
251
		/* Get a packet from the client. */
299
		/* Get a packet from the client. */
252
		type = packet_read();
300
		type = packet_read();
301
		meth_name = get_authname(type);
253
		if ((meth = lookup_authmethod1(type)) == NULL) {
302
		if ((meth = lookup_authmethod1(type)) == NULL) {
254
			logit("Unknown message during authentication: "
303
			logit("Unknown message during authentication: type %d",
255
			    "type %d", type);
304
			    type);
256
			goto skip;
305
			goto skip;
257
		}
306
		}
258
307
Lines 261-266 do_authloop(Authctxt *authctxt) Link Here
261
			goto skip;
310
			goto skip;
262
		}
311
		}
263
312
313
		/*
314
		 * Skip methods not in required list, until all the required
315
		 * ones are done
316
		 */
317
		if (options.required_auth1 != NULL &&
318
		    !auth_method_in_list(options.required_auth1, meth_name)) {
319
			debug("Skipping method \"%s\" until required "
320
			    "authentication completed", meth_name);
321
			goto skip;
322
		}
323
264
		authenticated = meth->method(authctxt, info, sizeof(info));
324
		authenticated = meth->method(authctxt, info, sizeof(info));
265
		if (authenticated == -1)
325
		if (authenticated == -1)
266
			continue; /* "postponed" */
326
			continue; /* "postponed" */
Lines 282-288 do_authloop(Authctxt *authctxt) Link Here
282
342
283
 skip:
343
 skip:
284
		/* Log before sending the reply */
344
		/* Log before sending the reply */
285
		auth_log(authctxt, authenticated, get_authname(type), info);
345
		auth_log(authctxt, authenticated, meth_name, NULL, info);
346
347
		/* Loop until the required authmethods are done */
348
		if (authenticated && options.required_auth1 != NULL) {
349
			if (auth_remove_from_list(&options.required_auth1,
350
			    meth_name) != 1)
351
				fatal("INTERNAL ERROR: authenticated method "
352
				    "\"%s\" not in required list \"%s\"",
353
				    meth_name, options.required_auth1);
354
			debug2("do_authloop: required list now: %s",
355
			    options.required_auth1 == NULL ?
356
			    "DONE" : options.required_auth1);
357
			if (options.required_auth1 == NULL)
358
				return;
359
			authenticated = 0;
360
			/*
361
			 * Disable method so client can't authenticate with it
362
			 * after the required authentications are complete.
363
			 */
364
			*(meth->enabled) = 0;
365
			packet_send_debug("Further authentication required");
366
			goto send_fail;
367
		}
286
368
287
		if (authenticated)
369
		if (authenticated)
288
			return;
370
			return;
Lines 290-295 do_authloop(Authctxt *authctxt) Link Here
290
		if (authctxt->failures++ > options.max_authtries)
372
		if (authctxt->failures++ > options.max_authtries)
291
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
373
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
292
374
375
 send_fail:
293
		packet_start(SSH_SMSG_FAILURE);
376
		packet_start(SSH_SMSG_FAILURE);
294
		packet_send();
377
		packet_send();
295
		packet_write_wait();
378
		packet_write_wait();
(-)auth2-chall.c (-10 / +4 lines)
Lines 242-250 input_userauth_info_response(int type, u Link Here
242
{
242
{
243
	Authctxt *authctxt = ctxt;
243
	Authctxt *authctxt = ctxt;
244
	KbdintAuthctxt *kbdintctxt;
244
	KbdintAuthctxt *kbdintctxt;
245
	int authenticated = 0, res, len;
245
	int authenticated = 0, res;
246
	u_int i, nresp;
246
	u_int i, nresp;
247
	char **response = NULL, *method;
247
	char **response = NULL;
248
248
249
	if (authctxt == NULL)
249
	if (authctxt == NULL)
250
		fatal("input_userauth_info_response: no authctxt");
250
		fatal("input_userauth_info_response: no authctxt");
Lines 291-302 input_userauth_info_response(int type, u Link Here
291
		break;
291
		break;
292
	}
292
	}
293
293
294
	len = strlen("keyboard-interactive") + 2 +
295
		strlen(kbdintctxt->device->name);
296
	method = xmalloc(len);
297
	snprintf(method, len, "keyboard-interactive/%s",
298
	    kbdintctxt->device->name);
299
300
	if (!authctxt->postponed) {
294
	if (!authctxt->postponed) {
301
		if (authenticated) {
295
		if (authenticated) {
302
			auth2_challenge_stop(authctxt);
296
			auth2_challenge_stop(authctxt);
Lines 306-313 input_userauth_info_response(int type, u Link Here
306
			auth2_challenge_start(authctxt);
300
			auth2_challenge_start(authctxt);
307
		}
301
		}
308
	}
302
	}
309
	userauth_finish(authctxt, authenticated, method);
303
	userauth_finish(authctxt, authenticated, "keyboard-interactive",
310
	xfree(method);
304
	    kbdintctxt->device->name);
311
}
305
}
312
306
313
void
307
void
(-)auth2-gss.c (-3 / +3 lines)
Lines 155-161 input_gssapi_token(int type, u_int32_t p Link Here
155
		}
155
		}
156
		authctxt->postponed = 0;
156
		authctxt->postponed = 0;
157
		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
157
		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
158
		userauth_finish(authctxt, 0, "gssapi-with-mic");
158
		userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
159
	} else {
159
	} else {
160
		if (send_tok.length != 0) {
160
		if (send_tok.length != 0) {
161
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
161
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
Lines 243-249 input_gssapi_exchange_complete(int type, Link Here
243
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
243
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
244
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
244
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
245
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
245
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
246
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
246
	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
247
}
247
}
248
248
249
static void
249
static void
Lines 283-289 input_gssapi_mic(int type, u_int32_t ple Link Here
283
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
283
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
284
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
284
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
285
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
285
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
286
	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
286
	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
287
}
287
}
288
288
289
Authmethod method_gssapi = {
289
Authmethod method_gssapi = {
(-)auth2-none.c (-1 / +1 lines)
Lines 104-110 userauth_none(Authctxt *authctxt) Link Here
104
	none_enabled = 0;
104
	none_enabled = 0;
105
	packet_check_eom();
105
	packet_check_eom();
106
	userauth_banner();
106
	userauth_banner();
107
	if (options.password_authentication)
107
	if (options.password_authentication && options.required_auth2 == NULL)
108
		return (PRIVSEP(auth_password(authctxt, "")));
108
		return (PRIVSEP(auth_password(authctxt, "")));
109
	return (0);
109
	return (0);
110
}
110
}
(-)auth2.c (-10 / +82 lines)
Lines 134-140 input_userauth_request(int type, u_int32 Link Here
134
{
134
{
135
	Authctxt *authctxt = ctxt;
135
	Authctxt *authctxt = ctxt;
136
	Authmethod *m = NULL;
136
	Authmethod *m = NULL;
137
	char *user, *service, *method, *style = NULL;
137
	char *user, *service, *method, *active_methods, *style = NULL;
138
	int authenticated = 0;
138
	int authenticated = 0;
139
139
140
	if (authctxt == NULL)
140
	if (authctxt == NULL)
Lines 183-194 input_userauth_request(int type, u_int32 Link Here
183
	authctxt->postponed = 0;
183
	authctxt->postponed = 0;
184
184
185
	/* try to authenticate user */
185
	/* try to authenticate user */
186
	m = authmethod_lookup(method);
186
	active_methods = authmethods_get();
187
	if (m != NULL) {
187
	if (strcmp(method, "none") == 0 || 
188
		debug2("input_userauth_request: try method %s", method);
188
	    auth_method_in_list(active_methods, method)) {
189
		authenticated =	m->userauth(authctxt);
189
		m = authmethod_lookup(method);
190
		if (m != NULL) {
191
			debug2("input_userauth_request: try method %s", method);
192
			authenticated =	m->userauth(authctxt);
193
		}
190
	}
194
	}
191
	userauth_finish(authctxt, authenticated, method);
195
	xfree(active_methods);
196
	userauth_finish(authctxt, authenticated, method, NULL);
192
197
193
	xfree(service);
198
	xfree(service);
194
	xfree(user);
199
	xfree(user);
Lines 196-204 input_userauth_request(int type, u_int32 Link Here
196
}
201
}
197
202
198
void
203
void
199
userauth_finish(Authctxt *authctxt, int authenticated, char *method)
204
userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
205
    const char *submethod)
200
{
206
{
201
	char *methods;
207
	char *methods;
208
	Authmethod *m = NULL;
209
	u_int partial = 0;
202
210
203
	if (!authctxt->valid && authenticated)
211
	if (!authctxt->valid && authenticated)
204
		fatal("INTERNAL ERROR: authenticated invalid user %s",
212
		fatal("INTERNAL ERROR: authenticated invalid user %s",
Lines 210-221 userauth_finish(Authctxt *authctxt, int Link Here
210
		authenticated = 0;
218
		authenticated = 0;
211
219
212
	/* Log before sending the reply */
220
	/* Log before sending the reply */
213
	auth_log(authctxt, authenticated, method, " ssh2");
221
	auth_log(authctxt, authenticated, method, submethod, " ssh2");
214
222
215
	if (authctxt->postponed)
223
	if (authctxt->postponed)
216
		return;
224
		return;
225
226
	/* Handle RequiredAuthentications2: loop until required methods done */
227
	if (authenticated && options.required_auth2 != NULL) {
228
		if ((m = authmethod_lookup(method)) == NULL)
229
			fatal("INTERNAL ERROR: authenticated method "
230
			    "\"%s\" unknown", method);
231
		if (auth_remove_from_list(&options.required_auth2, method) != 1)
232
			fatal("INTERNAL ERROR: authenticated method "
233
			    "\"%s\" not in required list \"%s\"", 
234
			    method, options.required_auth2);
235
		debug2("userauth_finish: required list now: %s",
236
		    options.required_auth2 == NULL ?
237
		    "DONE" : options.required_auth2);
238
		/*
239
		 * Disable method so client can't authenticate with it after
240
		 * the required authentications are complete.
241
		 */
242
		if (m->enabled != NULL)
243
			*(m->enabled) = 0;
244
		authenticated = 0;
245
		partial = 1;
246
		goto send_fail;
247
	}
217
248
218
	/* XXX todo: check if multiple auth methods are needed */
219
	if (authenticated == 1) {
249
	if (authenticated == 1) {
220
		/* turn off userauth */
250
		/* turn off userauth */
221
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
251
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
Lines 227-236 userauth_finish(Authctxt *authctxt, int Link Here
227
	} else {
257
	} else {
228
		if (authctxt->failures++ > options.max_authtries)
258
		if (authctxt->failures++ > options.max_authtries)
229
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
259
			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
260
 send_fail:
230
		methods = authmethods_get();
261
		methods = authmethods_get();
231
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
262
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
232
		packet_put_cstring(methods);
263
		packet_put_cstring(methods);
233
		packet_put_char(0);	/* XXX partial success, unused */
264
		packet_put_char(partial);
234
		packet_send();
265
		packet_send();
235
		packet_write_wait();
266
		packet_write_wait();
236
		xfree(methods);
267
		xfree(methods);
Lines 246-251 authmethods_get(void) Link Here
246
	char *list;
277
	char *list;
247
	int i;
278
	int i;
248
279
280
	if (options.required_auth2 != NULL)
281
		return xstrdup(options.required_auth2);
282
249
	buffer_init(&b);
283
	buffer_init(&b);
250
	for (i = 0; authmethods[i] != NULL; i++) {
284
	for (i = 0; authmethods[i] != NULL; i++) {
251
		if (strcmp(authmethods[i]->name, "none") == 0)
285
		if (strcmp(authmethods[i]->name, "none") == 0)
Lines 278-281 authmethod_lookup(const char *name) Link Here
278
	debug2("Unrecognized authentication method name: %s",
312
	debug2("Unrecognized authentication method name: %s",
279
	    name ? name : "NULL");
313
	    name ? name : "NULL");
280
	return NULL;
314
	return NULL;
315
}
316
317
int
318
auth2_check_required(const char *list)
319
{
320
	char *orig_methods, *methods, *cp;
321
	struct Authmethod *m;
322
	int i, ret = 0;
323
324
	orig_methods = methods = xstrdup(list);
325
	for(;;) {
326
		if ((cp = strsep(&methods, DELIM)) == NULL)
327
			break;
328
		debug2("auth2_check_required: method \"%s\"", cp);
329
		if (*cp == '\0') {
330
			debug("auth2_check_required: empty method");
331
			ret = -1;
332
		}
333
		for (i = 0; authmethods[i] != NULL; i++)
334
			if (strcmp(cp, authmethods[i]->name) == 0)
335
				break;
336
		if ((m = authmethods[i]) == NULL) {
337
			debug("auth2_check_required: unknown method "
338
			    "\"%s\"", cp);
339
			ret = -1;
340
			break;
341
		}
342
		if (m->enabled == NULL || *(m->enabled) == 0) {
343
			debug("auth2_check_required: method %s explicitly "
344
			    "disabled", cp);
345
			ret = -1;
346
		}
347
		/* Activate method if it isn't already */
348
		if (*(m->enabled) == -1)
349
			*(m->enabled) = 1;
350
	}
351
	xfree(orig_methods);
352
	return (ret);
281
}
353
}
(-)monitor.c (-4 / +21 lines)
Lines 260-266 void Link Here
260
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
260
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
261
{
261
{
262
	struct mon_table *ent;
262
	struct mon_table *ent;
263
	int authenticated = 0;
263
	int no_increment, authenticated = 0;
264
	char **req_auth;
264
265
265
	debug3("preauth child monitor started");
266
	debug3("preauth child monitor started");
266
267
Lines 269-280 monitor_child_preauth(Authctxt *_authctx Link Here
269
270
270
	if (compat20) {
271
	if (compat20) {
271
		mon_dispatch = mon_dispatch_proto20;
272
		mon_dispatch = mon_dispatch_proto20;
273
		req_auth = &options.required_auth2;
272
274
273
		/* Permit requests for moduli and signatures */
275
		/* Permit requests for moduli and signatures */
274
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
276
		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
275
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
277
		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
276
	} else {
278
	} else {
277
		mon_dispatch = mon_dispatch_proto15;
279
		mon_dispatch = mon_dispatch_proto15;
280
		req_auth = &options.required_auth1;
278
281
279
		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
282
		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
280
	}
283
	}
Lines 282-287 monitor_child_preauth(Authctxt *_authctx Link Here
282
	/* The first few requests do not require asynchronous access */
285
	/* The first few requests do not require asynchronous access */
283
	while (!authenticated) {
286
	while (!authenticated) {
284
		auth_method = "unknown";
287
		auth_method = "unknown";
288
		no_increment = 0;
285
		authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
289
		authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
286
		if (authenticated) {
290
		if (authenticated) {
287
			if (!(ent->flags & MON_AUTHDECIDE))
291
			if (!(ent->flags & MON_AUTHDECIDE))
Lines 291-301 monitor_child_preauth(Authctxt *_authctx Link Here
291
			    !auth_root_allowed(auth_method))
295
			    !auth_root_allowed(auth_method))
292
				authenticated = 0;
296
				authenticated = 0;
293
		}
297
		}
298
		/* Loop until the required authmethods are done */
299
		if (authenticated && *req_auth != NULL) {
300
			if (auth_remove_from_list(req_auth, auth_method) != 1)
301
				fatal("INTERNAL ERROR: authenticated method "
302
				    "\"%s\" not in required list \"%s\"",
303
				    auth_method, *req_auth);
304
			debug2("monitor_child_preauth: required list now: %s",
305
			    *req_auth == NULL ? "DONE" : *req_auth);
306
			if (*req_auth != NULL)
307
				authenticated = 0;
308
			no_increment = 1;
309
		}
294
310
295
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
311
		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
296
			auth_log(authctxt, authenticated, auth_method,
312
			auth_log(authctxt, authenticated, auth_method, NULL,
297
			    compat20 ? " ssh2" : "");
313
			    compat20 ? " ssh2" : "");
298
			if (!authenticated)
314
			if (!authenticated && !no_increment)
299
				authctxt->failures++;
315
				authctxt->failures++;
300
		}
316
		}
301
	}
317
	}
Lines 825-831 mm_answer_keyallowed(int sock, Buffer *m Link Here
825
		hostbased_chost = chost;
841
		hostbased_chost = chost;
826
	} else {
842
	} else {
827
		/* Log failed attempt */
843
		/* Log failed attempt */
828
		auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
844
		auth_log(authctxt, 0, auth_method, NULL,
845
		    compat20 ? " ssh2" : "");
829
		xfree(blob);
846
		xfree(blob);
830
		xfree(cuser);
847
		xfree(cuser);
831
		xfree(chost);
848
		xfree(chost);
(-)servconf.c (+33 lines)
Lines 22-27 Link Here
22
#include "cipher.h"
22
#include "cipher.h"
23
#include "kex.h"
23
#include "kex.h"
24
#include "mac.h"
24
#include "mac.h"
25
#include "auth.h"
25
26
26
static void add_listen_addr(ServerOptions *, char *, u_short);
27
static void add_listen_addr(ServerOptions *, char *, u_short);
27
static void add_one_listen_addr(ServerOptions *, char *, u_short);
28
static void add_one_listen_addr(ServerOptions *, char *, u_short);
Lines 97-102 initialize_server_options(ServerOptions Link Here
97
	options->authorized_keys_file2 = NULL;
98
	options->authorized_keys_file2 = NULL;
98
	options->num_accept_env = 0;
99
	options->num_accept_env = 0;
99
	options->permit_tun = -1;
100
	options->permit_tun = -1;
101
	options->required_auth1 = NULL;
102
	options->required_auth2 = NULL;
100
103
101
	/* Needs to be accessable in many places */
104
	/* Needs to be accessable in many places */
102
	use_privsep = -1;
105
	use_privsep = -1;
Lines 251-256 typedef enum { Link Here
251
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
254
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
252
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
255
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
253
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
256
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
257
	sRequiredAuthentications1, sRequiredAuthentications2,
254
	sUsePrivilegeSeparation,
258
	sUsePrivilegeSeparation,
255
	sDeprecated, sUnsupported
259
	sDeprecated, sUnsupported
256
} ServerOpCodes;
260
} ServerOpCodes;
Lines 342-347 static struct { Link Here
342
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
346
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
343
	{ "acceptenv", sAcceptEnv },
347
	{ "acceptenv", sAcceptEnv },
344
	{ "permittunnel", sPermitTunnel },
348
	{ "permittunnel", sPermitTunnel },
349
	{ "requiredauthentications1", sRequiredAuthentications1 },
350
	{ "requiredauthentications2", sRequiredAuthentications2 },
345
	{ NULL, sBadOption }
351
	{ NULL, sBadOption }
346
};
352
};
347
353
Lines 883-888 parse_flag: Link Here
883
			    filename, linenum);
889
			    filename, linenum);
884
		else
890
		else
885
			options->max_startups = options->max_startups_begin;
891
			options->max_startups = options->max_startups_begin;
892
		break;
893
894
895
	case sRequiredAuthentications1:
896
		charptr = &options->required_auth1;
897
		arg = strdelim(&cp);
898
		if (auth1_check_required(arg) != 0)
899
			fatal("%.200s line %d: Invalid required authentication "
900
			    "list", filename, linenum);
901
		if (!arg || *arg == '\0')
902
			fatal("%.200s line %d: Missing argument.",
903
			    filename, linenum);
904
		if (*charptr == NULL)
905
			*charptr = xstrdup(arg);
906
		break;
907
908
	case sRequiredAuthentications2:
909
		charptr = &options->required_auth2;
910
		arg = strdelim(&cp);
911
		if (auth2_check_required(arg) != 0)
912
			fatal("%.200s line %d: Invalid required authentication "
913
			    "list", filename, linenum);
914
		if (!arg || *arg == '\0')
915
			fatal("%.200s line %d: Missing argument.",
916
			    filename, linenum);
917
		if (*charptr == NULL)
918
			*charptr = xstrdup(arg);
886
		break;
919
		break;
887
920
888
	case sMaxAuthTries:
921
	case sMaxAuthTries:
(-)servconf.h (+3 lines)
Lines 135-140 typedef struct { Link Here
135
	char   *authorized_keys_file2;
135
	char   *authorized_keys_file2;
136
136
137
	int	permit_tun;
137
	int	permit_tun;
138
139
	char   *required_auth1; /* Required, but not sufficient */
140
	char   *required_auth2;
138
}       ServerOptions;
141
}       ServerOptions;
139
142
140
void	 initialize_server_options(ServerOptions *);
143
void	 initialize_server_options(ServerOptions *);

Return to bug 983