+struct _cfg {
+ int noaskpass;
+ int verbose;
+ int injectauth;
+};
+
+#ifndef HAVE_PAM_GET_AUTHTOK
+static int pam_get_authtok(pam_handle_t *pamh, int item, const char **authtok,
+ const char *prompt)
+{
+ struct _cfg dfl_cfg = {0};
+ struct _cfg *cfg = &dfl_cfg;
+ struct pam_conv *conv;
+ struct pam_message msg;
+ const struct pam_message *msgp;
+ struct pam_response *resp;
+ int pam_err;
+
+ (void)pam_get_data(pamh, "pcsc_cr_cfg_struct", (const void **)&cfg);
+
+ if ((pam_err = pam_get_item(pamh, PAM_AUTHTOK,
+ (const void **)authtok))) {
+ if (cfg->verbose) syslog(LOG_ERR,
+ "get_item(PAM_AUTHTOK) failed: %s",
+ pam_strerror(pamh, pam_err));
+ } else {
+ if (*authtok) return PAM_SUCCESS;
+ }
+
+ if ((pam_err = pam_get_item(pamh, PAM_CONV,
+ (const void **)&conv))) {
+ if (cfg->verbose) syslog(LOG_ERR,
+ "get_item(PAM_CONV) failed: %s",
+ pam_strerror(pamh, pam_err));
+ return pam_err;
+ }
+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
+ msg.msg = prompt;
+ msgp = &msg;
+ resp = NULL;
+ pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
+ if (resp != NULL) {
+ if (pam_err == PAM_SUCCESS) *authtok = resp->resp;
+ else free(resp->resp);
+ free(resp);
+ }
+ return pam_err;
+}
+#endif
+