void prompt_to_packet(pamc_bp_t prompt, struct internal_packet *packet) { int data_length; data_length = PAM_BP_LENGTH(prompt); packet->at = 0; append_data(packet, data_length, NULL); PAM_BP_EXTRACT(prompt, 0, data_length, packet->buffer); fprintf(stderr, "server received[%d]: {%d|0x%.2x|%s}\n", data_length, PAM_BP_SIZE(prompt), PAM_BP_RCONTROL(prompt), PAM_BP_RDATA(prompt)); }
int misc_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr) { int count=0; struct pam_response *reply; if (num_msg <= 0) return PAM_CONV_ERR; D(("allocating empty response structure array.")); reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response)); if (reply == NULL) { D(("no memory for responses")); return PAM_CONV_ERR; } D(("entering conversation function.")); for (count=0; count < num_msg; ++count) { char *string=NULL; switch (msgm[count]->msg_style) { case PAM_PROMPT_ECHO_OFF: string = read_string(CONV_ECHO_OFF,msgm[count]->msg); if (string == NULL) { goto failed_conversation; } break; case PAM_PROMPT_ECHO_ON: string = read_string(CONV_ECHO_ON,msgm[count]->msg); if (string == NULL) { goto failed_conversation; } break; case PAM_ERROR_MSG: if (fprintf(stderr,"%s\n",msgm[count]->msg) < 0) { goto failed_conversation; } break; case PAM_TEXT_INFO: if (fprintf(stdout,"%s\n",msgm[count]->msg) < 0) { goto failed_conversation; } break; case PAM_BINARY_PROMPT: { pamc_bp_t binary_prompt = NULL; if (!msgm[count]->msg || !pam_binary_handler_fn) { goto failed_conversation; } PAM_BP_RENEW(&binary_prompt, PAM_BP_RCONTROL(msgm[count]->msg), PAM_BP_LENGTH(msgm[count]->msg)); PAM_BP_FILL(binary_prompt, 0, PAM_BP_LENGTH(msgm[count]->msg), PAM_BP_RDATA(msgm[count]->msg)); if (pam_binary_handler_fn(appdata_ptr, &binary_prompt) != PAM_SUCCESS || (binary_prompt == NULL)) { goto failed_conversation; } string = (char *) binary_prompt; binary_prompt = NULL; break; } default: fprintf(stderr, "erroneous conversation (%d)\n" ,msgm[count]->msg_style); goto failed_conversation; } if (string) { /* must add to reply array */ /* add string to list of responses */ reply[count].resp_retcode = 0; reply[count].resp = string; string = NULL; } } /* New (0.59+) behavior is to always have a reply - this is compatable with the X/Open (March 1997) spec. */ *response = reply; reply = NULL; return PAM_SUCCESS; failed_conversation: if (reply) { for (count=0; count<num_msg; ++count) { if (reply[count].resp == NULL) { continue; } switch (msgm[count]->msg_style) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: _pam_overwrite(reply[count].resp); free(reply[count].resp); break; case PAM_BINARY_PROMPT: pam_binary_handler_free(appdata_ptr, (pamc_bp_t *) &reply[count].resp); break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: /* should not actually be able to get here... */ free(reply[count].resp); } reply[count].resp = NULL; } /* forget reply too */ free(reply); reply = NULL; } return PAM_CONV_ERR; }