diff options
Diffstat (limited to 'auth-pam.c')
-rw-r--r-- | auth-pam.c | 100 |
1 files changed, 70 insertions, 30 deletions
diff --git a/auth-pam.c b/auth-pam.c index 8ffc1a587..b9f82a1d4 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -52,6 +52,7 @@ RCSID("$Id: auth-pam.c,v 1.72.2.2 2003/09/23 09:24:21 djm Exp $"); | |||
52 | #include "auth-options.h" | 52 | #include "auth-options.h" |
53 | 53 | ||
54 | extern ServerOptions options; | 54 | extern ServerOptions options; |
55 | extern Buffer loginmsg; | ||
55 | 56 | ||
56 | #define __unused | 57 | #define __unused |
57 | 58 | ||
@@ -419,13 +420,9 @@ sshpam_query(void *ctx, char **name, char **info, | |||
419 | case PAM_AUTH_ERR: | 420 | case PAM_AUTH_ERR: |
420 | if (**prompts != NULL) { | 421 | if (**prompts != NULL) { |
421 | /* drain any accumulated messages */ | 422 | /* drain any accumulated messages */ |
422 | #if 0 /* XXX - not compatible with privsep */ | 423 | debug("PAM: %s", **prompts); |
423 | packet_start(SSH2_MSG_USERAUTH_BANNER); | 424 | buffer_append(&loginmsg, **prompts, |
424 | packet_put_cstring(**prompts); | 425 | strlen(**prompts)); |
425 | packet_put_cstring(""); | ||
426 | packet_send(); | ||
427 | packet_write_wait(); | ||
428 | #endif | ||
429 | xfree(**prompts); | 426 | xfree(**prompts); |
430 | **prompts = NULL; | 427 | **prompts = NULL; |
431 | } | 428 | } |
@@ -550,21 +547,6 @@ do_pam_account(void) | |||
550 | } | 547 | } |
551 | 548 | ||
552 | void | 549 | void |
553 | do_pam_session(void) | ||
554 | { | ||
555 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | ||
556 | (const void *)&null_conv); | ||
557 | if (sshpam_err != PAM_SUCCESS) | ||
558 | fatal("PAM: failed to set PAM_CONV: %s", | ||
559 | pam_strerror(sshpam_handle, sshpam_err)); | ||
560 | sshpam_err = pam_open_session(sshpam_handle, 0); | ||
561 | if (sshpam_err != PAM_SUCCESS) | ||
562 | fatal("PAM: pam_open_session(): %s", | ||
563 | pam_strerror(sshpam_handle, sshpam_err)); | ||
564 | sshpam_session_open = 1; | ||
565 | } | ||
566 | |||
567 | void | ||
568 | do_pam_set_tty(const char *tty) | 550 | do_pam_set_tty(const char *tty) |
569 | { | 551 | { |
570 | if (tty != NULL) { | 552 | if (tty != NULL) { |
@@ -610,7 +592,7 @@ is_pam_password_change_required(void) | |||
610 | } | 592 | } |
611 | 593 | ||
612 | static int | 594 | static int |
613 | pam_chauthtok_conv(int n, const struct pam_message **msg, | 595 | pam_tty_conv(int n, const struct pam_message **msg, |
614 | struct pam_response **resp, void *data) | 596 | struct pam_response **resp, void *data) |
615 | { | 597 | { |
616 | char input[PAM_MAX_MSG_SIZE]; | 598 | char input[PAM_MAX_MSG_SIZE]; |
@@ -619,7 +601,7 @@ pam_chauthtok_conv(int n, const struct pam_message **msg, | |||
619 | 601 | ||
620 | *resp = NULL; | 602 | *resp = NULL; |
621 | 603 | ||
622 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | 604 | if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) |
623 | return (PAM_CONV_ERR); | 605 | return (PAM_CONV_ERR); |
624 | 606 | ||
625 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | 607 | if ((reply = malloc(n * sizeof(*reply))) == NULL) |
@@ -661,6 +643,8 @@ pam_chauthtok_conv(int n, const struct pam_message **msg, | |||
661 | return (PAM_CONV_ERR); | 643 | return (PAM_CONV_ERR); |
662 | } | 644 | } |
663 | 645 | ||
646 | static struct pam_conv tty_conv = { pam_tty_conv, NULL }; | ||
647 | |||
664 | /* | 648 | /* |
665 | * XXX this should be done in the authentication phase, but ssh1 doesn't | 649 | * XXX this should be done in the authentication phase, but ssh1 doesn't |
666 | * support that | 650 | * support that |
@@ -668,15 +652,10 @@ pam_chauthtok_conv(int n, const struct pam_message **msg, | |||
668 | void | 652 | void |
669 | do_pam_chauthtok(void) | 653 | do_pam_chauthtok(void) |
670 | { | 654 | { |
671 | struct pam_conv pam_conv; | ||
672 | |||
673 | pam_conv.conv = pam_chauthtok_conv; | ||
674 | pam_conv.appdata_ptr = NULL; | ||
675 | |||
676 | if (use_privsep) | 655 | if (use_privsep) |
677 | fatal("Password expired (unable to change with privsep)"); | 656 | fatal("Password expired (unable to change with privsep)"); |
678 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | 657 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
679 | (const void *)&pam_conv); | 658 | (const void *)&tty_conv); |
680 | if (sshpam_err != PAM_SUCCESS) | 659 | if (sshpam_err != PAM_SUCCESS) |
681 | fatal("PAM: failed to set PAM_CONV: %s", | 660 | fatal("PAM: failed to set PAM_CONV: %s", |
682 | pam_strerror(sshpam_handle, sshpam_err)); | 661 | pam_strerror(sshpam_handle, sshpam_err)); |
@@ -687,6 +666,67 @@ do_pam_chauthtok(void) | |||
687 | pam_strerror(sshpam_handle, sshpam_err)); | 666 | pam_strerror(sshpam_handle, sshpam_err)); |
688 | } | 667 | } |
689 | 668 | ||
669 | static int | ||
670 | pam_store_conv(int n, const struct pam_message **msg, | ||
671 | struct pam_response **resp, void *data) | ||
672 | { | ||
673 | struct pam_response *reply; | ||
674 | int i; | ||
675 | size_t len; | ||
676 | |||
677 | debug3("PAM: %s called with %d messages", __func__, n); | ||
678 | *resp = NULL; | ||
679 | |||
680 | if (n <= 0 || n > PAM_MAX_NUM_MSG) | ||
681 | return (PAM_CONV_ERR); | ||
682 | |||
683 | if ((reply = malloc(n * sizeof(*reply))) == NULL) | ||
684 | return (PAM_CONV_ERR); | ||
685 | memset(reply, 0, n * sizeof(*reply)); | ||
686 | |||
687 | for (i = 0; i < n; ++i) { | ||
688 | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { | ||
689 | case PAM_ERROR_MSG: | ||
690 | case PAM_TEXT_INFO: | ||
691 | len = strlen(PAM_MSG_MEMBER(msg, i, msg)); | ||
692 | buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len); | ||
693 | buffer_append(&loginmsg, "\n", 1 ); | ||
694 | reply[i].resp_retcode = PAM_SUCCESS; | ||
695 | break; | ||
696 | default: | ||
697 | goto fail; | ||
698 | } | ||
699 | } | ||
700 | *resp = reply; | ||
701 | return (PAM_SUCCESS); | ||
702 | |||
703 | fail: | ||
704 | for(i = 0; i < n; i++) { | ||
705 | if (reply[i].resp != NULL) | ||
706 | xfree(reply[i].resp); | ||
707 | } | ||
708 | xfree(reply); | ||
709 | return (PAM_CONV_ERR); | ||
710 | } | ||
711 | |||
712 | static struct pam_conv store_conv = { pam_store_conv, NULL }; | ||
713 | |||
714 | void | ||
715 | do_pam_session(void) | ||
716 | { | ||
717 | debug3("PAM: opening session"); | ||
718 | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, | ||
719 | (const void *)&store_conv); | ||
720 | if (sshpam_err != PAM_SUCCESS) | ||
721 | fatal("PAM: failed to set PAM_CONV: %s", | ||
722 | pam_strerror(sshpam_handle, sshpam_err)); | ||
723 | sshpam_err = pam_open_session(sshpam_handle, 0); | ||
724 | if (sshpam_err != PAM_SUCCESS) | ||
725 | fatal("PAM: pam_open_session(): %s", | ||
726 | pam_strerror(sshpam_handle, sshpam_err)); | ||
727 | sshpam_session_open = 1; | ||
728 | } | ||
729 | |||
690 | /* | 730 | /* |
691 | * Set a PAM environment string. We need to do this so that the session | 731 | * Set a PAM environment string. We need to do this so that the session |
692 | * modules can handle things like Kerberos/GSI credentials that appear | 732 | * modules can handle things like Kerberos/GSI credentials that appear |