|
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 |
|