- switch (msg[replies]->msg_style)
- {
- case PAM_PROMPT_ECHO_ON:
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = strdup (c->user); /* freed by PAM */
- if (c->verbose_p)
- fprintf (stderr, "%s: PAM ECHO_ON(\"%s\") ==> \"%s\"\n",
- blurb(), msg[replies]->msg,
- reply[replies].resp);
- break;
- case PAM_PROMPT_ECHO_OFF:
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = strdup (c->typed_passwd); /* freed by PAM */
- if (c->verbose_p)
- fprintf (stderr, "%s: PAM ECHO_OFF(\"%s\") ==> password\n",
- blurb(), msg[replies]->msg);
- break;
- case PAM_TEXT_INFO:
- /* ignore it... */
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = 0;
- if (c->verbose_p)
- fprintf (stderr, "%s: PAM TEXT_INFO(\"%s\") ==> ignored\n",
- blurb(), msg[replies]->msg);
- break;
- case PAM_ERROR_MSG:
- /* ignore it... */
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies].resp = 0;
- if (c->verbose_p)
- fprintf (stderr, "%s: PAM ERROR_MSG(\"%s\") ==> ignored\n",
- blurb(), msg[replies]->msg);
- break;
- default:
- /* Must be an error of some sort... */
- free (reply);
- if (c->verbose_p)
- fprintf (stderr, "%s: PAM unknown %d(\"%s\") ==> ignored\n",
- blurb(), msg[replies]->msg_style, msg[replies]->msg);
- return PAM_CONV_ERR;
- }
+ if (verbose_p && i > 0) fprintf (stderr, ", ");
+
+ messages[i].msg = msg[i]->msg;
+
+ switch (msg[i]->msg_style) {
+ case PAM_PROMPT_ECHO_OFF: messages[i].type = AUTH_MSGTYPE_PROMPT_NOECHO;
+ if (verbose_p) fprintf (stderr, "ECHO_OFF");
+ break;
+ case PAM_PROMPT_ECHO_ON: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO;
+ if (verbose_p) fprintf (stderr, "ECHO_ON");
+ break;
+ case PAM_ERROR_MSG: messages[i].type = AUTH_MSGTYPE_ERROR;
+ if (verbose_p) fprintf (stderr, "ERROR_MSG");
+ break;
+ case PAM_TEXT_INFO: messages[i].type = AUTH_MSGTYPE_INFO;
+ if (verbose_p) fprintf (stderr, "TEXT_INFO");
+ break;
+ default: messages[i].type = AUTH_MSGTYPE_PROMPT_ECHO;
+ if (verbose_p) fprintf (stderr, "PROMPT_ECHO");
+ break;
+ }
+
+ if (verbose_p)
+ fprintf (stderr, "=\"%s\"", msg[i]->msg ? msg[i]->msg : "(null)");
+ }
+
+ if (verbose_p)
+ fprintf (stderr, ") ...\n");
+
+ ret = si->unlock_cb(nmsgs, messages, &authresp, si);
+
+ /* #### If the user times out, or hits ESC or Cancel, we return PAM_CONV_ERR,
+ and PAM logs this as an authentication failure. It would be nice if
+ there was some way to indicate that this was a "cancel" rather than
+ a "fail", so that it wouldn't show up in syslog, but I think the
+ only options are PAM_SUCCESS and PAM_CONV_ERR. (I think that
+ PAM_ABORT means "internal error", not "cancel".) Bleh.
+ */
+
+ if (ret == 0)
+ {
+ for (i = 0; i < nmsgs; ++i)
+ pam_responses[i].resp = authresp[i].response;
+ }
+
+end:
+ if (messages)
+ free(messages);
+
+ if (authresp)
+ free(authresp);
+
+ if (verbose_p)
+ fprintf (stderr, "%s: pam_conversation (...) ==> %s\n", blurb(),
+ (ret == 0 ? "PAM_SUCCESS" : "PAM_CONV_ERR"));
+
+ if (ret == 0)
+ {
+ *resp = pam_responses;
+ return PAM_SUCCESS;