diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | auth2.c | 321 |
2 files changed, 3 insertions, 322 deletions
@@ -133,6 +133,8 @@ | |||
133 | - (bal) Missed msg.[ch] in merge. Required for ssh-keysign. | 133 | - (bal) Missed msg.[ch] in merge. Required for ssh-keysign. |
134 | - (bal) Forgot to add msg.c Makefile.in. | 134 | - (bal) Forgot to add msg.c Makefile.in. |
135 | - (bal) monitor_mm.c typos. | 135 | - (bal) monitor_mm.c typos. |
136 | - (bal) Refixed auth2.c. It was never fully commited while spliting out | ||
137 | authentication to different files. | ||
136 | 138 | ||
137 | 20020604 | 139 | 20020604 |
138 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed | 140 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed |
@@ -817,4 +819,4 @@ | |||
817 | - (stevesk) entropy.c: typo in debug message | 819 | - (stevesk) entropy.c: typo in debug message |
818 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ | 820 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ |
819 | 821 | ||
820 | $Id: ChangeLog,v 1.2182 2002/06/07 01:57:25 mouring Exp $ | 822 | $Id: ChangeLog,v 1.2183 2002/06/07 02:05:25 mouring Exp $ |
@@ -249,327 +249,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) | |||
249 | } | 249 | } |
250 | } | 250 | } |
251 | 251 | ||
252 | char * | ||
253 | auth2_read_banner(void) | ||
254 | { | ||
255 | struct stat st; | ||
256 | char *banner = NULL; | ||
257 | off_t len, n; | ||
258 | int fd; | ||
259 | |||
260 | if ((fd = open(options.banner, O_RDONLY)) == -1) | ||
261 | return (NULL); | ||
262 | if (fstat(fd, &st) == -1) { | ||
263 | close(fd); | ||
264 | return (NULL); | ||
265 | } | ||
266 | len = st.st_size; | ||
267 | banner = xmalloc(len + 1); | ||
268 | n = atomicio(read, fd, banner, len); | ||
269 | close(fd); | ||
270 | |||
271 | if (n != len) { | ||
272 | free(banner); | ||
273 | return (NULL); | ||
274 | } | ||
275 | banner[n] = '\0'; | ||
276 | |||
277 | return (banner); | ||
278 | } | ||
279 | |||
280 | static void | ||
281 | userauth_banner(void) | ||
282 | { | ||
283 | char *banner = NULL; | ||
284 | |||
285 | if (options.banner == NULL || (datafellows & SSH_BUG_BANNER)) | ||
286 | return; | ||
287 | |||
288 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) | ||
289 | goto done; | ||
290 | |||
291 | packet_start(SSH2_MSG_USERAUTH_BANNER); | ||
292 | packet_put_cstring(banner); | ||
293 | packet_put_cstring(""); /* language, unused */ | ||
294 | packet_send(); | ||
295 | debug("userauth_banner: sent"); | ||
296 | done: | ||
297 | if (banner) | ||
298 | xfree(banner); | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | static int | ||
303 | userauth_none(Authctxt *authctxt) | ||
304 | { | ||
305 | /* disable method "none", only allowed one time */ | ||
306 | Authmethod *m = authmethod_lookup("none"); | ||
307 | if (m != NULL) | ||
308 | m->enabled = NULL; | ||
309 | packet_check_eom(); | ||
310 | userauth_banner(); | ||
311 | |||
312 | if (authctxt->valid == 0) | ||
313 | return(0); | ||
314 | |||
315 | #ifdef HAVE_CYGWIN | ||
316 | if (check_nt_auth(1, authctxt->pw) == 0) | ||
317 | return(0); | ||
318 | #endif | ||
319 | return PRIVSEP(auth_password(authctxt, "")); | ||
320 | } | ||
321 | |||
322 | static int | ||
323 | userauth_passwd(Authctxt *authctxt) | ||
324 | { | ||
325 | char *password; | ||
326 | int authenticated = 0; | ||
327 | int change; | ||
328 | u_int len; | ||
329 | change = packet_get_char(); | ||
330 | if (change) | ||
331 | log("password change not supported"); | ||
332 | password = packet_get_string(&len); | ||
333 | packet_check_eom(); | ||
334 | if (authctxt->valid && | ||
335 | #ifdef HAVE_CYGWIN | ||
336 | check_nt_auth(1, authctxt->pw) && | ||
337 | #endif | ||
338 | PRIVSEP(auth_password(authctxt, password)) == 1) | ||
339 | authenticated = 1; | ||
340 | memset(password, 0, len); | ||
341 | xfree(password); | ||
342 | return authenticated; | ||
343 | } | ||
344 | |||
345 | static int | ||
346 | userauth_kbdint(Authctxt *authctxt) | ||
347 | { | ||
348 | int authenticated = 0; | ||
349 | char *lang, *devs; | ||
350 | |||
351 | lang = packet_get_string(NULL); | ||
352 | devs = packet_get_string(NULL); | ||
353 | packet_check_eom(); | ||
354 | |||
355 | debug("keyboard-interactive devs %s", devs); | ||
356 | |||
357 | if (options.challenge_response_authentication) | ||
358 | authenticated = auth2_challenge(authctxt, devs); | ||
359 | |||
360 | #ifdef USE_PAM | ||
361 | if (authenticated == 0 && options.pam_authentication_via_kbd_int) | ||
362 | authenticated = auth2_pam(authctxt); | ||
363 | #endif | ||
364 | xfree(devs); | ||
365 | xfree(lang); | ||
366 | #ifdef HAVE_CYGWIN | ||
367 | if (check_nt_auth(0, authctxt->pw) == 0) | ||
368 | return(0); | ||
369 | #endif | ||
370 | return authenticated; | ||
371 | } | ||
372 | |||
373 | static int | ||
374 | userauth_pubkey(Authctxt *authctxt) | ||
375 | { | ||
376 | Buffer b; | ||
377 | Key *key = NULL; | ||
378 | char *pkalg; | ||
379 | u_char *pkblob, *sig; | ||
380 | u_int alen, blen, slen; | ||
381 | int have_sig, pktype; | ||
382 | int authenticated = 0; | ||
383 | |||
384 | if (!authctxt->valid) { | ||
385 | debug2("userauth_pubkey: disabled because of invalid user"); | ||
386 | return 0; | ||
387 | } | ||
388 | have_sig = packet_get_char(); | ||
389 | if (datafellows & SSH_BUG_PKAUTH) { | ||
390 | debug2("userauth_pubkey: SSH_BUG_PKAUTH"); | ||
391 | /* no explicit pkalg given */ | ||
392 | pkblob = packet_get_string(&blen); | ||
393 | buffer_init(&b); | ||
394 | buffer_append(&b, pkblob, blen); | ||
395 | /* so we have to extract the pkalg from the pkblob */ | ||
396 | pkalg = buffer_get_string(&b, &alen); | ||
397 | buffer_free(&b); | ||
398 | } else { | ||
399 | pkalg = packet_get_string(&alen); | ||
400 | pkblob = packet_get_string(&blen); | ||
401 | } | ||
402 | pktype = key_type_from_name(pkalg); | ||
403 | if (pktype == KEY_UNSPEC) { | ||
404 | /* this is perfectly legal */ | ||
405 | log("userauth_pubkey: unsupported public key algorithm: %s", | ||
406 | pkalg); | ||
407 | goto done; | ||
408 | } | ||
409 | key = key_from_blob(pkblob, blen); | ||
410 | if (key == NULL) { | ||
411 | error("userauth_pubkey: cannot decode key: %s", pkalg); | ||
412 | goto done; | ||
413 | } | ||
414 | if (key->type != pktype) { | ||
415 | error("userauth_pubkey: type mismatch for decoded key " | ||
416 | "(received %d, expected %d)", key->type, pktype); | ||
417 | goto done; | ||
418 | } | ||
419 | if (have_sig) { | ||
420 | sig = packet_get_string(&slen); | ||
421 | packet_check_eom(); | ||
422 | buffer_init(&b); | ||
423 | if (datafellows & SSH_OLD_SESSIONID) { | ||
424 | buffer_append(&b, session_id2, session_id2_len); | ||
425 | } else { | ||
426 | buffer_put_string(&b, session_id2, session_id2_len); | ||
427 | } | ||
428 | /* reconstruct packet */ | ||
429 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
430 | buffer_put_cstring(&b, authctxt->user); | ||
431 | buffer_put_cstring(&b, | ||
432 | datafellows & SSH_BUG_PKSERVICE ? | ||
433 | "ssh-userauth" : | ||
434 | authctxt->service); | ||
435 | if (datafellows & SSH_BUG_PKAUTH) { | ||
436 | buffer_put_char(&b, have_sig); | ||
437 | } else { | ||
438 | buffer_put_cstring(&b, "publickey"); | ||
439 | buffer_put_char(&b, have_sig); | ||
440 | buffer_put_cstring(&b, pkalg); | ||
441 | } | ||
442 | buffer_put_string(&b, pkblob, blen); | ||
443 | #ifdef DEBUG_PK | ||
444 | buffer_dump(&b); | ||
445 | #endif | ||
446 | /* test for correct signature */ | ||
447 | authenticated = 0; | ||
448 | if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && | ||
449 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | ||
450 | buffer_len(&b))) == 1) | ||
451 | authenticated = 1; | ||
452 | buffer_clear(&b); | ||
453 | xfree(sig); | ||
454 | } else { | ||
455 | debug("test whether pkalg/pkblob are acceptable"); | ||
456 | packet_check_eom(); | ||
457 | |||
458 | /* XXX fake reply and always send PK_OK ? */ | ||
459 | /* | ||
460 | * XXX this allows testing whether a user is allowed | ||
461 | * to login: if you happen to have a valid pubkey this | ||
462 | * message is sent. the message is NEVER sent at all | ||
463 | * if a user is not allowed to login. is this an | ||
464 | * issue? -markus | ||
465 | */ | ||
466 | if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { | ||
467 | packet_start(SSH2_MSG_USERAUTH_PK_OK); | ||
468 | packet_put_string(pkalg, alen); | ||
469 | packet_put_string(pkblob, blen); | ||
470 | packet_send(); | ||
471 | packet_write_wait(); | ||
472 | authctxt->postponed = 1; | ||
473 | } | ||
474 | } | ||
475 | if (authenticated != 1) | ||
476 | auth_clear_options(); | ||
477 | done: | ||
478 | debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); | ||
479 | if (key != NULL) | ||
480 | key_free(key); | ||
481 | xfree(pkalg); | ||
482 | xfree(pkblob); | ||
483 | #ifdef HAVE_CYGWIN | ||
484 | if (check_nt_auth(0, authctxt->pw) == 0) | ||
485 | return(0); | ||
486 | #endif | ||
487 | return authenticated; | ||
488 | } | ||
489 | |||
490 | static int | ||
491 | userauth_hostbased(Authctxt *authctxt) | ||
492 | { | ||
493 | Buffer b; | ||
494 | Key *key = NULL; | ||
495 | char *pkalg, *cuser, *chost, *service; | ||
496 | u_char *pkblob, *sig; | ||
497 | u_int alen, blen, slen; | ||
498 | int pktype; | ||
499 | int authenticated = 0; | ||
500 | |||
501 | if (!authctxt->valid) { | ||
502 | debug2("userauth_hostbased: disabled because of invalid user"); | ||
503 | return 0; | ||
504 | } | ||
505 | pkalg = packet_get_string(&alen); | ||
506 | pkblob = packet_get_string(&blen); | ||
507 | chost = packet_get_string(NULL); | ||
508 | cuser = packet_get_string(NULL); | ||
509 | sig = packet_get_string(&slen); | ||
510 | |||
511 | debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", | ||
512 | cuser, chost, pkalg, slen); | ||
513 | #ifdef DEBUG_PK | ||
514 | debug("signature:"); | ||
515 | buffer_init(&b); | ||
516 | buffer_append(&b, sig, slen); | ||
517 | buffer_dump(&b); | ||
518 | buffer_free(&b); | ||
519 | #endif | ||
520 | pktype = key_type_from_name(pkalg); | ||
521 | if (pktype == KEY_UNSPEC) { | ||
522 | /* this is perfectly legal */ | ||
523 | log("userauth_hostbased: unsupported " | ||
524 | "public key algorithm: %s", pkalg); | ||
525 | goto done; | ||
526 | } | ||
527 | key = key_from_blob(pkblob, blen); | ||
528 | if (key == NULL) { | ||
529 | error("userauth_hostbased: cannot decode key: %s", pkalg); | ||
530 | goto done; | ||
531 | } | ||
532 | if (key->type != pktype) { | ||
533 | error("userauth_hostbased: type mismatch for decoded key " | ||
534 | "(received %d, expected %d)", key->type, pktype); | ||
535 | goto done; | ||
536 | } | ||
537 | service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : | ||
538 | authctxt->service; | ||
539 | buffer_init(&b); | ||
540 | buffer_put_string(&b, session_id2, session_id2_len); | ||
541 | /* reconstruct packet */ | ||
542 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
543 | buffer_put_cstring(&b, authctxt->user); | ||
544 | buffer_put_cstring(&b, service); | ||
545 | buffer_put_cstring(&b, "hostbased"); | ||
546 | buffer_put_string(&b, pkalg, alen); | ||
547 | buffer_put_string(&b, pkblob, blen); | ||
548 | buffer_put_cstring(&b, chost); | ||
549 | buffer_put_cstring(&b, cuser); | ||
550 | #ifdef DEBUG_PK | ||
551 | buffer_dump(&b); | ||
552 | #endif | ||
553 | /* test for allowed key and correct signature */ | ||
554 | authenticated = 0; | ||
555 | if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && | ||
556 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | ||
557 | buffer_len(&b))) == 1) | ||
558 | authenticated = 1; | ||
559 | |||
560 | buffer_clear(&b); | ||
561 | done: | ||
562 | debug2("userauth_hostbased: authenticated %d", authenticated); | ||
563 | if (key != NULL) | ||
564 | key_free(key); | ||
565 | xfree(pkalg); | ||
566 | xfree(pkblob); | ||
567 | xfree(cuser); | ||
568 | xfree(chost); | ||
569 | xfree(sig); | ||
570 | return authenticated; | ||
571 | } | ||
572 | |||
573 | /* get current user */ | 252 | /* get current user */ |
574 | 253 | ||
575 | struct passwd* | 254 | struct passwd* |