|
Lines 209-215
input_userauth_request(int type, u_int32
Link Here
|
| 209 |
{ |
209 |
{ |
| 210 |
Authctxt *authctxt = ctxt; |
210 |
Authctxt *authctxt = ctxt; |
| 211 |
Authmethod *m = NULL; |
211 |
Authmethod *m = NULL; |
| 212 |
char *user, *service, *method, *style = NULL; |
212 |
char *user, *service, *method, *active_methods, *style = NULL; |
| 213 |
int authenticated = 0; |
213 |
int authenticated = 0; |
| 214 |
|
214 |
|
| 215 |
if (authctxt == NULL) |
215 |
if (authctxt == NULL) |
|
Lines 266-287
input_userauth_request(int type, u_int32
Link Here
|
| 266 |
authctxt->postponed = 0; |
266 |
authctxt->postponed = 0; |
| 267 |
|
267 |
|
| 268 |
/* try to authenticate user */ |
268 |
/* try to authenticate user */ |
| 269 |
m = authmethod_lookup(method); |
269 |
active_methods = authmethods_get(); |
| 270 |
if (m != NULL && authctxt->failures < options.max_authtries) { |
270 |
if (strcmp(method, "none") == 0 || |
| 271 |
debug2("input_userauth_request: try method %s", method); |
271 |
auth_method_in_list(active_methods, method)) { |
| 272 |
authenticated = m->userauth(authctxt); |
272 |
m = authmethod_lookup(method); |
| 273 |
} |
273 |
if (m != NULL) { |
| 274 |
userauth_finish(authctxt, authenticated, method); |
274 |
debug2("input_userauth_request: try method %s", method); |
|
|
275 |
authenticated = m->userauth(authctxt); |
| 276 |
} |
| 275 |
|
277 |
|
|
|
278 |
} |
| 279 |
xfree(active_methods); |
| 280 |
userauth_finish(authctxt, authenticated, method, NULL); |
| 281 |
|
| 276 |
xfree(service); |
282 |
xfree(service); |
| 277 |
xfree(user); |
283 |
xfree(user); |
| 278 |
xfree(method); |
284 |
xfree(method); |
| 279 |
} |
285 |
} |
| 280 |
|
286 |
|
| 281 |
void |
287 |
void |
| 282 |
userauth_finish(Authctxt *authctxt, int authenticated, char *method) |
288 |
userauth_finish(Authctxt *authctxt, int authenticated, const char *method, |
|
|
289 |
const char *submethod) |
| 283 |
{ |
290 |
{ |
| 284 |
char *methods; |
291 |
char *methods; |
|
|
292 |
Authmethod *m = NULL; |
| 293 |
u_int partial = 0; |
| 285 |
|
294 |
|
| 286 |
if (!authctxt->valid && authenticated) |
295 |
if (!authctxt->valid && authenticated) |
| 287 |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
296 |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
|
Lines 319-330
userauth_finish(Authctxt *authctxt, int
Link Here
|
| 319 |
#endif /* _UNICOS */ |
328 |
#endif /* _UNICOS */ |
| 320 |
|
329 |
|
| 321 |
/* Log before sending the reply */ |
330 |
/* Log before sending the reply */ |
| 322 |
auth_log(authctxt, authenticated, method, " ssh2"); |
331 |
auth_log(authctxt, authenticated, method, submethod, " ssh2"); |
| 323 |
|
332 |
|
| 324 |
if (authctxt->postponed) |
333 |
if (authctxt->postponed) |
| 325 |
return; |
334 |
return; |
| 326 |
|
335 |
|
| 327 |
/* XXX todo: check if multiple auth methods are needed */ |
336 |
/* Handle RequiredAuthentications2: loop until required methods done */ |
|
|
337 |
if (authenticated && options.required_auth2 != NULL) { |
| 338 |
if ((m = authmethod_lookup(method)) == NULL) |
| 339 |
fatal("INTERNAL ERROR: authenticated method " |
| 340 |
"\"%s\" unknown", method); |
| 341 |
if (auth_remove_from_list(&options.required_auth2, method) != 1) |
| 342 |
fatal("INTERNAL ERROR: authenticated method " |
| 343 |
"\"%s\" not in required list \"%s\"", |
| 344 |
method, options.required_auth2); |
| 345 |
debug2("userauth_finish: required list now: %s", |
| 346 |
options.required_auth2 == NULL ? |
| 347 |
"DONE" : options.required_auth2); |
| 348 |
/* |
| 349 |
* Disable method so client can't authenticate with it after |
| 350 |
* the required authentications are complete. |
| 351 |
*/ |
| 352 |
if (m->enabled != NULL) |
| 353 |
*(m->enabled) = 0; |
| 354 |
authenticated = 0; |
| 355 |
partial = 1; |
| 356 |
goto send_fail; |
| 357 |
} |
| 358 |
|
| 328 |
if (authenticated == 1) { |
359 |
if (authenticated == 1) { |
| 329 |
/* turn off userauth */ |
360 |
/* turn off userauth */ |
| 330 |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); |
361 |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); |
|
Lines 344-353
userauth_finish(Authctxt *authctxt, int
Link Here
|
| 344 |
#endif |
375 |
#endif |
| 345 |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
376 |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
| 346 |
} |
377 |
} |
|
|
378 |
send_fail: |
| 347 |
methods = authmethods_get(); |
379 |
methods = authmethods_get(); |
| 348 |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
380 |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
| 349 |
packet_put_cstring(methods); |
381 |
packet_put_cstring(methods); |
| 350 |
packet_put_char(0); /* XXX partial success, unused */ |
382 |
packet_put_char(partial); |
| 351 |
packet_send(); |
383 |
packet_send(); |
| 352 |
packet_write_wait(); |
384 |
packet_write_wait(); |
| 353 |
xfree(methods); |
385 |
xfree(methods); |
|
Lines 361-366
authmethods_get(void)
Link Here
|
| 361 |
char *list; |
393 |
char *list; |
| 362 |
int i; |
394 |
int i; |
| 363 |
|
395 |
|
|
|
396 |
if (options.required_auth2 != NULL) |
| 397 |
return xstrdup(options.required_auth2); |
| 398 |
|
| 364 |
buffer_init(&b); |
399 |
buffer_init(&b); |
| 365 |
for (i = 0; authmethods[i] != NULL; i++) { |
400 |
for (i = 0; authmethods[i] != NULL; i++) { |
| 366 |
if (strcmp(authmethods[i]->name, "none") == 0) |
401 |
if (strcmp(authmethods[i]->name, "none") == 0) |
|
Lines 393-397
authmethod_lookup(const char *name)
Link Here
|
| 393 |
debug2("Unrecognized authentication method name: %s", |
428 |
debug2("Unrecognized authentication method name: %s", |
| 394 |
name ? name : "NULL"); |
429 |
name ? name : "NULL"); |
| 395 |
return NULL; |
430 |
return NULL; |
|
|
431 |
} |
| 432 |
|
| 433 |
#define DELIM "," |
| 434 |
|
| 435 |
int |
| 436 |
auth2_check_required(const char *list) |
| 437 |
{ |
| 438 |
char *orig_methods, *methods, *cp; |
| 439 |
struct Authmethod *m; |
| 440 |
int i, ret = 0; |
| 441 |
|
| 442 |
orig_methods = methods = xstrdup(list); |
| 443 |
for(;;) { |
| 444 |
if ((cp = strsep(&methods, DELIM)) == NULL) |
| 445 |
break; |
| 446 |
debug2("auth2_check_required: method \"%s\"", cp); |
| 447 |
if (*cp == '\0') { |
| 448 |
debug("auth2_check_required: empty method"); |
| 449 |
ret = -1; |
| 450 |
} |
| 451 |
for (i = 0; authmethods[i] != NULL; i++) |
| 452 |
if (strcmp(cp, authmethods[i]->name) == 0) |
| 453 |
break; |
| 454 |
if ((m = authmethods[i]) == NULL) { |
| 455 |
debug("auth2_check_required: unknown method " |
| 456 |
"\"%s\"", cp); |
| 457 |
ret = -1; |
| 458 |
break; |
| 459 |
} |
| 460 |
if (m->enabled == NULL || *(m->enabled) == 0) { |
| 461 |
debug("auth2_check_required: method %s explicitly " |
| 462 |
"disabled", cp); |
| 463 |
ret = -1; |
| 464 |
} |
| 465 |
/* Activate method if it isn't already */ |
| 466 |
if (*(m->enabled) == -1) |
| 467 |
*(m->enabled) = 1; |
| 468 |
} |
| 469 |
xfree(orig_methods); |
| 470 |
return (ret); |
| 396 |
} |
471 |
} |
| 397 |
|
472 |
|