diff -urN openssh-3.6.1p1-owl-hide-unknown/auth-pam.c openssh-3.6.1p1/auth-pam.c --- openssh-3.6.1p1-owl-hide-unknown/auth-pam.c Wed Jan 22 04:42:26 2003 +++ openssh-3.6.1p1/auth-pam.c Mon Apr 7 23:53:30 2003 @@ -34,6 +34,9 @@ #include "canohost.h" #include "readpass.h" +#include +#include + extern char *__progname; extern int use_privsep; @@ -49,13 +52,13 @@ struct pam_response **resp, void *appdata_ptr); /* module-local variables */ +static pam_userpass_t userpass; static struct pam_conv conv = { (int (*)())do_pam_conversation, - NULL + &userpass }; static char *__pam_msg = NULL; static pam_handle_t *__pamh = NULL; -static const char *__pampasswd = NULL; /* states for do_pam_conversation() */ enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; @@ -87,18 +90,45 @@ * PAM conversation function. * There are two states this can run in. * - * INITIAL_LOGIN mode simply feeds the password from the client into - * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output - * messages with into __pam_msg. This is used during initial - * authentication to bypass the normal PAM password prompt. + * INITIAL_LOGIN mode simply feeds the username and the password from + * the client into PAM via Linux-PAM binary prompts and queues any text + * messages for printing later. * - * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase() - * and outputs messages to stderr. This mode is used if pam_chauthtok() - * is called to update expired passwords. + * OTHER mode is a regular PAM conversation. This mode is used if + * pam_chauthtok() is called to update expired passwords. */ static int do_pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { + if (pamstate == INITIAL_LOGIN) { + int i, status; + + status = pam_userpass_conv(num_msg, msg, resp, appdata_ptr); + if (status != PAM_CONV_ERR) + return status; + + if (!(*resp = malloc(num_msg * sizeof(struct pam_response)))) + return PAM_CONV_ERR; + for (i = 0; i < num_msg; i++) { + switch (msg[i]->msg_style) { + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + message_cat(&__pam_msg, msg[i]->msg); + (*resp)[i].resp_retcode = PAM_SUCCESS; + (*resp)[i].resp = NULL; + continue; + default: + free(*resp); + *resp = NULL; + return PAM_CONV_ERR; + } + } + return PAM_SUCCESS; + } + + return misc_conv(num_msg, msg, resp, appdata_ptr); + +#if 0 struct pam_response *reply; int count; char buf[1024]; @@ -172,6 +202,7 @@ *resp = reply; return PAM_SUCCESS; +#endif } /* Called at exit to cleanly shutdown PAM */ @@ -210,7 +241,8 @@ do_pam_set_conv(&conv); - __pampasswd = password; + userpass.user = pw ? pw->pw_name : "ILLEGAL USER"; + userpass.pass = password; pamstate = INITIAL_LOGIN; pam_retval = do_pam_authenticate(